
设计模式-抽象工厂模式
发布日期:2021-05-09 02:13:21
浏览次数:9
分类:博客文章
本文共 4217 字,大约阅读时间需要 14 分钟。
《》讲了简单工厂模式,但是简单工厂模式存在一定的问题,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包-开放原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
抽象工厂模式的概念
抽象工厂模式(Abstract Factory Pattern)的定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
抽象工厂模式包含如下角色:
- AbstractFactory:抽象工厂;
- ConcreteFactory:具体工厂,如ShapeFactory,ColorFactory;
- AbstractProduct:抽象产品;
- Product:具体产品,如Circle,Red等。
实现
我们将创建 Shape 和 Color 接口和实现这些接口的实体类。下一步是创建抽象工厂类 AbstractFactory。接着定义具体工厂类 ShapeFactory 和 ColorFactory,这两个工厂类都是扩展了 AbstractFactory。然后创建一个工厂创造器/生成器类 FactoryProducer。
AbstractFactoryPatternDemo,我们的演示类使用 FactoryProducer 来获取 AbstractFactory 对象。它将向 AbstractFactory 传递形状信息 Shape(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 Color(RED / GREEN / BLUE),以便获取它所需对象的类型。 抽象工厂模式的UML图:
步骤 1为形状创建一个接口。Shape.javapublic interface Shape {void draw();}步骤 2创建实现接口的实体类。Rectangle.javapublic class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}}Square.javapublic class Square implements Shape {@Overridepublic void draw() {System.out.println("Inside Square::draw() method.");}}Circle.javapublic class Circle implements Shape {@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");}}步骤 3为颜色创建一个接口。Color.javapublic interface Color {void fill();}步骤4创建实现接口的实体类。Red.javapublic class Red implements Color {@Overridepublic void fill() {System.out.println("Inside Red::fill() method.");}}Green.javapublic class Green implements Color {@Overridepublic void fill() {System.out.println("Inside Green::fill() method.");}}Blue.javapublic class Blue implements Color {@Overridepublic void fill() {System.out.println("Inside Blue::fill() method.");}}步骤 5为 Color 和 Shape 对象创建抽象类来获取工厂。AbstractFactory.javapublic abstract class AbstractFactory {abstract Color getColor(String color);abstract Shape getShape(String shape) ;}步骤 6创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象。ShapeFactory.javapublic class ShapeFactory extends AbstractFactory {@Overridepublic Shape getShape(String shapeType){if(shapeType == null){return null;}if(shapeType.equalsIgnoreCase("CIRCLE")){return new Circle();} else if(shapeType.equalsIgnoreCase("RECTANGLE")){return new Rectangle();} else if(shapeType.equalsIgnoreCase("SQUARE")){return new Square();}return null;}@OverrideColor getColor(String color) {return null;}}ColorFactory.javapublic class ColorFactory extends AbstractFactory {@Overridepublic Shape getShape(String shapeType){return null;}@OverrideColor getColor(String color) {if(color == null){return null;}if(color.equalsIgnoreCase("RED")){return new Red();} else if(color.equalsIgnoreCase("GREEN")){return new Green();} else if(color.equalsIgnoreCase("BLUE")){return new Blue();}return null;}}步骤 7创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂。FactoryProducer.javapublic class FactoryProducer {public static AbstractFactory getFactory(String choice){if(choice.equalsIgnoreCase("SHAPE")){return new ShapeFactory();} else if(choice.equalsIgnoreCase("COLOR")){return new ColorFactory();}return null;}}步骤 8使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象。AbstractFactoryPatternDemo.javapublic class AbstractFactoryPatternDemo {public static void main(String[] args) {//获取形状工厂AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");//获取形状为 Circle 的对象Shape shape1 = shapeFactory.getShape("CIRCLE");//调用 Circle 的 draw 方法shape1.draw();//获取形状为 Rectangle 的对象Shape shape2 = shapeFactory.getShape("RECTANGLE");//调用 Rectangle 的 draw 方法shape2.draw();//获取颜色工厂AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");//获取颜色为 Red 的对象Color color1 = colorFactory.getColor("RED");//调用 Red 的 fill 方法color1.fill();}}步骤 9验证输出。Inside Circle::draw() method.Inside Rectangle::draw() method.Inside Red::fill() method.Inside Green::fill() method.
应用场景
第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。Java Collection中的iterator() 方法即属于这种情况。
第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。
Reference
https://yq.aliyun.com/articles/659658?spm=a2c4e.11163080.searchblog.117.91432ec1Cet3zK
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2025年04月18日 20时30分49秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
oracle 11g not in 与not exists 那个高效?
2021-05-09
Linux 安装Redis 5.0(以及参数调优)
2021-05-09
html5 Game开发系列文章之 零[开篇]
2021-05-09
为什么阿里巴巴建议集合初始化时,指定集合容量大小
2021-05-09
为什么阿里巴巴要求谨慎使用ArrayList中的subList方法
2021-05-09
Redis不是一直号称单线程效率也很高吗,为什么又采用多线程了?
2021-05-09
基于Python的Appium环境搭建合集
2021-05-09
Requests实践详解
2021-05-09
接口测试简介
2021-05-09
Golang Web入门(4):如何设计API
2021-05-09
让sublime实现js控制台(前提是安装了nodejs)
2021-05-09
树莓派连接二手液晶屏小记
2021-05-09
error: 'LOG_TAG' macro redefined
2021-05-09
android10Binder(一)servicemanager启动流程
2021-05-09
ES6基础之——new Set
2021-05-09
nodeJS实现识别验证码(tesseract-ocr+GraphicsMagick)
2021-05-09
玩玩小爬虫——试搭小架构
2021-05-09
AS与.net的交互——加载web上的xml
2021-05-09
Javascript之旅——第八站:说说instanceof踩了一个坑
2021-05-09