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设计模式之工厂方法模式与抽象工厂模式相关推荐

  1. 初学 Java 设计模式(三):实战抽象工厂方法模式 「QQ 厘米秀装扮」

    一.抽象工厂方法模式介绍 1. 解决的问题 通过接口的选择,解决在系统产品存在多个产品族,而系统仅消费某一族的产品的问题. 2. 定义 抽象工厂模式是一个围绕超级工厂创建其他工厂的模式,即抽象工厂是一 ...

  2. 抽象工厂和工厂方法示例_抽象工厂设计模式示例

    抽象工厂和工厂方法示例 本文是我们名为" Java设计模式 "的学院课程的一部分. 在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们. 您将了解模式如此 ...

  3. 『创建型』简单工厂SimpleFactory、工厂方法FactoryMethod、抽象工厂AbstractFactory

    为什么80%的码农都做不了架构师?>>>    几点说明 永远不要纠结于在什么时候使用什么模式 永远不要纠结于什么模式适用于什么情景 永远不要去死记任何的模式 并不是说,23种设计模 ...

  4. JAVA设计模式是个什么玩意儿_02_抽象工厂模式

    1. 定义 2. 思路 抽象工厂模式是工厂方法模式的进一步抽象,为创建一组相关或相互依赖的对象提供一个接口,无需指定它们的具体类.抽象工厂通常用于创一族产品,并且这组产品分不同的等级,不同的工厂生产不 ...

  5. 对设计模式的总结之工厂方法模式和抽象工厂模式

    前言 面向对象编程追求的本质-提高扩展性.可维护性.灵活性和复用性.合理利用面向对象6个原则,能够很好的达到要求.如何利用好就是至关重要的了,前人总结了23+个设计模式能够让初学者更容易学到其中的精髓 ...

  6. 设计模式详解(四)抽象工厂模式

    文章目录 1. 简介 2. 代码实例 3. 抽象工厂的优缺点 1. 简介 定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类 与工厂方法模式不同(工厂方法的升级,在工厂方法模式 ...

  7. JAVA设计模式——工厂模式【简单工厂模式、工厂方法模式、抽象工厂模式】

    目录 简单工厂模式 传统方式 简单工厂模式 静态工厂模式 工厂方法模式 抽象工厂模式 工厂模式JDK-Calendar源码分析 工厂模式小结 简单工厂模式   看一个具体的需求 看一个披萨的项目:要便 ...

  8. Java设计模式-工厂方法模式和抽象工厂模式

    工厂方法模式定义: 即定义一个创建对象的接口(即抽象工厂类),让其子类(具体工厂类)决定实例化哪一个类(具体产品类)."一对一"的关系 1,一抽象工厂类派生出多个具体工厂类: 2, ...

  9. Java设计模式(工厂模式>抽象工厂模式和原型模式)

    Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...

最新文章

  1. 一些量化(quantization)技巧
  2. 3D视觉创新应用(三维重建)竞赛作品系列——人体三维精准量测与动作捕捉
  3. BAPI_SALESORDER_CREATEFROMDAT2 条件 定价元素
  4. asp.net core系列 48 Identity 身份模型自定义
  5. mac 安装和使用MongoDB
  6. select模型的原理、优点、缺点
  7. 你是否需要购买网站重构?
  8. Illustrator 教程,如何在 Illustrator 中描摹对象?
  9. jackson json的使用
  10. 几大经典算法c语言cnds,浮点数据有损压缩算法 附完整C代码
  11. 关于windows完成端口(IOCP)的一些理解
  12. 计算机常见故障及其原因
  13. 《系统集成项目管理》第十二章 项目沟通管理和干系人管理
  14. Word一部分内容分为两栏或多栏的方法
  15. 网络安全究竟是什么?如何成为一位优秀的网络安全工程师?
  16. 如何用 Python 爬取网易云音乐歌单
  17. Java线程池及配置参数详解
  18. Android中的Picasso实现圆角图片
  19. matplotlib基本使用(二)
  20. Finereport 9.0升级到10.0工具下载[9-10升级工具]

热门文章

  1. Ubuntu安装teamviewer
  2. QQ企业邮箱+Spring+Javamail+ActiveMQ(发送企业邮件)
  3. 《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一2.3 执行计划各个列的含义...
  4. 居民安装光伏系统常会碰壁 怎么样做才能少走弯路?
  5. log4j 不同功能,同INFO级别,输出到不同log文件
  6. Codeforces 509C Sums of Digits
  7. Android开发网
  8. HSRP与VRRP以及GLBP区别
  9. 推荐一些好书(PHP方向)
  10. 经典仿句100例_(完整版)精美句子仿写100例