Java设计模式—工厂方法模式抽象工厂模式
工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式。
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
通用类图如下:
在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象创建
类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的。
工厂方法模式的扩展方式有很多种,下边是工厂方法模式一个比较实用的源代码:
抽象产品类:
public abstract class Product { //产品类的公共方法public void method1(){//业务逻辑处理} //抽象方法public abstract void method2();
}
具体的产品类可以有多个,都继承于抽象产品类。
public class ConcreteProduct1 extends Product {public void method2() {//业务逻辑处理}
}
public class ConcreteProduct2 extends Product {public void method2() {//业务逻辑处理}
}
抽象工厂类负责定义产品对象的产生:
public abstract class Creator { /** 创建一个产品对象,其输入参数类型可以自行设置* 通常为String、Enum、Class等,当然也可以为空*/ public abstract <T extends Product> T createProduct(Class<T> c);
}
具体如何产生一个产品的对象,是由具体的工厂类实现的:
public class ConcreteCreator extends Creator { public <T extends Product> T createProduct(Class<T> c){Product product=null;try {product = (Product)Class.forName(c.getName()).newInstance();} catch (Exception e) {//异常处理}return (T)product; }
}
场景类如下所示:
public class Client {public static void main(String[] args) {Creator creator = new ConcreteCreator();Product product = creator.createProduct(ConcreteProduct1.class);/** 继续业务处理*/}
}
该通用代码是一个比较实用、易扩展的框架。
工厂方法模式的优点:
(1)良好的封装性,代码结构清晰。一个对象创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要
知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,降低模块间的耦合。
(2)工厂方法模式的扩展性非常优秀。在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,
就可以完成“拥抱变化”。
(3)屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,
只要接口保持不变,系统中的上层模块就不要发生变化。因为产品类的实例化工作是由工厂类负责的,一个产品对象
具体由哪一个产品生成是由工厂类决定的。
使用场景:
首先,工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要慎重地考
虑是否要增加一个工厂类进行管理,增加代码的复杂度。
工厂方法模式的扩展:
(1)简单工厂模式
当一个模块只需要一个工工厂类时,我们可以将抽象工厂类kill掉,然后将具体工厂类中制造产品的方法前面加static
关键字,则,工厂方法模式就变为了简单工厂模式。
该模式是工厂方法模式的弱化,因为简单,所以称为简单工厂模式(Simple Factory Pattern),也叫做静态工
厂模式。在实际项目中,采用该方法的案例还是比较多的,其缺点是工厂类的扩展比较困难,不符合开闭原则,但它
仍然是一个非常实用的设计模式。
(2)多工厂模式
当遇到一个复杂的项目,初始化一个对象很费事的时候,我们可以使用多工厂模式,即一个工厂只生产特定的某种产
品,实现了单一职责。
每一个产品类都对应了一个创建类,好处就是创建类的职责清晰,而且结构简单,但是给可扩展性和可维护性带
来了一定的影响。为什么这么说呢?如果要扩展一个产品类,就需要建立一个相应的工厂类,这样就增加了扩展的难
度。因为工厂类和产品类的数量相同,维护时需要考虑两个对象之间的关系。
当然,在复杂的应用中一般采用多工厂的方法,然后再增加一个协调类,避免调用者与各个子工厂交流,协调类
的作用是封装子工厂类,对高层模块提供统一的访问接口。
抽象工厂模式
抽象工厂模式是一种比较常用的模式。
其定义如下:
为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。
通用类图如下:
抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的
对象是一种非常好的解决方式。我们来看看抽象工厂的通用源代码,首先有两个互相影响的产品线(也叫做产族),
例如制造汽车的左侧门和右侧门,这两个应该是数量相等的——两个对象之间的约束,每个型号的车门都是不
一样的,这是产品等级结构约束的,我们先看看两个产品族的类图,如下所示:
注意类图上的圈圈、框框相对应,两个抽象的产品类可以有关系,例如共同继承或实现一个抽象类或接口。
通用源代码如下:
//抽象产品类
public abstract class AbstractProduct A { //每个产品共有的方法public void shareMethod(){}//每个产品相同方法,不同实现public abstract void doSomething();
}
产品A1的实现类
public class ProductA1 extends AbstractProductA {public void doSomething() {System.out.println("产品A1的实现方法");}
}
产品A2的实现类
public class ProductA2 extends AbstractProductA {public void doSomething() {System.out.println("产品A2的实现方法");}
}
产品B与此类似,不再赘述。
抽象工厂类
public abstract class AbstractCreator {//创建A产品家族public abstract AbstractProductA createProductA(); //创建B产品家族public abstract AbstractProductB createProductB();
}
注意:有N个产品族,在抽象工厂类中就应该有N个创建方法。
产品等级1的实现类
public class Creator1 extends AbstractCreator { //只生产产品等级为1的A产品public Abstract ProductA createProductA() { return new ProductA1();}//只生产产品等级为1的B产品public AbstractProductB createProductB() {return new ProductB1();}
}
产品等级2的实现类
public class Creator2 extends AbstractCreator { //只生产产品等级为2的A产品public AbstractProductA createProductA() { return new ProductA2();}//只生产产品等级为2的B产品public AbstractProductB createProductB() {return new ProductB2();}
}
注意:M个实现工厂类,在每个实现工厂中,实现不同产品族的生产任务。
场景类如下:
public class Client {public static void main(String[] args) {//定义出两个工厂Abstract Creator creator1 = new Creator1();Abstract Creator creator2 = new Creator2();//产生A1对象AbstractProductA a1 = creator1.createProductA();//产生A2对象AbstractProductA a2 = creator2.createProductA();//产生B1对象AbstractProductB b1 = creator1.createProductB();//产生B2对象AbstractProductB b2 = creator2.createProductB();/** 然后在这里就可以为所欲为了...*/}
}
抽象工厂模式的优点:
● 封装性。
每个产品的实现类不是高层模块要关心的,它要关心的是什么?是接口,是抽象,它不关心对象是如何创建出
来,这由谁负责呢?工厂类,只要知道工厂类是谁,我就能创建出一个需要的对象,省时省力,优秀设计就应该如
此。
● 产品族内的约束为非公开状态。
缺点:
抽象工厂模式的最大缺点就是产品族扩展非常困难,为什么这么说呢?我们以通用代码为例,如果要增加一个产
品C,也就是说产品家族由原来的2个增加到3个,看看我们的程序有多大改动吧!抽象类AbstractCreator要增加一个
方法createProductC(),然后两个实现类都要修改,想想看,这严重违反了开闭原则,而且我们一直说明抽象类和接
口是一个契约。改变契约,所有与契约有关系的代码都要修改,那么这段代码叫什么?叫“有毒代码”,——只要与这
段代码有关系,就可能产生侵害的危险!
两种设计模式的区别:
区别在于产品,如果产品单一,最合适用工厂模式,但是如果有多个业务品种、业务分类时,通过抽象工
厂模式产生需要的对象是一种非常好的解决方式。再通俗深化理解下:工厂模式针对的是一个产品等级结构 ,
抽象工厂模式针对的是面向多个产品等级结构的。
工厂方法模式与抽象工厂模式对比:
工厂方法模式 |
抽象工厂模式 |
针对的是一个产品等级结构 | 针对的是面向多个产品等级结构 |
一个抽象产品类 | 多个抽象产品类 |
可以派生出多个具体产品类 | 每个抽象产品类可以派生出多个具体产品类 |
一个抽象工厂类,可以派生出多个具体工厂类 | 一个抽象工厂类,可以派生出多个具体工厂类 |
每个具体工厂类只能创建一个具体产品类的实例 | 每个具体工厂类可以创建多个具体产品类的实例 |
如果对你有帮助,记得点赞哦~
转载于:https://www.cnblogs.com/lanzhi/p/6467273.html
Java设计模式—工厂方法模式抽象工厂模式相关推荐
- 【Java设计模式】简单学抽象工厂模式——你好,微信还是支付宝
目录 说明 实现方式 自问自答 其他链接 说明 五大创建型模式之一,其他还有单例模式.原型模式.建造者模式.工厂模式. 抽象工厂模式(Abstract Factory Pattern):定义了一个in ...
- 设计模式:工厂方法与抽象工厂模式
说明:这篇blog写的很好,有助于理解工厂方法与抽象工厂模式的联系与区别. 原文链接:http://blog.csdn.net/yzxz/article/details/4601152 抽象工厂模式与 ...
- 设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
工厂模式 Factory Pattern(简单工厂.工厂方法.抽象工厂) 工厂模式-创建型模式-提供了创建对象的最佳方式. 在工厂模式中,创建对象时不会对客户端暴露创建逻辑,并且是通过一个共同的接口来 ...
- java 抽象工厂工厂_Java设计模式之简单工厂、工厂方法和抽象工厂
学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:456544752我们一起学Java! 在前面的学习中(参见前面的博客),我们学到了很 ...
- 23招做项目——工厂模式:工厂方法和抽象工厂
在网上的大多数资料里面,将工厂模式分为:简单工厂.工厂方法.抽象工厂,他们之间的联系(以电子厂为例)如下: 那么该文章首先讲解工厂模式是什么,为什么需要工厂模式,最后再对三种模式进行示例.该文章是23 ...
- 工厂模式(简单工厂,工厂方法,抽象工厂)
工厂顾名思义就是创建产品,工厂分为三种:简单工厂,工厂方法,抽象工厂.该模式用于封装和管理对象的创建,是一种创建型模式. 1)简单工厂 该模式通过向工厂传递类型来指定要创建的对象 提供一个方法,根据类 ...
- Android工厂设计模式(简单工厂,工厂方法,抽象工厂,BitmapFactory简单工厂分析,Retrofit抽象工厂分析)
文章目录 创建型设计模式(简单工厂,工厂方法,抽象工厂) 一.简单工厂模式 引出简单工厂模式 二.工厂方法模式 三.抽象工厂模式 Android源码中用到的工厂模式举例 一.BitmapFactory ...
- 设计模式——简单工厂、工厂方法和抽象工厂的区别与联系
前言 创建型模式中,常用的有工厂方法模式和抽象工厂模式,平时实践还包括简单工厂模式,虽然简单工厂模式不在23种设计模式中. 为了区分以上几种设计模式的差别,通过以下几个例子介绍这几种模式的使用场景以及 ...
- 设计模式:简单工厂、工厂方法、抽象工厂之小结与区别
简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他 ...
- 【设计模式实战】简单工厂、工厂方法、抽象工厂:原理篇
小明开发的应用,经常要从XML或者Asset中读取省市区数据. 小明是这样写的: public abstract class IOHandler {/*** 添加*/public abstract v ...
最新文章
- c++ 判断nil_golang A=nil,B=A,but B!=nil 这是真的
- 解决 macOS 下HTTP请求访问本地服务被阻塞5秒钟的问题
- [转载] Python中numpy.clip();numpy.fabs()的用法;以及math.pow()的说明
- .NET伪静态使用以及和纯静态的区别
- tp5 查询求和_TP5 Or查询的几种方法
- 一个产品从立项到上线流程总结
- HDMI接口 HDCP
- 【华为编程大赛】投票问题
- linux段错误core dumped,段错误 (core dumped) 之 core文件
- 思维转换--等价换位思考
- 从1到无穷大—机器学习篇
- jacobi旋转法的VB实现
- 做了个抓取全网群二维码和个人二维码的平台
- 【数学建模】2019A题 高压油管的压力控制器(附带优秀论文资源文档下载)
- 这样定义通用人工智能
- 基于ssm+vue的师生防疫登记管理系统 elementui
- 压测springCloud报错ThreadPoolExecutor [Running, pool size = 10, active threads = 10, queued tasks=0错误 )
- 三层交换机的详细配置步骤
- PM-四象限时间管理-需求优先级排序
- CMakeCMakeList.txt
热门文章
- JS如何关闭当前浏览器窗口?
- Windows下JetBrains CLion的pthread使用配置
- orb特征 稠密特征_特征点的基本概念和如何找到它们
- oracle9可以访问8,使用Oracle9i全索引扫描快速访问数据
- java迷宫实训报告_Java综合实训报告-迷宫.doc
- 图像傅里叶变换的幅度谱、相位谱以及双谱重构原图像
- Python中的无序集合(set)
- mysql数据库乱码检查项
- shell分割参数为数组并循环执行jar,异常时退出循环
- android 调用 asp.net web api,从 .NET 客户端调用 Web API (C#)