工厂模式是JAVA中
最经常使用的设计模式之一
,使用工厂模式后,建立对象的时候不在将建立逻辑暴露给客户端,而是经过实现接口的方式建立对象,这种设计模式也是对象实例化的最佳方式。html
<!-- more -->java
工厂模式的三种形态git
简单工厂模式属于工厂模式的小弟
,未被收纳进GOF 23
中,可是也被频繁使用编程
1.建立一个Animal
接口设计模式
interface Shape { void draw(); }
2.建立Dog
和Pig
实现Animal
接口微信
class Circle implements Shape { public Circle() { System.out.println("建立圆形模型"); } @Override public void draw() { System.out.println("画了一个圆形"); } } class Square implements Shape { public Square() { System.out.println("建立了方形模型"); } @Override public void draw() { System.out.println("画了一个方形"); } }
3.建立工厂类SimpleFactory
,定义一个基于参数信息实例化具体对象的方法ide
public class SimpleFactory { private final static String CIRCLE = "CIRCLE"; private final static String SQUARE = "SQUARE"; public static Shape getFactory(String type) { switch (type) { case CIRCLE: return new Circle(); case SQUARE: return new Square(); default: throw new NullPointerException("未描绘任何图形"); } } public static void main(String[] args) { Shape circle = SimpleFactory.getFactory(CIRCLE); circle.draw(); Shape square = SimpleFactory.getFactory(SQUARE); square.draw(); } }
4.日志测试
建立圆形模型 画了一个圆形 建立了方形模型 画了一个方形
分析: 从上述代码中能够发现,简单工厂
拥有必定判断能力,构建结果取决于入参,使用起来也十分的方便,也正由于使用太过方便
而致使高耦合
的状况,全部对象实例化都须要依赖它,一旦出问题,影响的会是整个系统spa
使用场景: 建立简单,无复杂业务逻辑的对象操作系统
前面说到过简单工厂模式
存在耦合,且违反了开闭原则
,那么这一问题在工厂方法模式
中能够很容易的解决掉,它能够作到添加新的产品而不破坏已有代码
工厂方法模式
:定义一个建立对象的接口,由它的实现类来决定具体实现,其模式又被称为工厂模式(Factory Pattern)
。
1.新增ImageReaderFactory
抽象工厂接口,用来构建具体的对象
interface ImageReader { void read(); } interface ImageReaderFactory { ImageReader create(); }
2.相比单一实例化的简单工厂模式
而言,方法工厂模式
更加的灵活,针对不一样的产品(图片读取器)
提供不一样的工厂。
class JpgReader implements ImageReader { public JpgReader() { System.out.println("建立Jpg读取器"); } @Override public void read() { System.out.println("读取Jpg文件"); } } class PngReader implements ImageReader { public PngReader() { System.out.println("建立Png读取器"); } @Override public void read() { System.out.println("读取Png文件"); } } class JpgFactory implements ImageReaderFactory { @Override public ImageReader create() { System.out.println("实例化Jpg文件工厂"); return new JpgReader(); } } class PngFactory implements ImageReaderFactory { @Override public ImageReader create() { System.out.println("实例化Png文件工厂"); return new PngReader(); } }
3.建立测试类,固然实际使用过程当中,实现工厂方法
除了能够实例化具体对象,还能够初始化某些资源配置,好比链接池、建立文件等
public class MethodFactory { public static void main(String[] args) { ImageReaderFactory png = new PngFactory(); ImageReader pngReader = png.create(); pngReader.read(); ImageReaderFactory jpg = new JpgFactory(); ImageReader jpgReader = jpg.create(); jpgReader.read(); } }
4.日志
实例化Png文件工厂 建立Png读取器 读取Png文件 实例化Jpg文件工厂 建立Jpg读取器 读取Jpg文件
优势:
产品(图片读取器)
,无需更改现有代码,提升系统扩展性,符合开闭原则
多态性
,又被称为多态工厂模式
缺点: 每次须要编写新的对象和对象工厂类
,随业务发展,必定程度上增长了系统复杂度
抽象工厂模式
是为建立一组对象提供提供的解决方案,与工厂方法模式相比
,抽象工厂模式中的具体工厂不仅是建立某一种产品,而是负责一组(产品族)。抽象工厂模式(Abstract Factory Pattern)
:提供了建立一系列相互依赖对象的接口,无需指定具体类抽象工厂模式
是围绕着一个超级工厂工做,创造其它的工厂类,也被称为工厂的工厂
,这种类型的设计模式是创造性的模式,由于这种模式提供了建立对象的最佳方法之一。抽象工厂模式
的起源或者最先的应用,是用于建立分属于不一样操做系统的视窗构建。好比:命令按键(Button)与文字框(Text)都是视窗构建,在UNIX操做系统的视窗环境和Windows操做系统的视窗环境中,这两个构建有不一样的本地实现,它们的细节有所不一样。
在每个操做系统中,都有一个视窗构建组成的构建家族。在这里就是Button和Text组成的产品族。而每个视窗构件都构成本身的等级结构,由一个抽象角色给出抽象的功能描述,而由具体子类给出不一样操做系统下的具体实现。
能够发如今上面的产品类图中,有两个产品的等级结构,分别是Button等级结构和Text等级结构。同时有两个产品族,也就是UNIX产品族和Windows产品族。UNIX产品族由UNIX Button和UNIX Text产品构成;而Windows产品族由Windows Button和Windows Text产品构成。
系统对产品对象的建立需求由一个工程的等级结构知足,其中有两个具体工程角色,即UnixFactory和WindowsFactory。UnixFactory对象负责建立Unix产品族中的产品,而WindowsFactory对象负责建立Windows产品族中的产品。这就是抽象工厂模式的应用,抽象工厂模式的解决方案以下图:
显然,一个系统只可以在某一个操做系统的视窗环境下运行,而不能同时在不一样的操做系统上运行。因此,系统实际上只能消费属于同一个产品族的产品。
在现代的应用中,抽象工厂模式的使用范围已经大大扩大了,再也不要求系统只能消费某一个产品族了。所以,能够没必要理会前面所提到的原始用意。
摘抄自《JAVA与模式》之抽象工厂模式:http://www.cnblogs.com/java-my-life/archive/2012/03/28/2418836.html
需求: 开发一款《王者荣耀》,支持多操做系统和多控制方式操做控制
和界面控制
,并提供相应的工厂类来封装这些类的初始化过程
1.建立不一样的操做系统接口
interface Linux { void controller(); } interface Windows { void controller(); }
2.基于不一样操做系统实现控制逻辑
class LinuxController implements Linux { @Override public void controller() { System.out.println("Linux 控制 《王者荣耀》"); } } class WindowsController implements Windows { @Override public void controller() { System.out.println("Windows 控制 《王者荣耀》"); } }
3.建立一个工厂类,基于接口分别实现操做控制
和界面控制
两种方式的工厂
interface AbstractFactory { Linux installLinux(); Windows installWindows(); } class OperationFactory implements AbstractFactory { @Override public Linux installLinux() { System.out.println("安装Linux操做控制系统"); return new LinuxController(); } @Override public Windows installWindows() { System.out.println("安装Windows操做控制系统"); return new WindowsController(); } } class InterfaceFactory implements AbstractFactory { @Override public Linux installLinux() { System.out.println("安装Linux界面控制系统"); return new LinuxController(); } @Override public Windows installWindows() { System.out.println("安装Windows界面控制系统"); return new WindowsController(); } }
4.建立《王者荣耀》进行测试
public class KingGlory { public static void main(String[] args) { AbstractFactory operationFactory = new OperationFactory(); operationFactory.installLinux().controller(); operationFactory.installWindows().controller(); System.out.println("========================================================"); AbstractFactory interfaceFactory = new InterfaceFactory(); interfaceFactory.installLinux().controller(); interfaceFactory.installWindows().controller(); } }
5.日志
安装Linux操做控制系统 Linux 控制 《王者荣耀》 安装Windows操做控制系统 Windows 控制 《王者荣耀》 ======================================================== 安装Linux界面控制系统 Linux 控制 《王者荣耀》 安装Windows界面控制系统 Windows 控制 《王者荣耀》
使用抽象工厂模式
来定义的一系列对象一般是相关或相互依赖的,这些产品对象就构成了一个产品族
,也就是抽象工厂定义了一个产品族
。这就带来很是大的灵活性,切换产品族的时候,只要提供不一样的抽象工厂实现就能够了,也就是说如今是以一个产品族做为一个总体被切换,从上文中能够发现,若是咱们须要切换控制方式
,只须要变动下对应的工厂类便可
优势:
开闭原则
,只须要增长具体产品并对应增长一个新的具体工厂,对已有代码无须作任何修改(如:新增一种手柄操做支持)。缺点:
Factory
代码须要所有修改)。使用场景:
全文代码:https://gitee.com/battcn/design-pattern/tree/master/Chapter1/battcn-factory
微信公众号:battcn
(欢迎调戏)