设计模式(Java)——工厂模式

工厂模式的关键在于我们使用这个模式时的需求是使得使用者不关注创建目标对象的具体过程,而只关注对象如何通过简单的参数配置而获取需要的对象

下面通过工厂模式的种类循序渐进的了解其发展和各种工厂模式的优缺点

一、简单工厂模式(Simple Factory )

简单工厂模式是其他工厂模式的基础,理解简单工厂模式就能逐渐深入理解其他工厂模式(例如工厂方法模式,抽象工厂模式)

核心结构:

  • 工厂类(Factory):负责根据参数和配置返回具体产品类的实例对象
  • 抽象产品(Abstract Product):具体产品类的父类
  • 具体产品类 (Concrete Product) :实现具体的产品对象

结构:

举个例子:

设计一个绘图类生成工具,根据传入的参数可以选择:三角形,矩形,圆形,都具有draw()方法

使用简单工厂模式设计:

Shape Factory(工厂类)

public class ShapeFactory {static Shape shapeFactoryMethod(String type){switch (type){case "triangle" : return new Triangle();case "rectangle" : return new Rectangle();case "circle" : return new Circle();default: throw new UnsupportedOperationException("不支持该操作");}}
}

Shape (抽象产品类)

public interface Shape {void display();//void draw();
}

Concrete Shape(具体产品类)

public class Triangle implements Shape{public void draw(double a,double b, double c) {System.out.println("绘制三角形");}@Overridepublic void display() {System.out.println("显示三角形");}
}public class Circle implements Shape{public void draw(double r) {System.out.println("绘制圆形");}@Overridepublic void display() {System.out.println("显示圆形");}
}public class Rectangle implements Shape{public void draw(double width,double length) {System.out.println("绘制矩形");}@Overridepublic void display() {System.out.println("显示矩形");}
}

使用者:

public class Client {public static void main(String[] args) {Rectangle rectangle = (Rectangle)                              ShapeFactory.shapeFactoryMethod("rectangle");rectangle.draw(2, 3);rectangle.display();}
}

优点:逻辑简单,系统提高了一定的灵活性,使用者只需关注怎么通过工厂方法获取对象并调用方法,而不用去关注对象的创建。实现了对象的使用和创建的隔离

简单工厂模式缺点

  • 不符合开闭原则,系统拓展困难:增加具体类和方法需要修改源代码而不是在原来基础上扩展
  • 工厂类集中了产品(对象)的创建逻辑,一旦出现问题就麻烦
  • 只适合产品类个数较少使用例如(2-3)产品类,太多增加系统复杂度,不好维护
  • 工厂使用了静态方法,造成具体工厂角色不能实现继承,也就是说工厂类无法再拓展

二、工厂方法模式(Factory Pattern)

工厂方法模式在简单工厂模式的基础上更好地符合开闭原则(对扩展开放,对修改关闭),即:不需要修改源代码,而是在源代码基础上增加新的类实现新功能。

同时弥补了简单工厂方法复杂度高的缺点,即:具体对象的生成不再通过一个工厂返回,而是交给工厂子类去生成。

核心结构

  • 抽象(接口)产品(Product):定义产品的接口
  • 具体产品实现类(Concrete Product):实现具体的产品
  • 工厂方法接口(Factory Method):声明工厂方法
  • 具体工厂方法实现类(Concrete Factory Method)具体工厂方法返回一个具体产品

结构:

举例:

使用工厂方法模式设计一个程序:读取各种不同类型格式的图片(例如:png,jpg,gif)。每种格式设计一个图片读取器(ImageReader),考虑系统的灵活性,可扩展性。

抽象产品类:

public abstract class ImageReader {abstract void readImage();
}

具体产品类:

public class GifReader extends ImageReader {@Overridevoid readImage() {System.out.println("GIF Reader");}
}public class JpgReader extends ImageReader {@Overridevoid readImage() {System.out.println("JPG Reader");}
}public class PngReader extends ImageReader {@Overridevoid readImage() {System.out.println("PNG Reader");}
}

工厂类:

public interface ImageFactory {ImageReader createImage();
}

具体工厂子类:

public class JpgFactoryMethod implements ImageFactory{@Overridepublic ImageReader createImage(){return new JpgReader();}
}
public class PngFactoryMethod implements ImageFactory{@Overridepublic ImageReader createImage() {return new PngReader();}
}
public class GifFactoryMethod implements ImageFactory{@Overridepublic ImageReader createImage() {return new GifReader();}
}

使用者:

public class Client {public static void main(String[] args) {JpgFactoryMethod jpgFactoryMethod = new JpgFactoryMethod();//只需要返回不同的工厂方法对象ImageReader imageReader = jpgFactoryMethod.createImage();//JpgReader jpgImage = (JpgReader) jpgFactoryMethod.createImage();imageReader.readImage();}
}

系统更具灵活性:

可以配置xml文件,利用反射,修改xml配置的类名,从而实现返回不同的工厂方法对象

可扩展性:

添加新的图片格式的读取直接继承父类再编写代码,同时继承工厂类实现新的子类工厂

工厂方法的隐藏

public abstract ImageFactory { //接口类改为抽象类public abstract ImageReader createImage();//直接在工厂类中创建具体对象调用业务方法public void readImage(){ImageReader imageReader = this.createImage();imageReader.readImage();}
}

工厂方法模式

  • 优点:

    • 用户只需要关心所需要对象的创建工厂
    • 较好的符合了开闭原则
    • 工厂角色和产品角色具有多态性
  • 缺点:
    • 考虑到在扩展新的产品当中,类的个数会增加更多,会造成一定的系统复杂度

三、抽象工厂模式(Abstract Factory)

抽象工厂模式比工厂方法模式抽象程度更高。

工厂方法模式中:每一个具体工厂对应一个具体产品

抽象工厂模式:每一个具体工厂对应创造一组相关的具体产品,将其称之为(产品族),产品族中的每一个具体产品又继承自某一产品父类。

产品族:即来自不同产品等级结构的产品的组合(例如 冰箱,电视组合)

在工厂方法模式中,我们引入了工厂等级结构,即:父类工厂声明方法,交由具体的子类工厂实现。但是通过不同的工厂方法也只能生成一种类型而规格不同的产品。而在抽象工厂模式中,又引入了产品等级结构,可以实现一个工厂子类生成一个产品族,即不同类型的产品。

因此:区别在于抽象工厂模式实现了多个产品等级结构,而方法模式实现的单一产品结构

核心结构:

  • 抽象工厂(Abstract Factory):声明创建产品的方法
  • 具体工厂(Concrete Factory):实现创建具体产品的方法
  • 抽象产品 (Abstract Product):声明产品类型
  • 具体产品(Concrete Product):实现具体产品

结构:

举例:

针对一款手机游戏,为了其支持iOS,Andrioid,操作系统,提供不同的游戏操作控制类(OperationController)和游戏界面控制类(InterfaceController),并提供相应的工厂类来封装这些类初始化过程。使用抽象设计模式对其设计。

抽象产品类:

OperationController

public abstract class OperationController {public abstract void doOperation();
}

InterfaceController

public abstract class InterfaceController {public abstract void doInterface();
}

具体产品类(产品等级结构)

IOSOperationController

public class IOSOperationController extends OperationController {@Overridepublic void doOperation() {System.out.println("IOSOperationController");}
}

AndrioidOperationController

public class AndroidOperationController extends OperationController {@Overridepublic void doOperation() {System.out.println("AndroidOperationController");}
}

IOSInterfaceController

public class IOSInterfaceController extends InterfaceController {@Overridepublic void doInterface() {System.out.println("IOSInterfaceController");}
}

AndrioidInterfaceController

public class AndroidInterfaceController extends InterfaceController {@Overridepublic void doInterface() {System.out.println("AndroidInterfaceController");}
}

抽象工厂类:

ControllerFactory

public  interface ControllerFactory {OperationController getOperationController();InterfaceController getInterfaceController();
}

具体工厂子类:

IOSControllerFactoryMethod

public class IOSControllerFactory implements ControllerFactory {@Overridepublic OperationController getOperationController() {return new IOSOperationController();}@Overridepublic InterfaceController getInterfaceController() {return new IOSInterfaceController();}
}

AndrioidControllerFactoryMethod


public class AndroidControllerFactory implements ControllerFactory {@Overridepublic OperationController getOperationController() {return new AndroidOperationController();}@Overridepublic InterfaceController getInterfaceController() {return new AndroidInterfaceController();}
}

客户端 Client:

public class Client {public static void main(String[] args) {//AndroidAndroidControllerFactory factory = new AndroidControllerFactory();factory.getInterfaceController().doInterface();factory.getOperationController().doOperation();}
}

同样的:抽象工厂模式也可以通过xml+反射灵活配置工厂类型返回具体的产品族。

但相对于工厂方法模式的开闭原则,抽象工厂模式的开闭原则具有倾斜性:当增加新的产品等级结构时(例如在本例中增加xxxController类的不同系统实现)不满足开闭原则,需要修改源代码,这个过程随着抽象程度变大比起最初的简单工厂模式扩展起来更加复杂。但是对于增加新的产品族,抽象工厂能够实现开闭原则(例如增加一个新系统的支持),只需要在增加一个新的具体工厂。

抽象工厂

  • 优点

    • 只关注具体工厂获取对象并使用,不关注对象的创建过程
    • 实现了多个产品等级结构,因此实现了产品族,保证客户端使用的是同一个产品族中的对象
    • 增加产品族符合开闭原则
  • 缺点
    • 增加新的产品等级结构很麻烦,违背开闭原则

(Java)设计模式——工厂模式相关推荐

  1. Java设计模式-工厂模式(3)抽象工厂模式

    在Java设计模式-工厂模式(2)工厂方法模式 我们知道了工厂方法模式解决了简单工厂模式中的缺陷,做到了满足开闭原则,但是时代是进步的,进而又产生新的问题,工厂难道只能生产一种东西吗.我们所见到的工厂 ...

  2. Java设计模式-工厂模式(2)工厂方法模式

    在Java设计模式-工厂模式(1)简单工厂模式 中我们介绍了简单工厂模式,提到了简单工厂模式违背了开闭原则,而"工厂方法模式"是对简单工厂模式的进一步抽象化,其好处是可以使系统在不 ...

  3. Java设计模式-工厂模式(1)简单工厂模式

    Java设计模式-工厂模式(1)简单工厂模式 一.前言 1)例子 2)类图关系 3)代码实现 二.简单工厂模式 2.1.概述: 2.2.类图关系: 2.3.代码修改: 2.4.优缺点 2.5.扩展-简 ...

  4. java设计模式工厂模式_Java中的工厂设计模式

    java设计模式工厂模式 Welcome to the Factory Design Pattern in Java tutorial. Factory Pattern is one of the C ...

  5. java设计模式工厂模式_Java中的复合设计模式

    java设计模式工厂模式 Composite pattern is one of the Structural design pattern. Composite design pattern is ...

  6. java设计模式工厂模式_Java中的桥梁设计模式

    java设计模式工厂模式 Today we will look into Bridge Design Pattern in java. When we have interface hierarchi ...

  7. java设计模式工厂模式_Java中的外观设计模式

    java设计模式工厂模式 Facade Design Pattern is one of the Structural design patterns (such as Adapter pattern ...

  8. java 工厂模式的写法_[java设计模式] 工厂模式解析

    什么是工厂模式? 我的总结是: 遵守软件设计中的开闭原则和依赖反转原则, 并且客户端只需通过参数来创造多个对象, 并且在创建过程中,创建对象的过程对客户端是透明的. 这种开发模式叫做工厂模式. 出现原 ...

  9. 10.Java设计模式 工厂模式,单例模式

    Java 之工厂方法和抽象工厂模式 1. 概念 工厂方法:一抽象产品类派生出多个具体产品类:一抽象工厂类派生出多个具体工厂类:每个具体工厂类只能创建一个具体产品类的实例. 即定义一个创建对象的接口(即 ...

  10. 学习:java设计模式—工厂模式

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Facto ...

最新文章

  1. Waymo向客户发邮件,宣布纯无人驾驶汽车即将上路
  2. stm32之USART学习
  3. 如何高效的使用vim
  4. hibernate 延迟加载(转载)
  5. struts2的注入参数,获取值
  6. html语言可以写模版继承吗,16-Django的模板语言(变量,标签,过滤器,继承,html转义)...
  7. Pig 0.12.1安装和使用
  8. 数据挖掘之关联分析四(连续属性处理)
  9. 区块链app源码_区块链app商城系统开发适用于哪些企业
  10. 2018.10.20 2018-2019 ICPC,NEERC,Southern Subregional Contest(Online Mirror, ACM-ICPC Rules)
  11. dls 深度受限搜索java_JAVA深入学习(栈和队列)之栈
  12. 《数据挖掘概念与技术》学习笔记
  13. 《R语言初学者指南》pdf
  14. 三农数据(1990-2020)七:农村居民家庭生产现金支出、农村固定资产构成、固定资产投向
  15. Ubuntu18.04安装GPU显卡驱动
  16. GEE-Python遥感大数据分析、管理与可视化
  17. 【华为OD机试真题 JS】统计射击比赛成绩
  18. 解决谷歌浏览器Chrome不能播放央视新闻视频的问题
  19. 如何快速合并PDF文件?几个方法教你合并PDF
  20. Axure幻灯片制作

热门文章

  1. 查询ios设备的电池循环次数以及目前的电量
  2. nodejs读取本地json文件中文乱码问题
  3. 关闭CentOS系统自动更新服务
  4. 发黄图、泼脏水,为了搞垮对手,Soul 到底有多努力,他们到底是如何发展起来的呢?...
  5. 耳鸣常见的因素有哪些?
  6. 字节软件测试学习,软件测试中http_load和Glimpse工具的学习
  7. linux基本功系列之less命令实战
  8. Windows 10 ISO原版镜像文件下载(2022年12月)
  9. 算法——音乐播发器中考虑已听次数的随机播放算法
  10. 星形和雪花模型_星型模型和雪花型模型比较