Java设计模式之工厂方法模式与抽象工厂模式
2019独角兽企业重金招聘Python工程师标准>>>
一、前期回顾
上一篇《Java设计模式之单例模式》详细介绍了单例模式,介绍了单例模式的使用场景,优缺点,同时也写了两种常见的单例模式写法,懒汉式单例模式和饿汉氏单例模式,当然,单例模式的写法还有很多,比如,枚举单例模式,静态内部类单例模式等。有兴趣的可以自行查找资料。本篇开始介绍单例模式的第二篇,工厂方法模式,以及工厂模式的升级版,抽象工厂模式。
二、工厂方法模式的定义与实践
定义:Define an interface for creating an object,but let subclasses decide which class to instantiation.Factory Mehod lets a class defer instantiation to subclasses.翻译过来就是,定义一个用于创建对象的接口,让其子类决定实例化哪个类。工厂方法让一个类的实例化延迟到其子类。
上面的定义说明好像很绕口,如果不理解没关系,我们用个例子来说明这个定义:
//定义产品接口
public interface Iproduct {public void doSomething();
}
//产品实现类
public class ProductA implements Iproduct {@Overridepublic void doSomething() {System.out.println("我是产品A,我可以搞事情");}
}
//定义工厂类接口
public interface IFactory {//创建产品工厂方法< T extends Iproduct> T creatProduct(Class<T> clz);
}
//工厂方法实现类
public class ProductFactory implements IFactory {@Overridepublic <T extends Iproduct> T creatProduct(Class<T> clz) {Iproduct product=null;try {product= clz.newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return (T) product;}
}
//场景类
public class Client {public static void main(String[] args) {IFactory factory=new ProductFactory();Iproduct product= factory.creatProduct(ProductA.class);product.doSomething();}
}
上述例子,实现了一个简单的工厂方法模式,定义了一个工厂接口类,然后具体的工厂方法实现了创建对象的逻辑。看到这里,有人肯定会问,这里要new一个工厂类的实例,和我new一个具体的对象有什么区别呢?反正都要自己new,干嘛要搞一个工厂类这么绕呢?对,没错。这里是要new一个工厂类,但是上面的例子创建产品的对象是比较简单,所以感觉不出来,如果ProductA的实例创建是一个非常复杂的过程,那么这个时候我通过工厂方法模式创建对象的实例就很方便了。
肯定还有人问,我觉得上面这个方式还有点啰嗦,有没有更简便的方式实现工厂模式呢?答案是,有。我们接下来看看简单工厂模式。简单工厂方法模式就是上述工厂方法模式的简单版本。我们只要把上述工厂类的接口去掉,然后把工厂实现类改为静态类就可以实现简单工厂方法模式了。代码是这样的:
//这里只去掉了接口,改为静态方法
public class ProductFactory {public static <T extends Iproduct> T creatProduct(Class<T> clz) {Iproduct product=null;try {product= clz.newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return (T) product;}
}public class Client {public static void main(String[] args) {Iproduct product= ProductFactory.creatProduct(ProductA.class);product.doSomething();}
}
这里就不用自己去new 工厂类啦,代码也简洁了很多。但是去掉了接口也就意味着后面的扩展是不友好的,所以违反了开闭原则。
三、抽象工厂模式的定义与实践
定义:Provide an interface for creating families of related or dependent objects without specifying their concrete classes.翻译: 提供一个创建相关或者相互依赖的对象的接口,并且无需指定他们的具体实现类。
这里理解可能有点困难,为了便于理解,我们先引入两个概念。
产品等级结构: 产品等级结构即产品的继承结构,如一个抽象类是汽车,其子类就是各个品牌的汽车,比如奔驰,宝马汽车。汽车和奔驰就构成了一个产品等级结构,抽象汽车是父类,而具体品牌的汽车是其子类。
产品族 : 在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如奔驰工厂生产的奔驰跑车,宝马公司生产的跑车,奔驰跑车位于奔驰产品等级结构中,宝马跑车位于宝马产品等级结构中。
所以,汽车和品牌是一个产品等级结构,而每个品牌下面有多个产品线,也就是说奔驰牌下面的汽车有多个产品族,比如跑车族,SUV族。奔驰跑车和宝马跑车是一个产品族,奔驰SUV和宝马SUV是一个产品族。所以上面定义中“相关或者相互依赖的对象”就是场景中包含,同一个等级结构中有不同的产品族。 ,我们来用一个实际场景来说明下。
假设,我需要一个汽车工厂,汽车可以生产跑车和SUV车型,那么这个时候用之前的工厂方法模式就不满足了,方法工厂模式只能满足生产一个产品,现在需要生产两个产品。所以我们在方法工厂模式的基础上改造下来满足这个场景。
//汽车接口
public interface ICar {void dirver();
}
//抽象汽车类
public abstract class AbstractProduct implements ICar{@Overridepublic void dirver() {System.out.println("我是汽车,我可以开动");}/**** 展示不同车的亮点*/public abstract void showSpecial();
}
//宝马SUV实现类
public class BmwSuv extends AbstractProduct {@Overridepublic void showSpecial() {System.out.println("我是宝马牌SUV,我的特点就是多功能用途");}
}
//宝马跑车实现类
public class BmwProductRoadster extends AbstractProduct {@Overridepublic void showSpecial() {System.out.println("我是宝马跑车,我的特点就是跑的快");}
}
//奔驰SUV
public class BenzSuv extends AbstractProduct {@Overridepublic void showSpecial() {System.out.println("我是奔驰牌SUV,我的特点就是多功能用途");}
}
//奔驰跑车
public class BenzProductRoadster extends AbstractProduct {@Overridepublic void showSpecial() {System.out.println("我是奔驰跑车,我的特点就是跑的快");}
}//抽象工厂类
public abstract class AbstractFactory {//创建跑车public abstract < T extends ICar> T createRoadster();//创建SUVpublic abstract < T extends ICar> T createSuv();
}
//奔驰汽车工厂类
public class BenzFactory extends AbstractFactory {@Overridepublic <T extends ICar> T createRoadster() {return (T) new BenzProductRoadster();}@Overridepublic <T extends ICar> T createSuv() {return (T) new BenzSuv();}
}
//宝马汽车工厂类
public class BmwFactory extends AbstractFactory {@Overridepublic <T extends ICar> T createRoadster() {return (T) new BmwProductRoadster();}@Overridepublic <T extends ICar> T createSuv() {return (T) new BmwSuv();}
}
//场景类
public class Client {public static void main(String[] args) {AbstractFactory bmwFactory=new BmwFactory();AbstractFactory benzFactory=new BenzFactory();AbstractProduct bmwRoadster= bmwFactory.createRoadster();AbstractProduct bmwSuv=bmwFactory.createSuv();AbstractProduct benzRoadster=benzFactory.createRoadster();AbstractProduct benzSuv=benzFactory.createSuv();bmwRoadster.showSpecial();bmwSuv.showSpecial();benzRoadster.showSpecial();benzSuv.showSpecial();}
}
细心的读者应该发现,我们的改造相对于工厂方法模式而言,只是抽象工厂模式新增了多一个创建方法。这也是抽象工厂模式和工厂方法模式最明显的区别,抽象工厂模式可以满足多类型,多业务的场景,比如汽车工厂可以生产多种类型汽车,就适用于抽象工厂模式。而普通工厂方法模式就是针对生产某一种对象而言比较适用。总结来说就是,抽象工厂模式适用于多产品族的情况,普通工厂方法模式适用于单产品族情况。
四、总结
上面介绍了工厂方法模式与抽象工厂模式的定义与实践,同时也衍生了一个简单工厂模式。我们先来总结下工厂模式的优点与缺点。
优点:
1.良好的封装性,代码结构清晰,不用关注具体对象的创建过程,符合迪米特法则。
2.良好的扩展性,我们扩展了产品,只要新建对应的工厂类,实现自己的实现逻辑即可。
缺点:
1.对于抽象工厂模式,产品族的扩展比较困难,需要修改顶部抽象工厂类,这会导致所有实现类都要修改,不符合开闭原则。
2.对于简单工厂模式,由于没有接口和抽象父类的约束,从而也会导致扩展只能修改代码,不符合开闭原则。
最后我们列一个表格来总结下工厂方法模式,简单工厂模式,抽象工厂模式的区别。
简单工厂模式 | 工厂方法模式 | 抽象工厂模式 | |
---|---|---|---|
有无接口或抽象类 | 无 | 有 | 有 |
适用场景 | 一般不涉及扩展,单产品族 | 涉及单产品族,便于扩展 | 多产品族场景,可以扩展等级结构,不便于扩展产品族 |
实现复杂度 | 最简单 | 简单 | 一般 |
五、参考
《设计模式之禅》
设计模式(三)抽象工厂模式
六、推荐阅读
《Java设计模式之单例模式》
《JAVA设计模式之开篇》
《带你走进java集合之ArrayList》
《带你走进java集合之HashMap》
《Java锁之ReentrantLock(一)》
《Java锁之ReentrantLock(二)》
《Java锁之ReentrantReadWriteLock》
转载于:https://my.oschina.net/luozhou/blog/2874120
Java设计模式之工厂方法模式与抽象工厂模式相关推荐
- 初学 Java 设计模式(三):实战抽象工厂方法模式 「QQ 厘米秀装扮」
一.抽象工厂方法模式介绍 1. 解决的问题 通过接口的选择,解决在系统产品存在多个产品族,而系统仅消费某一族的产品的问题. 2. 定义 抽象工厂模式是一个围绕超级工厂创建其他工厂的模式,即抽象工厂是一 ...
- 抽象工厂和工厂方法示例_抽象工厂设计模式示例
抽象工厂和工厂方法示例 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式如此 ...
- 『创建型』简单工厂SimpleFactory、工厂方法FactoryMethod、抽象工厂AbstractFactory
为什么80%的码农都做不了架构师?>>> 几点说明 永远不要纠结于在什么时候使用什么模式 永远不要纠结于什么模式适用于什么情景 永远不要去死记任何的模式 并不是说,23种设计模 ...
- JAVA设计模式是个什么玩意儿_02_抽象工厂模式
1. 定义 2. 思路 抽象工厂模式是工厂方法模式的进一步抽象,为创建一组相关或相互依赖的对象提供一个接口,无需指定它们的具体类.抽象工厂通常用于创一族产品,并且这组产品分不同的等级,不同的工厂生产不 ...
- 对设计模式的总结之工厂方法模式和抽象工厂模式
前言 面向对象编程追求的本质-提高扩展性.可维护性.灵活性和复用性.合理利用面向对象6个原则,能够很好的达到要求.如何利用好就是至关重要的了,前人总结了23+个设计模式能够让初学者更容易学到其中的精髓 ...
- 设计模式详解(四)抽象工厂模式
文章目录 1. 简介 2. 代码实例 3. 抽象工厂的优缺点 1. 简介 定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类 与工厂方法模式不同(工厂方法的升级,在工厂方法模式 ...
- JAVA设计模式——工厂模式【简单工厂模式、工厂方法模式、抽象工厂模式】
目录 简单工厂模式 传统方式 简单工厂模式 静态工厂模式 工厂方法模式 抽象工厂模式 工厂模式JDK-Calendar源码分析 工厂模式小结 简单工厂模式 看一个具体的需求 看一个披萨的项目:要便 ...
- Java设计模式-工厂方法模式和抽象工厂模式
工厂方法模式定义: 即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类)."一对一"的关系 1,一抽象工厂类派生出多个具体工厂类: 2, ...
- Java设计模式(工厂模式>抽象工厂模式和原型模式)
Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...
最新文章
- 一些量化(quantization)技巧
- 3D视觉创新应用(三维重建)竞赛作品系列——人体三维精准量测与动作捕捉
- BAPI_SALESORDER_CREATEFROMDAT2 条件 定价元素
- asp.net core系列 48 Identity 身份模型自定义
- mac 安装和使用MongoDB
- select模型的原理、优点、缺点
- 你是否需要购买网站重构?
- Illustrator 教程,如何在 Illustrator 中描摹对象?
- jackson json的使用
- 几大经典算法c语言cnds,浮点数据有损压缩算法 附完整C代码
- 关于windows完成端口(IOCP)的一些理解
- 计算机常见故障及其原因
- 《系统集成项目管理》第十二章 项目沟通管理和干系人管理
- Word一部分内容分为两栏或多栏的方法
- 网络安全究竟是什么?如何成为一位优秀的网络安全工程师?
- 如何用 Python 爬取网易云音乐歌单
- Java线程池及配置参数详解
- Android中的Picasso实现圆角图片
- matplotlib基本使用(二)
- Finereport 9.0升级到10.0工具下载[9-10升级工具]
热门文章
- Ubuntu安装teamviewer
- QQ企业邮箱+Spring+Javamail+ActiveMQ(发送企业邮件)
- 《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一2.3 执行计划各个列的含义...
- 居民安装光伏系统常会碰壁 怎么样做才能少走弯路?
- log4j 不同功能,同INFO级别,输出到不同log文件
- Codeforces 509C Sums of Digits
- Android开发网
- HSRP与VRRP以及GLBP区别
- 推荐一些好书(PHP方向)
- 经典仿句100例_(完整版)精美句子仿写100例