在Java设计模式-工厂模式(2)工厂方法模式 我们知道了工厂方法模式解决了简单工厂模式中的缺陷,做到了满足开闭原则,但是时代是进步的,进而又产生新的问题,工厂难道只能生产一种东西吗。我们所见到的工厂大都都是综合性的。所以就有了抽象工厂模式。
放张图舒缓一下心情。
- [一、前言](https://cloud.tencent.com/developer)
- [1)概述:](https://cloud.tencent.com/developer)
- [2)角色概述:](https://cloud.tencent.com/developer)
- [3)前文](https://cloud.tencent.com/developer)
- [二、代码实现](https://cloud.tencent.com/developer)
- [1)抽象产品及具体产品:](https://cloud.tencent.com/developer)
- [2)抽象工厂 及具体工厂](https://cloud.tencent.com/developer)
- [3)测试](https://cloud.tencent.com/developer)
- [4)优缺点:](https://cloud.tencent.com/developer)
- [5)使用场景:](https://cloud.tencent.com/developer)
- [三、自言自语](https://cloud.tencent.com/developer)
抽象工厂模式中存在四种角色,分别是抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。
在这里再次上一篇文章中👉Java设计模式-工厂模式(2)工厂方法模式 中出现的问题再做一次扩展。
原问题是:
需求:设计一个咖啡店点餐系统。
设计一个咖啡类(Coffee),并定义其两个子类(美式咖啡【AmericanCoffee】和拿铁咖啡【LatteCoffee】);再设计一个咖啡店类(CoffeeStore),咖啡店具有点咖啡的功能。
但是现在我们咖啡店进行扩张了。
现咖啡店业务发生改变,不仅要生产咖啡还要生产甜点,如提拉米苏、抹茶慕斯等,要是按照工厂方法模式,需要定义提拉米苏类、抹茶慕斯类、提拉米苏工厂、抹茶慕斯工厂、甜点工厂类,很容易发生类爆炸情况。其中拿铁咖啡、美式咖啡是一个产品等级,都是咖啡;提拉米苏、抹茶慕斯也是一个产品等级;拿铁咖啡和提拉米苏是同一产品族(也就是都属于意大利风味),美式咖啡和抹茶慕斯是同一产品族(也就是都属于美式风味)。
所以这个案例可以使用抽象工厂模式实现。类图如下:
第一种产品:
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("提拉米苏"); }
}
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(); }
}
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();
}
}
如果要加同一个产品族的话,只需要再加一个对应的工厂类即可,不需要修改其他的类。
抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。
其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。
使用抽象工厂模式一般要满足以下条件。
如:输入法换皮肤,一整套一起换。生成不同操作系统的程序。
我也不知道文章写出来是有用还是无用,只是想做一个分享。希望大家能够喜欢并且在这里能有收获。
你好啊,要天天开心哦。下篇文章再见。
此系列还在持续更新中… 我一定还会回来的。😁