java 工厂模式 转载
下面介绍三种设计模式,简单工厂模式,工厂方法模式,抽象工厂模式
思考如下场景:
有一天,林同学准备去买笔记本,他到商城发现有两款电脑他特别喜欢, 一款是 Macbook Pro, 另一款是 Surface Pro。
根据以上的场景,类图可以如下表示:
interface Computer {
public void printComputer();
} class MacbookProComputer implements Computer {
public void printComputer() {
System.out.println("This is a macbook pro");
}
} class SurfaceBookComputer implements Computer {
public void printComputer() {
System.out.println("This is a surface book");
}
} public class Client {
public void buy(Computer c){
c.printComputer();
}
public static void main(String[] args) {
Client c = new Client();
c.buy(new SurfaceBookComputer());
}
}
这时候问题就来了,客户只关心得到电脑,并不关心电脑是如何被生产出来的,假设这里电脑是由鼠标,键盘和显示器组成,那么我们还需要先创建这些类实例,才能创建电脑。
Keyboard keyboard = new Keyboard();
Display display = new Display();
Mouse mouse = new Mouse();
Client c = new Client();
c.buy(new SurfaceBookComputer(keyboard, display, mouse));
显然商家在卖电脑的时候不会要求客户自己把电脑组装好的吧。
简单工厂模式
下面就先介绍简单工厂模式。
简单工厂模式:专门定义一个类用来创建其它类的实例,被创建的实例通常都具有共同的父类。
这里我们相当于是创建生产电脑的工厂,客户需要购买什么样的电脑,只要输入类型编号就可以获取该电脑,而无需知道该电脑是如何被生产出来的。
类图如下表示:
Java 代码:
interface Computer {
public void printComputer();
} class MacbookProComputer implements Computer {
public void printComputer() {
System.out.println("This is a macbook pro");
}
} class SurfaceBookComputer implements Computer {
public void printComputer() {
System.out.println("This is a surface book");
}
} class ComputerFactory {
public Computer createComputer(String type) {
Computer c = null;
if(type.equals("macbook")) {
c = new MacbookProComputer();
}else if(type.equals("surface")) {
c = new SurfaceBookComputer();
}
return c;
}
} public class Client {
public void buy(Computer c){
System.out.println("I buy a computer");
c.printComputer();
}
public static void main(String[] args) { Client c = new Client();
ComputerFactory cf = new ComputerFactory(); Computer computer = cf.createComputer("macbook");
c.buy(computer);
}
}
工厂模式的角色一般包括:
- 工厂角色: 如上图的 ComputerFactory,它可以被客户端调用,其内部用于负责创建具体的对象。
- 抽象产品类:如上图的 Computer,它描述了所有实例的公共接口。
- 具体产品类:如上图的 MacbookProComputer,实现抽象产品的接口,是工厂角色中要创建的具体实例。
简单工厂模式的优点从上面两种方式对比可以看出,工厂角色负责产生具体的实例对象,所以在工厂类中需要有必要的逻辑,通过客户的输入能够得到具体创建的实例;所以客户端就不需要感知具体对象是如何产生的,只需要将必要的信息提供给工厂即可。
这时候负责这个工厂的产品经理说该工厂需要生产新的产品 Macbook Air, 那么该方法的缺点就暴露显现,一般工厂生产方法和具体产品实现一般是由不同工程师开发的,那么如果实现产品的工程师早早实现了新产品而工厂方法却一直没有更新,那么该产品就一直无法上架。其次代码耦合度太高,如果工厂方法由新来的工程师去修改的话,那么他又得先读懂源代码,效率显得低下。
所以简单工厂模式的缺点:简单工厂模式是违反“开闭原则”,即对扩展开放,对修改关闭;因为如果要新增具体产品,就需要修改工厂类的代码。
针对简单工厂模式暴露出来的弊端,我们需要对代码再进行改进,由此延伸出工厂方法模式。
工厂方法模式
工厂方法模式:定义一个用来创建对象的接口,让子类决定实例化哪一个类,让子类决定实例化延迟到子类。
工厂方法模式是针对每个产品提供一个工厂类,在客户端中判断使用哪个工厂类去创建对象。
我们将之前的 ComputerFactory 抽象成一个接口,那么创建相应具体的工厂类去实现该接口的方法。
具体类图的实现:
Java 代码实现:
interface Computer {
public void printComputer();
} class MacbookProComputer implements Computer {
public void printComputer() {
System.out.println("This is a macbook pro");
}
} class SurfaceBookComputer implements Computer {
public void printComputer() {
System.out.println("This is a surface book");
}
}
interface ComputerFactory {
public Computer createComputer();
} class MsFactory implements ComputerFactory {
public Computer createComputer(){
return new SurfaceBookComputer();
}
} class AppleFactory implements ComputerFactory {
public Computer createComputer() {
return new MacbookProComputer();
}
} public class Client {
public void buy(Computer c){
System.out.println("I buy a computer");
c.printComputer();
}
public static void main(String[] args) { Client c = new Client();
ComputerFactory cf = new AppleFactory(); Computer computer = cf.createComputer();
c.buy(computer);
}
}
工厂方法模式是针对每个产品提供一个工厂类,在客户端中判断使用哪个工厂类去创建对象。
对比简单工厂模式和工厂方法模式:
对于简单工厂模式而言,创建对象的逻辑判断放在了工厂类中,客户不感知具体的类,但是其违背了开闭原则,如果要增加新的具体类,就必须修改工厂类。
对于工厂方法模式而言,是通过扩展来新增具体类的,符合开闭原则,但是在客户端就必须要感知到具体的工厂类,也就是将判断逻辑由简单工厂的工厂类挪到客户端。
工厂模式横向扩展很方便,假如该工厂又有新的产品 Macbook Air 要生产,那么只需要创建相应的工厂类和产品类去实现抽象工厂接口和抽象产品接口即可,而不用去修改原有已经存在的代码。
抽象工厂模式:
这时候负责该工厂的产品经理说要生产新的一类产品操作系统 Mac Os 和 Windows 8,这时候就引申出了抽象工厂模式。
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
工厂方法模式和抽象工厂模式基本类似,可以这么理解:当工厂只生产一个产品的时候,即为工厂方法模式,而工厂如果生产两个或以上的商品即变为抽象工厂模式。
我们在抽象工厂接口中新增创建系统的方法,并由实例工厂类去实现。
类图可由下表示:
interface Computer {
public void printComputer();
} class MacbookProComputer implements Computer {
public void printComputer() {
System.out.println("This is a macbook pro");
}
} class SurfaceBookComputer implements Computer {
public void printComputer() {
System.out.println("This is a surface book");
}
} interface OperatingSystem {
public void printSystem();
} class MacOsSystem implements OperatingSystem {
public void printSystem() {
System.out.println("This is a mac os");
}
} class Windows8System implements OperatingSystem {
public void printSystem() {
System.out.println("This is a window 8");
}
} interface ProductionFactory {
public Computer createComputer();
public OperatingSystem createSystem();
} class AppleFactory implements ProductionFactory {
public Computer createComputer() {
return new MacbookProComputer();
}
public OperatingSystem createSystem() {
return new MacOsSystem();
}
} class MsFactory implements ProductionFactory {
public Computer createComputer() {
return new SurfaceBookComputer();
}
public OperatingSystem createSystem() {
return new Windows8System();
}
} public class Client { public void buy(Computer c){
System.out.println("I buy a computer");
c.printComputer();
}
public void use(OperatingSystem s) {
System.out.println("Operating System");
s.printSystem();
}
public static void main(String[] args) { ProductionFactory pf = new AppleFactory();
Computer c = pf.createComputer();
OperatingSystem s = pf.createSystem(); Client client = new Client();
client.buy(c);
client.use(s); }
}
抽象工厂模式的缺点在于产品类的扩展,将会是十分费力的,假如在需要加入新的产品,那么几乎所有的工厂类都需要进行修改,所以在使用抽象工厂模式时,对产品等级结构的划分是十分重要的。
适用场景:
无论是简单工厂模式,工厂方法模式还是抽象工厂模式,它们都具有类似的特性,适用场景也十分类似。
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。
所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。使用工厂方法后,调用端的耦合度大大降低了。并且对于工厂来说,是可以扩展的,以后如果想组装其他的产品,只需要再增加一个工厂类的实现就可以。无论是灵活性还是稳定性都得到了极大的提高。
java 工厂模式 转载的更多相关文章
- java工厂模式
(1)概念大白话:java工厂模式就是客户端(main函数)要创建对象觉得麻烦就让另外一个叫工厂的类帮它创建,然后自己每次要创建对象就叫工厂帮它弄,举个例子,在没有工厂这个"手下" ...
- Java工厂模式解耦 —— 理解Spring IOC
Java工厂模式解耦 -- 理解Spring IOC 最近看到一个很好的思想来理解Spring IOC,故记录下来. 资源获取方式 主动式:(要什么资源都自己创建) 被动式:(资源的获取不是我们创建, ...
- Java学习笔记——Java工厂模式之简单工厂
package com.app; import java.util.Date; /* * 工厂模式:简单工厂.工厂方法.抽象工厂 * * */ public class Test0718_Factor ...
- JAVA - 工厂模式
1. 简单工厂违背OCP(Open Close Principle)原则 , 即对增加开放,对修改关闭.如果要符合OCP原则,要针对接口编程. //简单工厂模式,违反了OCP原则 public cla ...
- Java 工厂模式(一)— 抽象工厂(Abstract Factory)模式
一.抽象工厂模式介绍: 1.什么是抽象工厂模式: 抽象工厂模式是所有形态的工厂模式中最为抽象和最具有一般性的一种形态,抽象工厂模式向客户端提供一个接口,使得客户端在不知道具体产品的情类型的情况下,创建 ...
- Java 工厂模式(一)— 简单工厂模式
一.什么是工厂模式: Java中的工厂模式主要是用来将有大量共同接口的类实例化.工厂模式可以动态的决定将哪一个类实例化,不必事先知道要实例化哪个类,将类的实例化的主动权交给工厂而不是类本身.我们常见的 ...
- java工厂模式个人体会
上一边文章主要对单例模式做了一个总结,这篇文章主要对工厂模式也写一写个人的体会. 工厂模式是设计模式的一种,它主要是把实现产品对象的过程封装起来,然后提供给客户端相应的接口.工厂模式也是有3种,分别为 ...
- 自己理解的java工厂模式,希望对大家有所帮助
[http://www.360doc.com/content/11/0824/17/3034429_142983837.shtml] 这两天突然想学学java源代码,不过看到一篇文章说看java源代码 ...
- java工厂模式的测试
/** * 工厂模式的测试 * <p> * 工厂方法模式 * 工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽 ...
随机推荐
- python3内置函数练习
1. abs() abs() 函数返回数字的绝对值. print(abs(1.5236)) # 1.5236 print(abs(1.0)) # 1.0 2. all() all() 函数用于判断给定 ...
- 【Linux基础】crontab定时命令详解
周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron].cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间.cron的配置文件称为“crontab”,是 ...
- linux快速搭建
------------------------------------------ 转载内容 --------------------- Linux升级命令有两个分别是yum upgrade和yum ...
- [Micropython]TPYBoard v202 v102+v202 家庭无线温湿度检测
一.实验器件 1.TPYBoard v102 1块 2.TPYBoard v202 1块 3.Nokia 5110LCD显示屏 1块 4.DHT11温湿度传感器 1个 5.micro USB 数据线 ...
- 实现RunOnUiThread和RunOnUiThreadBlock
现在需要实现一个工具类,RunUtils,这个类中包含runOnUiThread(Context context, Runnable runnable)和runOnUiThreadBlock(Cont ...
- Winform开发框架中的综合案例Demo
在实际的系统开发中,我们往往需要一些简单的的案例代码,基于此目的我把Winform开发框架中各种闪光点和不错的功能,有些是我们对功能模块的简单封装,而有些则是引入了一些应用广泛的开源组件进行集成使用, ...
- 重构JS代码 - 让JS代码平面化
js中的嵌套函数用的很多,很牛叉,那为何要平面化? 易懂(自己及他人) 易修改(自己及他人) 平时Ajax调用写法(基于jQuery) $.post('url', jsonObj, function ...
- Django ORM模型:想说爱你不容易
作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载. 使用Python的Django模型的话,一般都会用它自带的ORM(Object-relational ma ...
- python--迭代器(Iterator)
博客地址:http://www.cnblogs.com/yudanqu/ 1.可迭代对象 在介绍迭代器之前呢,我们先聊一下可迭代对象(Iterable),可迭代对象就是可以直接作用于for循环的对象. ...
- 如何用CSS3画出一个立体魔方?
前言 最近在写<动画点点系列>文章,上一期分享了< 手把手教你如何绘制一辆会跑车 >,本期给大家带来是结合CSS3画出来的一个立体3d魔方,结合了js让你随心所欲想怎么转,就怎 ...