在Java设计模式-工厂模式(2)工厂方法模式 我们知道了工厂方法模式解决了简单工厂模式中的缺陷,做到了满足开闭原则,但是时代是进步的,进而又产生新的问题,工厂难道只能生产一种东西吗。我们所见到的工厂大都都是综合性的。所以就有了抽象工厂模式。
旧图
设计模式系列:
一、前言
1)概述:
- 抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
- 工厂模式中的每一个形态都是针对一定问题的解决方案,工厂方法针对的是多个产品系列结构;而抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列。
- 抽象工厂模式相对于工厂方法模式来说,就是工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。
- 如果客户端需要创建一些产品结构,而这些产品结构又分别属于不同的产品类别,则可以使用抽象工厂模式,抽象工厂模式中抽象工厂类负责定义创建对象的接口,具体这一系列对象的创建工作由实现抽象工厂的具体工厂类来完成。
2)角色概述:
抽象工厂模式中存在四种角色,分别是抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。
- 抽象工厂:提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
- 具体工厂:主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
- 抽象产品:定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。
3)前文
在这里再次上一篇文章中👉Java设计模式-工厂模式(2)工厂方法模式 中出现的问题再做一次扩展。
原问题是:
需求:设计一个咖啡店点餐系统。
设计一个咖啡类(Coffee),并定义其两个子类(美式咖啡【AmericanCoffee】和拿铁咖啡【LatteCoffee】);再设计一个咖啡店类(CoffeeStore),咖啡店具有点咖啡的功能。
但是现在我们咖啡店进行扩张了。
现咖啡店业务发生改变,不仅要生产咖啡还要生产甜点,如提拉米苏、抹茶慕斯等,要是按照工厂方法模式,需要定义提拉米苏类、抹茶慕斯类、提拉米苏工厂、抹茶慕斯工厂、甜点工厂类,很容易发生类爆炸情况。其中拿铁咖啡、美式咖啡是一个产品等级,都是咖啡;提拉米苏、抹茶慕斯也是一个产品等级;拿铁咖啡和提拉米苏是同一产品族(也就是都属于意大利风味),美式咖啡和抹茶慕斯是同一产品族(也就是都属于美式风味)。
所以这个案例可以使用抽象工厂模式实现。类图如下:
二、代码实现
1)抽象产品及具体产品:
第一种产品:
Coffee(第一种抽象产品类)、AmericanCoffee和LatteCoffee (具体产品类)
public abstract class Coffee {
public abstract void addMilk();
public abstract void addSugar();
public abstract String getName();
}
public class AmericanCoffee extends Coffee {
@Override
public void addMilk() { System.out.println("给咖啡加奶"); }
@Override
public void addSugar() { System.out.println("给咖啡加糖"); }
@Override
public String getName() { return "美式咖啡"; }
}
public class LatteCoffee extends Coffee {
@Override
public void addMilk() { System.out.println("给咖啡加奶"); }
@Override
public void addSugar() { System.out.println("给咖啡加糖"); }
@Override
public String getName() { return "拿铁咖啡"; }
}
第二种产品:
Dessert (第二种抽象产品 甜点) MatchaMousse、Tiramisu(具体产品类)
public abstract class Dessert {
public abstract void show();
}
public class MatchaMousse extends Dessert{
@Override
public void show() { System.out.println("抹茶慕斯"); }
}
public class Tiramisu extends Dessert{
@Override
public void show() { System.out.println("提拉米苏"); }
}
2)抽象工厂 及具体工厂
DessertFactory (抽象工厂) AmericanDessertFactory 和(具体工厂)
public interface DessertFactory {
Coffee createCoffee();
Dessert createDessert();
}
public class AmericanDessertFactory implements DessertFactory {
@Override
public Coffee createCoffee() { return new AmericanCoffee(); }
@Override
public Dessert createDessert() { return new MatchaMousse(); }
}
public class ItalyDessertFactory implements DessertFactory {
@Override
public Coffee createCoffee() { return new LatteCoffee(); }
@Override
public Dessert createDessert() { return new Tiramisu(); }
}
3)测试
public class Client {
public static void main(String[] args) {
// 想次美式东西
// AmericanDessertFactory factory = new AmericanDessertFactory();
// 想换成意大利风味,仅仅只需要换一个工厂类 其他的代码无需改变
ItalyDessertFactory factory= new ItalyDessertFactory();
Coffee coffee = factory.createCoffee();
Dessert dessert = factory.createDessert();
System.out.println(coffee.getName());
dessert.show();
}
}
如果要加同一个产品族的话,只需要再加一个对应的工厂类即可,不需要修改其他的类。
4)优缺点:
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。
- 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
- 当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
- 抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。
使用抽象工厂模式一般要满足以下条件。
- 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
- 系统一次只可能消费其中某一族产品,即同族的产品一起使用。
5)使用场景:
如:输入法换皮肤,一整套一起换。生成不同操作系统的程序。
三、自言自语
我也不知道文章写出来是有用还是无用,只是想做一个分享。希望大家能够喜欢并且在这里能有收获。
你好啊,要天天开心哦。下篇文章再见。
此系列还在持续更新中…. 我一定还会回来的。😁
今天的文章Java设计模式-工厂模式(3)抽象工厂模式分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/17673.html