文章目录

  • 1. 工厂模式概述
  • 2. 简单工厂模式
  • 3. 工厂方法模式
  • 4. 抽象工厂模式

1. 工厂模式概述

工厂模式属于创建型模式的一种。

在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则

工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,使得如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦

开闭原则:

开闭原则要求对 扩展开放(对提供方),对修改关闭(对使用方)

工厂模式分为以下三种:

  • 简单工厂模式(不属于GOF的23种经典设计模式)
  • 工厂方法模式
  • 抽象工厂模式

2. 简单工厂模式

简单工厂不是一种设计模式,反而比较像是一种编程习惯

简单工厂模式的核心是定义一个创建对象的接口将对象的创建和本身的业务逻辑分离,降低系统的耦合度,使得两个修改起来相对容易些,当以后实现改变时,只需要修改工厂类即可。

简单工厂包含如下角色:

  • 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品 :实现或者继承抽象产品的子类
  • 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。

实现简单工厂模式的基本思路是什么?

简单工厂的实现思路是,定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。简单工厂适用于需要创建的对象较少或客户端不关心对象的创建过程的情况

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VKO6QEBf-1668690825240)(https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/9944/%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F.png)]

工厂类代码如下:

public class SimpleCoffeeFactory {public Coffee createCoffee(String type) {Coffee coffee = null;if("americano".equals(type)) {coffee = new AmericanoCoffee();} else if("latte".equals(type)) {coffee = new LatteCoffee();}return coffee;}
}

咖啡店类

public class CoffeeStore {public Coffee orderCoffee(String type) {SimpleCoffeeFactory factory = new SimpleCoffeeFactory();//调用生产咖啡的方法Coffee coffee = factory.createCoffee(type);//加配料coffee.addMilk();coffee.addsugar();return coffee;}
}

测试类

public class Client {public static void main(String[] args) {//创建咖啡店类对象CoffeeStore store = new CoffeeStore();Coffee coffee = store.orderCoffee("latte");System.out.println(coffee.getName());}
}

工厂(factory)处理创建对象的细节,一旦有了SimpleCoffeeFactory,CoffeeStore类中的orderCoffee()就变成此对象的客户,后期如果需要Coffee对象直接从工厂中获取即可。这样也就解除了和Coffee实现类的耦合,同时又产生了新的耦合,CoffeeStore对象和SimpleCoffeeFactory工厂对象的耦合,工厂对象和商品对象的耦合。

后期如果再加新品种的咖啡,我们势必要需求修改SimpleCoffeeFactory的createCoffee方法的代码,违反了开闭原则。工厂类的客户端可能有很多,比如创建美团外卖等,这样只需要修改工厂类的代码,省去其他的修改操作。

简单工厂模式有什么优点?

简单工厂模式封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。

简单工厂模式有什么缺点?

增加新产品时还是需要修改工厂类的代码,违背了“开闭原则”。

简单工厂模式还可以怎么实现?

简单工厂模式还可以使用静态工厂的方式实现,也就是将创建对象功能定义成静态的。

public class SimpleCoffeeFactory {public static Coffee createCoffee(String type) {Coffee coffee = null;if("americano".equals(type)) {coffee = new AmericanoCoffee();} else if("latte".equals(type)) {coffee = new LatteCoffee();}return coffe;}
}

3. 工厂方法模式

工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B4Jo4q8C-1668690825241)(https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/9944/%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F.png)]

工厂方法模式的主要角色:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
  • 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

具体实现:

抽象工厂

public interface CoffeeFactory {Coffee createCoffee();
}

具体工厂

public class LatteCoffeeFactory implements CoffeeFactory {public Coffee createCoffee() {return new LatteCoffee();}
}public class AmericanCoffeeFactory implements CoffeeFactory {public Coffee createCoffee() {return new AmericanCoffee();}
}

咖啡店类

public class CoffeeStore {private CoffeeFactory factory;public CoffeeStore(CoffeeFactory factory) {this.factory = factory;}public Coffee orderCoffee(String type) {Coffee coffee = factory.createCoffee();coffee.addMilk();coffee.addsugar();return coffee;}
}

测试类

public class Client {public static void main(String[] args) {//创建咖啡店对象CoffeeStore store = new CoffeeStore();//创建对象//CoffeeFactory factory = new AmericanCoffeeFactory();CoffeeFactory factory = new LatteCoffeeFactory();store.setFactory(factory);//点咖啡Coffee coffee = store.orderCoffee();System.out.println(coffee.getName());}
}

由上面的代码可见,当我们需要添加产品的时候也需要添加相应的工厂类,但是却不用修改工厂类的代码,这样就解决了简单工厂模式的缺点。

工厂方法模式是简单工厂模式的进一步抽象。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。

工厂方法模式有什么优点?

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
  • 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

工厂方法模式有什么缺点?

  • 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

4. 抽象工厂模式

在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。

抽象工厂模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

抽象工厂模式的主要角色如下:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
  • 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C8tYIWEU-1668690825242)(https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/9944/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F.png)]

抽象工厂

public interface DessertFactory {Coffee createCoffee();Dessert createDessert();
}

具体工厂

//美式甜点工厂
public class AmericanDessertFactory implements DessertFactory {public Coffee createCoffee() {return new AmericanCoffee();}public Dessert createDessert() {return new MatchaMousse();}
}
//意大利风味甜点工厂
public class ItalyDessertFactory implements DessertFactory {public Coffee createCoffee() {return new LatteCoffee();}public Dessert createDessert() {return new Tiramisu();}
}

测试类

public class Client {public static void main(String[] args) {//创建的是意大利风味甜品工厂对象//ItalyDessertFactory factory = new ItalyDessertFactory();AmericanDessertFactory factory = new AmericanDessertFactory();//获取拿铁咖啡和提拉米苏甜品Coffee coffee = factory.createCoffee();Dessert dessert = factory.createDessert();System.out.println(coffee.getName());dessert.show();}
}

抽象工厂模式有什么优点?

当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

抽象工厂模式有什么缺点?

当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

抽象工厂模式的应用场景有哪些?

  • 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。

  • 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。

  • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。

如:输入法换皮肤,一整套一起换。生成不同操作系统的程序。

抽象工厂模式与工厂方法模式的区别?

  1. 工厂方法只有一个抽象产品类和一个抽象工厂类,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。

  2. 抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例

请你比较以下简单工厂模式、工厂方法模式和抽象工厂模式的异同?

  • 简单工厂模式其实并不算是一种设计模式,更多的时候是一种编程习惯。简单工厂的实现思路是,定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。
  • 工厂方法模式是简单工厂的仅一步深化, 在工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的对象,而是针对不同的对象提供不同的工厂。也就是说每个对象都有一个与之对应的工厂。工厂方法的实现思路是,定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
  • 抽象工厂模式是工厂方法的仅一步深化,在这个模式中的工厂类不单单可以创建一个对象,而是可以创建一组对象。这是和工厂方法最大的不同点。抽象工厂的实现思路是,提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

参考:

  • Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)_张维鹏的博客-CSDN博客
  • 【面试最常见的设计模式之工厂模式】_硕风和炜的博客-CSDN博客_工厂模式 面试
  • 黑马程序员Java设计模式详解, 23种Java设计模式(图解+框架源码分析+实战)

【设计模式】2.工厂模式相关推荐

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

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

  2. JavaScript设计模式--简单工厂模式例子---XHR工厂

    JavaScript设计模式--简单工厂模式例子---XHR工厂 第一步,Ajax操作接口(目的是起一个接口检测作用) (1)引入接口文件 //定义一个静态方法来实现接口与实现类的直接检验 //静态方 ...

  3. 三角形圆形创建与擦除java_设计模式---------------简单工厂模式

    设计模式---------------简单工厂模式 一.题目(Question) 使用简单工厂模式设计一个可以创建不同几何形状(如圆形.方形和三角形等)的绘图工具,每个几何图形都要有绘制draw()和 ...

  4. 策略模式和工厂模式的区别_设计模式之工厂模式-工厂方法模式

    设计模式之工厂模式-工厂方法模式 大家好,欢迎来到污污弹公司,今天司小司又接到了一个新活-披萨项目. 来源:凯哥Java(kaigejava) 需求: 披萨项目: 要方便披萨品种的扩展.要便于维护.要 ...

  5. Java 设计模式之工厂模式(二)

    原文地址:Java 设计模式之工厂模式(二) 博客地址:http://www.extlight.com 一.背景 本篇内容是 Java 设计模式创建型模式的第二篇.上一篇主题为 <Java 设计 ...

  6. 设计模式之工厂模式(三)

    上一次我们已经通过代码,简单的认识了工厂方法模式,具体的思路请移步到设计模式之工厂模式(二),进行查看.这次,让我们通过设计模式的思想,来好好认识下工厂方法模式. 创建者和产品 所有工厂模式都用来封装 ...

  7. php工厂模式和单例模式,php 设计模式之工厂模式、单例模式、注册树模式

    php 设计模式之工厂模式.单例模式.注册树模式 在软件工程中,创建型设计模式承担着对象创建的职责,尝试创建适合程序上下文的对象,对象创建设计模式的产生是由于软件工程设计的问题,具体说是向设计中增加复 ...

  8. 教你如何一篇博客读懂设计模式之—--工厂模式

    一篇博客读懂设计模式之-工厂模式 工厂模式在我们日常开发的时候经常用到,相信大家都有了一定的了解,工厂模式是一种创建对象的设计模式,它提供一种创建对象的最佳方式. 主要过程是: 定义一个创建对象的接口 ...

  9. 一篇博客读懂设计模式之---工厂模式

    设计模式之-工厂模式 工厂模式: 创建过程: 创建Shape接口 public interface Shape {void draw(); } 创建实现类: public class Circle i ...

  10. java 工厂模式详解_Java设计模式之工厂模式详解

    简单工厂其实并不是设计模式,只是一种编程习惯. 首先我们创建父类Cup,所有杯子类的父类.再创建它的子类BigCup和SmallCup类. public abstract class Cup { pu ...

最新文章

  1. python3什么意思_python3中%d什么意思?
  2. python常见面试题:m1={‘a‘:1,‘b‘:2,‘c‘:1} 将同样的value的key集合在list里,输出{1:[‘a‘,‘c‘],2:[‘b‘]}
  3. Kaneboy:临时启事:寻找在北京,熟悉SPS、ASP.NET,有两周空闲时间的朋友
  4. dqs server sql_SQL-Server(一)数据库的基本概念
  5. 爬虫如何监听插件_Go 爬虫之 colly 从入门到不放弃指南
  6. .html() 与.text() 获取值、取值 区别
  7. node + node-webkit实现电脑文件信息扫描小插件
  8. ios点击推送闪退_越狱后改造iOS系统 Cydia篇
  9. Docker 管理之 --- 资源限制
  10. 【信号去噪】基于Sage-Husa自适应卡尔曼滤波器实现海浪磁场噪声抑制及海浪磁场噪声的产生附matlab代码
  11. 肥猫吃披萨游戏JAVA,题解 P1488 【肥猫的游戏】
  12. 上下定高 中间自适应_css经典布局——头尾固定高度中间高度自适应布局
  13. 业界天花板 | 四度入围Gartner全球《数据防泄露市场指南》
  14. 从零开始大数据--Hadoop、HDFS、MapReduce、HBase、Hive
  15. Ubuntu 怎么在 Libreoffice 中添加字体
  16. 【精品软件】WeGo(微博PPC客户端) Release Note (更新至v1.05 Build20110117)
  17. 日报2015/11/17(第一行代码读书笔记)
  18. 南京网预赛02 BY bly
  19. 浅析webmatrix建站
  20. 坚持努力奋斗学习(有终身受益的重点)

热门文章

  1. 计算机硬件检测数据恢复理论知识,计算机硬件检测维与数据恢复赛项规程.doc...
  2. 企业官网中的“农家老宅”和“精品房”区别在哪?
  3. 容灾备份概念及实现方式
  4. Qt蓝牙:QBluetoothDeviceInfo、QBluetoothAddress
  5. java 雷霆战机 教程,java swing实现简单的雷霆战机小游戏项目源码附带视频指导修改教程...
  6. 小荷才露尖尖角之struts的秘密
  7. ArcGIS基础知识之shape文件的构成
  8. K8S集群应用市场安装部署:第一篇
  9. MATLAB画心形立体图
  10. 滤波器基础05——巴特沃斯、切比雪夫与贝塞尔滤波器