-
2021-12-29 22:55:38
1. 抽象工厂模式
-
针对工厂方法模式无法创建一组相关或相互依赖对象的问题,引入了抽象工厂模式
-
抽象工厂模式的官方定义如下:
是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
1.1 敲黑板,画重点 —— 定义解读
提供一个创建一组相关或相互依赖对象的接口
- 相对工厂方法模式,抽象工厂模式的抽象工厂定义了多个创建对象的接口
不同等级的产品:
- 不同类的产品,又叫不同等级的产品。
- 工厂方法模式中,只考虑同一等级产品的生产,只是同一等级的产品也有很多不同的型号
- 就像电子厂只生产游戏机,游戏机有多种类型:插卡的游戏机、插光盘的游戏机、便携式游戏机(玩俄罗斯方块的那种😂)
同族的产品
- 现实生活中,电子厂不止生产游戏机,还生产电视机、音箱等产品。
- 这些由一个工厂生产的不同等级的产品,被称为产品族
- 因此,同族的不同等级的产品,就是指一个工厂能生产多类产品,与前面的
创建一组相关或相互依赖对象的接口
呼应 - 以海尔和TCL两家公司为例,产品族和产品等级的示意图如下
总结起来
- 抽象工厂模式中,工厂不再只生产一类产品,而是可以生产多类产品
- 也就是说,工厂可以支持多种类型的对象的创建
- 调用者无需指定对象类型(具体的类),就可以通过工厂类创建多种类型的对象
2. UML图
- 抽象工厂模式的UML图如下:
- 抽象工厂(Abstract Factory):定义了多个创建产品的接口,可以创建多个不同等级的产品
- 具体工厂(Abstract Factory):实现抽象工厂中的抽象方法,负责创建具体的产品
- 抽象产品(Product): 相对工厂方法模式,抽象工厂模式中的产品将是多种等级的。因此,一般会定义多个抽象产品
3. 代码示例
- 以海尔和TCL两家公司为例,实现抽象工厂模式
创建两个抽象产品类
-
假设产品只有电视机和空调两种等级
public interface TV { void play(); } public interface AirConditioner { void heat(); }
创建具体产品类
-
实现抽象产品接口,为海尔和TCL公司创建具体产品类
public class HaierTV implements TV{ @Override public void play() { System.out.println("海尔电视机,销量全国领先"); } } public class TCLTV implements TV{ @Override public void play() { System.out.println("TCL牌电视机,家家都在看的电视机"); } } public class HaierAirConditioner implements AirConditioner{ @Override public void heat() { System.out.println("海尔牌空调,制热效果好,省电又省心~"); } } public class TCLAirConditioner implements AirConditioner { @Override public void heat() { System.out.println("TCL牌空调,制热效果杠杠的"); } }
创建抽象工厂类
-
有两个接口,分别用于创建电视机和空调
public interface AbstractFactory { TV getTV(); AirConditioner getAirConditioner(); }
创建具体工厂类
- 为海尔和TCL两家公司,创建具体工厂类,实现具体产品的创建
public class HaierFactory implements AbstractFactory{ @Override public TV getTV() { return new HaierTV(); } @Override public AirConditioner getAirConditioner() { return new HaierAirConditioner(); } } public class TCLFactory implements AbstractFactory{ @Override public TV getTV() { return new TCLTV(); } @Override public AirConditioner getAirConditioner() { return new TCLAirConditioner(); } }
4. 总结
4.1 抽象工厂模式的总结
- 创建属于不同操作系统的视窗构件,是抽象工厂模式最早的应用。
- 如 Java 的 AWT 中的 Button 和 Text 等构件,在 Windows 和 UNIX 中的本地实现是不同的。
适用场景:
- 需要创建的对象是一系列相关或相互依赖的产品族
- 不同环境,需要使用不同产品族(系统中有多个产品族,但每次只使用其中的某一族产品)
开闭原则的倾斜性
- 增加一个产品族,只需要增加一个新的工厂类,无需修改已有的工厂 —— 满足开闭原则
- 增加一个新等级的产品,抽象工厂和具体工厂都需要进行修改 —— 不满足开闭原则
- 这样的现象被称作:开闭原则的倾斜性
4.2 工厂模式的总结
简单工厂模式
- 从长期的编程习惯总结出来的简单工厂模式,需要调用者传入对象名称,才能为其创建指定的对象
- 新增对象类型时,需要修改已有代码,违背了开闭原则
工厂方法模式
- 每个工厂只负责创建一种类型的对象,是对简单工厂模式的升级改造
- 虽然遵守了开闭原则,但是容易工厂类过多,且不支持创建一组相关或相互依赖的对象的场景
抽象工厂模式
- 将一组相关或相互依赖的对象,抽象成产品族,每个工厂负责创建一个产品族
- 开闭原则的倾斜性:新增产品族,满足开闭原则;新增产品,不满足开闭原则
参考链接:这是两篇不同的博客,名字相似而已😂
更多相关内容 -
-
常用设计模式——抽象工厂模式
2022-03-05 11:24:00本篇博客给大家介绍常用设计模式中的抽象工厂模式。本节要介绍的抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族。目录
前言
本篇博客给大家介绍常用设计模式中的抽象工厂模式,这个模式可能对于新手有点难以理解,不过没关系,我们重要的是感受它的设计思想,能理解多少算多少。
现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品,如农场里既养动物又种植物,电器厂既生产电视机又生产洗衣机或空调,大学既有软件专业又有生物专业等。
本节要介绍的抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族,图 1 所示的是海尔工厂和 TCL 工厂所生产的电视机与空调对应的关系图。
图1 电器工厂的产品等级与产品族
1.抽象工厂模式的定义与特点
抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
使用抽象工厂模式一般要满足以下条件:
-
可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
-
当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
-
抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。
2.抽象工厂模式的结构与实现
抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。现在我们来分析其基本结构和实现方法。
2.1 抽象工厂模式的结构
抽象工厂模式的主要角色如下:
-
抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
-
具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
-
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
-
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
抽象工厂模式的结构图如下:
图2 抽象工厂模式的结构图
2.2 抽象工厂模式的实现
【例】使用抽象工厂模式模仿生产小米手机、华为手机、小米路由器、华为路由器。
根据抽象工厂模式的结构图,首先要创建手机和路由器接口:
- 手机接口
public interface Phone { void callup(); void sendSMS(); }
- 路由器接口
public interface Router { void openWifi(); void setting(); }
接着创建小米手机、华为手机、小米路由器、华为路由器的具体实现类:
- 小米手机
public class XiaomiPhone implements Phone { @Override public void callup() { System.out.println("小米手机打电话"); } @Override public void sendSMS() { System.out.println("小米手机发短信"); } }
- 华为手机
public class HuaweiPhone implements Phone { @Override public void callup() { System.out.println("华为手机打电话"); } @Override public void sendSMS() { System.out.println("华为手机发短信"); } }
- 小米路由器
public class XiaomiRouter implements Router { @Override public void openWifi() { System.out.println("小米路由器打开WiFi"); } @Override public void setting() { System.out.println("小米路由器设置"); } }
- 华为路由器
public class HuaweiRouter implements Router { @Override public void openWifi() { System.out.println("华为路由器打开WiFi"); } @Override public void setting() { System.out.println("华为路由器设置"); } }
接着创建工厂接口(也就是抽象工厂)以及它的具体实现类小米工厂和华为工厂:
- 工厂接口(抽象工厂)
public interface ProductFactory { Phone getPhone(); Router getRouter(); }
- 小米工厂
public class XiaomiFactory implements ProductFactory { @Override public Phone getPhone() { return new XiaomiPhone(); } @Override public Router getRouter() { return new XiaomiRouter(); } }
- 华为工厂
public class HuaweiFactory implements ProductFactory { @Override public Phone getPhone() { return new HuaweiPhone(); } @Override public Router getRouter() { return new HuaweiRouter(); } }
最后写一个客户端测试一下:
public class Client { public static void main(String[] args) { System.out.println("=============小米系列============="); XiaomiFactory xiaomiFactory = new XiaomiFactory(); Phone phone = xiaomiFactory.getPhone(); phone.callup(); phone.sendSMS(); Router router = xiaomiFactory.getRouter(); router.openWifi(); System.out.println("=============华为系列============="); HuaweiFactory huaweiFactory = new HuaweiFactory(); phone = huaweiFactory.getPhone(); phone.callup(); phone.sendSMS(); router = huaweiFactory.getRouter(); router.openWifi(); } }
ps:如果这篇博客对你有帮助或者启发的话,就给博主点个赞吧,谢谢啦!
-
-
工厂方法和抽象工厂模式
2021-09-24 14:21:08文章目录一、工厂方法1、工厂法法模式结构图:2、工厂方法模式的优缺点二、抽象工厂模式1、抽象工厂模式结构图2、抽象工厂模式的优缺点 一、工厂方法 工厂方法定义:定义一个用于创建对象的接口,让子类决定实例化哪...一、工厂方法
工厂方法定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
1、工厂法法模式结构图:
工厂方法抽象出一个工厂接口,这个接口只有一个方法,就是创建抽象产品的工厂方法,所有要生产具体类的工厂就去实现这个接口。当需要创建新对象的工厂时,就不需要更改原有的工厂类,只需要增加相应的工厂类。产品抽象类 Product
public abstract class Product { protected String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
具体产品类 ConcreteProductA
public class ConcreteProductA extends Product{ public ConcreteProductA(){ super(); this.name = "具体产品 A"; } }
具体产品类 ConcreteProductB
public class ConcreteProductB extends Product{ public ConcreteProductB(){ super(); this.name = "具体产品 B"; } }
抽象工厂接口 Factory
public interface Factory { public Product createProduct(); }
创建 ConcreteProductA 的工厂类 ConcreteProductAFactory
public class ConcreteProductAFactory implements Factory{ @Override public Product createProduct() { return new ConcreteProductA(); } }
创建 ConcreteProductB 的工厂类 ConcreteProductBFactory
public class ConcreteProductBFactory implements Factory{ @Override public Product createProduct() { return new ConcreteProductB(); } }
效果测试类
public class FactoryMethodTest { public static void main(String[] args) { Factory factoryA = new ConcreteProductAFactory(); Factory factoryB = new ConcreteProductBFactory(); Product productA = factoryA.createProduct(); Product productB = factoryB.createProduct(); System.out.println(productA.getName()); System.out.println(productB.getName()); } }
2、工厂方法模式的优缺点
工厂方法模式具有良好的封装性,代码结构清晰。如果一个调用者需要一个具体的产品对象,只要知道这个产品的类名,不用知道创建对象的艰辛过程,降低模块间的耦合,并且拓展性好。但缺点也是相对的,每增加一个产品,就需要加一个产品的工厂类,增加了额外的开发量。
二、抽象工厂模式
抽象工厂模式定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
1、抽象工厂模式结构图
AbstractProductA 和 AbstractProductB 是两个抽象产品,而ProductA1和ProductA2、ProductB1、ProductB2就是对两个抽象产品的具体实现。AbstractFactory是一个抽象工厂接口,它里面包含所有产品创建的抽象方法。而ConcreteFactory1 和ConcreteFactory2就是具体的工厂了。
抽象产品类 AbstractProductA
public abstract class AbstractProductA { protected String type = "A型产品"; protected String name; public String getName() { return name; } public void setName(String name) { this.name = name; } /** 每个产品具体实现该方法 */ public abstract void doSomething(); }
抽象产品类 AbstractProductB
public abstract class AbstractProductB { protected String type = "B型产品"; protected String name; public String getName() { return name; } public void setName(String name) { this.name = name; } /** 每个产品具体实现该方法 */ public abstract void doSomething(); }
A型具体产品 ProductA1
public class ProductA1 extends AbstractProductA{ public ProductA1(){ super(); this.name = "产品A1"; } @Override public void doSomething() { System.out.println(this.name + " doSomething"); } }
A型具体产品 ProductA2
public class ProductA2 extends AbstractProductA{ public ProductA2(){ super(); this.name = "产品A2"; } @Override public void doSomething() { System.out.println(this.name + " doSomething"); } }
B型具体产品 ProductB1
public class ProductB1 extends AbstractProductB{ public ProductB1(){ super(); this.name = "产品B1"; } @Override public void doSomething() { System.out.println(this.name + " doSomething"); } }
B型具体产品 ProductB2
public class ProductB2 extends AbstractProductB{ public ProductB2(){ super(); this.name = "产品B2"; } @Override public void doSomething() { System.out.println(this.name + " doSomething"); } }
抽象工厂接口 AbstractFactory
public interface AbstractFactory { public AbstractProductA createProductA(); public AbstractProductB createProductB(); }
创建1系列产品的工厂类 ConcreteFactory1
public class ConcreteFactory1 implements AbstractFactory{ @Override public AbstractProductA createProductA() { return new ProductA1(); } @Override public AbstractProductB createProductB() { return new ProductB1(); } }
创建2系列产品的工厂类 ConcreteFactory2
public class ConcreteFactory2 implements AbstractFactory{ @Override public AbstractProductA createProductA() { return new ProductA2(); } @Override public AbstractProductB createProductB() { return new ProductB2(); } }
效果测试类
public class AbstractFactoryTest { public static void main(String[] args) { AbstractFactory factory = new ConcreteFactory1(); AbstractProductA productA = factory.createProductA(); AbstractProductB productB = factory.createProductB(); productA.doSomething(); productB.doSomething(); System.out.println("=========切换产品系列工厂========="); factory = new ConcreteFactory2(); productA = factory.createProductA(); productB = factory.createProductB(); productA.doSomething(); productB.doSomething(); } }
输出:
产品A1 doSomething
产品B1 doSomething
=切换产品系列工厂=
产品A2 doSomething
产品B2 doSomething由此可见,切换工厂类,即可对获取的产品系列进行切换
2、抽象工厂模式的优缺点
抽象工厂最大的好处是便于切换产品系列,其次是它让具体的创建实例过程与客户端分离,客户端是通过抽象接口获取实例,依赖的产品也是抽象的,而不是具体的产品类。
抽象工厂的缺点是产品族的拓展非常困难,如果增加了一个产品,抽象工厂类中需要增加创建该产品的抽象方法,具体工厂类中也得去实现,涉及到的改动多。
-
抽象工厂模式uml类图
2018-03-07 10:41:31java设计模式 抽象工厂模式详解 一张图让你彻底明白抽象工厂模式 -
PHP实现设计模式中的抽象工厂模式详解
2020-12-18 21:16:31【抽象工厂模式结构图】 【抽象工厂模式中主要角色】 抽象工厂(Abstract Factory)角色:它声明一个创建抽象产品对象的接口。通常以接口或抽象类实现,所有的具体工厂类必须实现这个接口或继承这个类。 具体工厂... -
工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)(图解+源码)
2020-11-29 21:22:44简单工厂模式简单工厂模式
基本介绍
- 简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式
- 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
- 在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.
注:GOF 在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
看一个具体的需求
看一个披萨的项目:要便于披萨种类的扩展,要便于维护
- 披萨的种类很多(比如GreekPizz、CheesePizz 等)
- 披萨的制作有prepare,bake, cut, box
- 完成披萨店订购功能。
使用传统的方式来完成
- 思路分析(类图)
编写OrderPizza.java 去订购需要的各种Pizza
2)代码实现public OrderPizza() { Pizza pizza = null; String orderType; // 订购披萨的类型 do { orderType = getType(); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else if (orderType.equals("pepper")) { pizza = new PepperPizza(); pizza.setName("胡椒披萨"); } else { break; } //输出pizza 制作过程 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); }
传统的方式的优缺点
- 优点是比较好理解,简单易操作。
- 缺点是违反了设计模式的ocp 原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码.
- 比如我们这时要新增加一个Pizza 的种类(Pepper 披萨),我们需要做如下修改.
如果我们增加一个Pizza 类,只要是订购Pizza 的代码都需要修改.
4) 改进的思路分析
分析:修改代码可以接受,但是如果我们在其它的地方也有创建Pizza 的代码,就意味着,也需要修改,而创建Pizza的代码,往往有多处。
思路:把创建Pizza 对象封装到一个类中,这样我们有新的Pizza 种类时,只需要修改该类就可,其它有创建到Pizza对象的代码就不需要修改了.-> 简单工厂模式使用简单工厂模式
概念:简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
组成:
工厂(Creator)角色:
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。抽象产品(Product)角色:
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。具体产品(Concrete Product)角色:
是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。类图:
- 简单工厂模式的设计方案: 定义一个可以实例化Pizaa 对象的类,封装创建对象的代码。
- 代码示例
普通OrderPizza类
public class OrderPizza { //定义一个简单工厂对象 SimpleFactory simpleFactory; Pizza pizza = null; //构造器 public OrderPizza(SimpleFactory simpleFactory) { setFactory(simpleFactory); } public void setFactory(SimpleFactory simpleFactory) { String orderType = ""; //用户输入的 this.simpleFactory = simpleFactory; //设置简单工厂对象 do { orderType = getType(); pizza = this.simpleFactory.createPizza(orderType); //输出pizza if(pizza != null) { //订购成功 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println(" 订购披萨失败"); break; } }while(true); } // 写一个方法,可以获取客户希望订购的披萨种类 private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza 种类:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } }
静态OrderPizza2类
public class OrderPizza2 { Pizza pizza = null; String orderType = ""; // 构造器 public OrderPizza2() { do { orderType = getType(); pizza = SimpleFactory.createPizza2(orderType); // 输出pizza if (pizza != null) { // 订购成功 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println(" 订购披萨失败 "); break; } } while (true); } // 写一个方法,可以获取客户希望订购的披萨种类 private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza 种类:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } }
工厂类
//简单工厂类 public class SimpleFactory { //更加orderType 返回对应的Pizza 对象 public Pizza createPizza(String orderType) { Pizza pizza = null; System.out.println("使用简单工厂模式"); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else if (orderType.equals("pepper")) { pizza = new PepperPizza(); pizza.setName("胡椒披萨"); } return pizza; } //简单工厂模式 也叫 静态工厂模式 public static Pizza createPizza2(String orderType) { Pizza pizza = null; System.out.println("使用简单工厂模式2"); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else if (orderType.equals("pepper")) { pizza = new PepperPizza(); pizza.setName("胡椒披萨"); } return pizza; } }
工厂方法模式
看一个新的需求
披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如北京的奶酪pizza、北京的胡椒pizza 或者是伦敦的奶酪pizza、伦敦的胡椒pizza。
思路1
使用简单工厂模式,创建不同的简单工厂类,比如BJPizzaSimpleFactory、LDPizzaSimpleFactory 等等.从当前这个案例来说,也是可以的,但是考虑到项目的规模,以及软件的可维护性、可扩展性并不是特别好
思路2
使用工厂方法模式
工厂方法模式介绍
-
工厂方法模式设计方案:将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现。
-
工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
工厂方法模式的结构
-
抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在 java 中它由抽象类或者接口来实现。
-
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
-
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在 java 中一般有抽象类或者接口来实现。
-
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在 java 中由具体的类来实现。
类图:
工厂方法模式应用案例
-
披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如北京的奶酪pizza、北京的胡椒pizza 或者是伦敦的奶酪pizza、伦敦的胡椒pizza
-
思路分析图解
-
看代码实现
OrderPizza 类
public abstract class OrderPizza { //定义一个抽象方法,createPizza , 让各个工厂子类自己实现 abstract Pizza createPizza(String orderType); // 构造器 public OrderPizza() { Pizza pizza = null; String orderType; // 订购披萨的类型 do { orderType = getType(); pizza = createPizza(orderType); //抽象方法,由工厂子类完成 //输出pizza 制作过程 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } while (true); } // 写一个方法,可以获取客户希望订购的披萨种类 private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza 种类:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } }
public class BJOrderPizza extends OrderPizza { @Override Pizza createPizza(String orderType) { Pizza pizza = null; if(orderType.equals("cheese")) { pizza = new BJCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new BJPepperPizza(); } // TODO Auto-generated method stub return pizza; } }
public class LDOrderPizza extends OrderPizza { @Override Pizza createPizza(String orderType) { Pizza pizza = null; if(orderType.equals("cheese")) { pizza = new LDCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new LDPepperPizza(); } // TODO Auto-generated method stub return pizza; } }
抽象工厂模式
基本介绍
-
抽象工厂模式:定义了一个interface 用于创建相关或有依赖关系的对象簇,而无需指明具体的类
-
抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
-
从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
-
将工厂抽象成两层,AbsFactory(抽象工厂) 和具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
角色
-
抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在 java 中它由抽象类或者接口来实现。
-
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在 java 中它由具体的类来实现。
-
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在 java 中一般有抽象类或者接口来实现。
-
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在 java 中由具体的类来实现。
类图如下:
类图
需求类图
抽象工厂模式应用实例
使用抽象工厂模式来完成披萨项目.
//一个抽象工厂模式的抽象层(接口) public interface AbsFactory { //让下面的工厂子类来 具体实现 public Pizza createPizza(String orderType); }
//这是工厂子类 public class BJFactory implements AbsFactory { @Override public Pizza createPizza(String orderType) { System.out.println("~使用的是抽象工厂模式~"); // TODO Auto-generated method stub Pizza pizza = null; if(orderType.equals("cheese")) { pizza = new BJCheesePizza(); } else if (orderType.equals("pepper")){ pizza = new BJPepperPizza(); } return pizza; } }
public class LDFactory implements AbsFactory { @Override public Pizza createPizza(String orderType) { System.out.println("~使用的是抽象工厂模式~"); Pizza pizza = null; if (orderType.equals("cheese")) { pizza = new LDCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } }
public class OrderPizza { AbsFactory factory; // 构造器 public OrderPizza(AbsFactory factory) { setFactory(factory); } private void setFactory(AbsFactory factory) { Pizza pizza = null; String orderType = ""; // 用户输入 this.factory = factory; do { orderType = getType(); // factory 可能是北京的工厂子类,也可能是伦敦的工厂子类 pizza = factory.createPizza(orderType); if (pizza != null) { // 订购ok pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); } else { System.out.println("订购失败"); break; } } while (true); } // 写一个方法,可以获取客户希望订购的披萨种类 private String getType() { try { BufferedReader strin = new BufferedReader(new InputStreamReader(System.in)); System.out.println("input pizza 种类:"); String str = strin.readLine(); return str; } catch (IOException e) { e.printStackTrace(); return ""; } } }
工厂模式在JDK-Calendar 应用的源码分析
- JDK 中的Calendar 类中,就使用了简单工厂模式
import java.util.Calendar; public class Factory { public static void main(String[] args) { // TODO Auto-generated method stub // getInstance 是 Calendar 静态方法 Calendar cal = Calendar.getInstance();//Calendar类的源码 // 注意月份下标从0开始,所以取月份要+1 System.out.println("年:" + cal.get(Calendar.YEAR)); System.out.println("月:" + (cal.get(Calendar.MONTH) + 1)); System.out.println("日:" + cal.get(Calendar.DAY_OF_MONTH)); System.out.println("时:" + cal.get(Calendar.HOUR_OF_DAY)); System.out.println("分:" + cal.get(Calendar.MINUTE)); System.out.println("秒:" + cal.get(Calendar.SECOND)); } }
public static Calendar getInstance(){ return createCalendar (TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT)); }
private static Calendar createCalendar(TimeZone zone, Locale aLocale) { if (provider != null) { try { return provider.getInstance(zone, aLocale);//默认方式获取 } catch (IllegalArgumentException iae) { // fall back to the default instantiation } } Calendar cal = null; if (aLocale.hasExtensions()) { String caltype = aLocale.getUnicodeLocaleType("ca"); }
工厂模式小结
- 工厂模式的意义
将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。 - 三种工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)
- 设计模式的依赖抽象原则
- 创建对象实例时,不要直接new 类, 而是把这个new 类的动作放在一个工厂的方法中,并返回。有的书上说,变量不要直接持有具体类的引用。
- 不要让类继承具体类,而是继承抽象类或者是实现interface(接口)
- 不要覆盖基类中已经实现的方法。
源码
总结
简单工厂模式:定义了一个创建对象的类,由这个类(工厂类)来封装实例化对象的行为(代码)
工厂方法模式: 定义了一个创建对象的抽象方法,由子类(子工厂)决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
抽象工厂模式:将工厂抽象成两层,AbsFactory(抽象工厂) 和具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
-
一起学习设计模式--04.抽象工厂模式
2021-03-07 21:42:45为了解决这个问题,可以考虑将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产,这就是抽象工厂模式的基本思想。 一、界面皮肤库的初始设计 A科技公司打算开发一套界面皮肤库,可以对Winform桌面软件进行... -
学习php设计模式 php实现抽象工厂模式
2021-01-20 00:54:31二、抽象工厂模式结构图 三、抽象工厂模式中主要角色 抽象工厂(Abstract Factory)角色:它声明一个创建抽象产品对象的接口。通常以接口或抽象类实现,所有的具体工厂类必须实现这个接口或继承这个类。 具体工厂... -
设计模式之抽象工厂模式(Java实现)
2022-05-02 08:29:18文章目录前言一、认识抽象工厂模式二、实现抽象工厂模式2.1、代码实现2.2、分析说明总结参考资料 前言 本篇博客是关于抽象工厂的实现,若文章中出现相关问题,请指出! 对应代码地址:Gitee(demo-exer/ java-Lear23... -
设计模式之抽象工厂模式(Abstract Factory)
2022-05-07 09:58:03目录前言Abstract Factory设计模式1.模式的应对场景2.案例1:数据库的connection、command依赖3....抽象工厂模式解决的是“一系列相互依赖的对象”的创建工作。 设计模式之工厂模式(Factor Method) 2.案 -
详解C#的设计模式编程之抽象工厂模式的应用
2020-09-02 18:48:02主要介绍了C#的设计模式编程之抽象工厂模式的应用,注意区分一下简单工厂模式、工厂方法模式和抽象工厂模式概念之间的区别,需要的朋友可以参考下 -
详解iOS应用开发中使用设计模式中的抽象工厂模式
2020-09-02 14:18:10主要介绍了iOS应用开发中使用设计模式中的抽象工厂模式,示例代码为传统的Objective-C,需要的朋友可以参考下 -
设计模式 - 抽象工厂模式案例
2022-03-17 19:15:41抽象工厂模式适用的环境,抽象工厂模式vs工厂方法模式,产品等级结构和产品族的概念,模式结构的4个角色,抽象工厂模式案例及代码:计算机包含内存(RAM),CPU等硬件设备,根据如图所示的“产品等级结构-产品族示意... -
c++抽象工厂模式
2022-07-07 14:54:49抽象工厂模式 -
设计模式之简单工厂模式和抽象工厂模式
2021-11-08 17:10:24目录 1简单工厂模式 1.1组成 1.2简单例子 1.2.1 抽象产品角色 1.2.2具体产品角色 1.2.3 工厂类角色 1.2.4 顾客测试类 ...2抽象工厂模式 ...2.2模式的结构与实现 ...2.2.1模式的结构 ... 抽象工厂模式(Abstract... -
【C++设计模式】抽象工厂模式
2022-02-18 21:04:37(1)抽象工厂模式结构与工厂方法模式结构类似,不同之处在于,一个具体工厂可以生产多种同类相关的产品。 抽象工厂模式的优点: 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,... -
【深入设计模式】工厂模式—抽象工厂及工厂模式在源码中的应用
2022-05-27 22:10:29前面介绍了简单工厂模式...接下来将继续深入工厂模式,主要介绍工厂方法模式的改进——抽象工厂模式,以及工厂模式在框架源码中的应用,希望在看完这两篇介绍之后能够对彻底搞懂工厂模式,并理解其在实际开发中的意义。 -
Java设计模式编程中简单工厂与抽象工厂模式的使用实例
2020-09-02 11:58:31主要介绍了Java设计模式编程中简单工厂与抽象工厂模式的使用实例,简单工厂与抽象工厂都可以归类于设计模式中的创建型模式,需要的朋友可以参考下 -
抽象工厂模式
2022-03-13 16:36:041. 抽象工厂模式的动机与定义 1.1 抽象工厂模式的动机 在工厂方法模式中具体的工厂负责生产具体的产品,每一个产品对应一个工厂,工厂方法也具有唯一性,一般情况下,一个具体的工厂只有一个工厂方法或一组重载的... -
抽象工厂模式的详解
2020-11-06 00:47:401.为什么需要抽象工厂模式? 虽然工厂方法模式引入工厂等级结构,解决了简单工厂模式中工厂类职责过重的问题,但由于工厂方法模式中每个工厂只创建一类具体类的对象,如果需要的具体类很多时候,这将会导致系统当中... -
解析iOS应用开发中对设计模式中的抽象工厂模式的实现
2020-09-02 14:01:34主要介绍了解析iOS应用开发中对设计模式中的抽象工厂模式的实现,示例代码为传统的Objective-C,需要的朋友可以参考下 -
学习设计模式之抽象工厂模式
2022-04-13 21:32:39而抽象工厂模式生产的是多个不同类型的不同产品,所以必须将共同点抽象出来,例如戴尔CPU,苹果CPU,抽象的接口就是CPU。(再比如:戴尔GPU,苹果GPU,抽象的接口就是GPU)。 这是为了遵守面向对象的原则之一,面向... -
【设计模式】抽象工厂模式 ( 简介 | 适用场景 | 优缺点 | 产品等级结构和产品族 | 代码示例 )
2021-08-22 22:31:30一、抽象工厂模式简介、 二、抽象工厂模式适用场景、 三、抽象工厂模式优缺点、 四、产品等级结构和产品族、 五、抽象工厂模式代码示例、 1、冰箱抽象类、 2、美的冰箱实现类、 3、格力冰箱实现类、 4、空调抽象类、... -
设计模式学习笔记(三)工厂模式中的简单工厂、工厂方法和抽象工厂模式之间的区别
2022-04-14 10:24:24设计模式中的工厂模式(Factory Design pattern)是一个比较常用的创建型设计模式,其中可以细分为三种:简单工厂(Simple Factory)、工厂方法(Factory Method)和抽象工厂(Abstract Factory)。那么三者有什么区别呢... -
Spring常用设计模式--抽象工厂模式
2022-03-15 16:54:45本专栏内容参考自:咕泡学院Tom老师的《Spring5核心原理与30个类手写实战》,仅作个人学习记录使用,如有侵权,联系速删。 ... 看抽象工厂模式之前,我们要了解两个概念:产品等级结构和产品族. -
抽象工厂模式(详解版)
2021-02-28 18:12:40前面介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。同种类称为同等级,也就是说...本节要介绍的抽象工厂模式将考虑多等级产... -
Java-设计模式之工厂模式(静态工厂模式、工厂方法模式、抽象工厂模式)
2021-11-16 15:12:04工厂模式(静态工厂模式、工厂方法模式、抽象工厂模式) 引子 话说十年前,有一个暴发户,他家有三辆汽车——Benz 奔驰、Bmw 宝马、Audi 奥迪,还雇了司机为他开车。不过,暴发户坐车时总是怪怪的:上 Benz 车后跟司机说... -
简单工厂、工厂方法、抽象工厂模式
2021-02-19 20:39:46 现实生活中,原始社会自给自足(没有工厂),农耕社会小作坊(简单工厂,民间酒坊),工业革命流水线(工厂方法,自产自销),现代产业链代工厂(抽象工厂,富士康)。我们的项目代码同样是由简到繁一步一步迭代... -
设计模式:抽象工厂模式,结合类图秒懂!
2019-07-11 09:13:33通过前篇文章《设计模式:工厂模式》的介绍,我们对工厂模式有了深入的了解,今天继续介绍一种特殊的工厂模式,也就是抽象工厂模式。 定义 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定...