✍ 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候 我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象, 这里就要引入抽象工厂的设计模式了。
为了更清晰地理解抽象工厂设计模式,需要先引入两个概念:
如果上面的文字看不太懂,也没关系,产品等级结构与产品族图示
相同颜色的代表同一产品等级
相同形状 不同颜色的是一个产品族
比如说华为生产基站,还生产手机,还生产芯片,华为生产的产品都是属于华为的品牌,属于同一产品等级
竖着来看 手机是方框形的 这个竖着的还有小米等手机品牌 这是同一产品组
对这些概念有了解之后,会发现抽象工厂的动机很简单:
✍ 这里引出抽象工厂的定义:
抽象工厂模式(Abstract Factory Pattern) : 提供一个 创建一系列相关或相互依赖对象的接口 ,而 无须指定它们具体的类 。抽象工厂模式又称为Kit 模式 ,属于 对象创建型模式
抽象工厂模式包含如下角色:
✍ 演示一下:
CakeFactory接口 (AbstractFactory:抽象工厂)
package softwareDesign.coding.factoryMethod.abstractFactory;
public interface CakeFactory {
Cake getCake();
GiftBox getGiftBox();
}
Cake抽象类(AbstractProduct:抽象产品)
package softwareDesign.coding.factoryMethod.abstractFactory;
public abstract class Cake {
public abstract void produce();
}
GiftBox 抽象类(AbstractProduct:抽象产品)
package softwareDesign.coding.factoryMethod.abstractFactory;
public abstract class GiftBox {
public abstract void produce();
}
SnowCake类(Product:具体产品)
package softwareDesign.coding.factoryMethod.abstractFactory;
public class SnowCake extends Cake{
@Override
public void produce() {
System.out.println("生产雪花蛋糕...");
}
}
SnowCakeGiftBox 类(Product:具体产品)
package softwareDesign.coding.factoryMethod.abstractFactory;
public class SnowCakeGiftBox extends GiftBox{
@Override
public void produce() {
System.out.println("生产雪花蛋糕礼盒...");
}
}
SnowCakeFactory 类(ConcreteFactory:具体工厂)
package softwareDesign.coding.factoryMethod.abstractFactory;
public class SnowCakeFactory implements CakeFactory{
@Override
public Cake getCake() {
return new SnowCake();
}
@Override
public GiftBox getGiftBox() {
return new SnowCakeGiftBox();
}
}
CCake类()(Product:具体产品)
package softwareDesign.coding.factoryMethod.abstractFactory;
public class CCake extends Cake{
@Override
public void produce() {
System.out.println("生产巧克力蛋糕...");
}
}
CCakeGiftBox类(Product:具体产品)
package softwareDesign.coding.factoryMethod.abstractFactory;
public class CCakeGiftBox extends GiftBox{
@Override
public void produce() {
System.out.println("生产巧克力蛋糕礼盒");
}
}
CCakeFactory 类(ConcreteFactory:具体工厂)
package softwareDesign.coding.factoryMethod.abstractFactory;
public class CCakeFactory implements CakeFactory {
@Override
public Cake getCake() {
return new CCake();
}
@Override
public GiftBox getGiftBox() {
return new CCakeGiftBox();
}
}
Test类
package softwareDesign.coding.factoryMethod.abstractFactory;
public class Test {
public static void main(String[] args) {
CakeFactory cakeFactory = new SnowCakeFactory();
Cake cake = cakeFactory.getCake();
GiftBox giftBox = cakeFactory.getGiftBox();
cake.produce();
giftBox.produce();
}
}
如果增加水果蛋糕和水果蛋糕礼盒 很容易能够拓展
加入test测试:
Test只关心从哪个工厂拿什么产品。应用层和具体的雪花蛋糕类及其礼盒等都是解耦的。
缺点也很明显,如果要拓展产品等级,那就违背了开闭原则,牵一发而动全身。
✍ 既然说到了缺点,就好好探究一下优缺点吧
抽象工厂模式的优点
隔离了具体类的生成
,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易。所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为
。另外,应用抽象工厂模式可以实现高内聚低耦合的设计目的
,因此抽象工厂模式得到了广泛的应用。能够保证客户端始终只使用同一个产品族中的对象
。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
抽象工厂模式的缺点
✍ 在以下情况下可以使用抽象工厂模式:
✍ 说一下它的应用吧:
在Java语言的AWT(抽象窗口工具包)中就使用了抽象工厂模式,它使用抽象工厂模式来实现在不同的操作系统中应用程序呈现与所在操作系统一致的外观界面。还有在很多软件系统中需要更换界面主题,要求界面中的按钮、文本框、背景色等一起发生改变时,可以使用抽象工厂模式进行设计。
✍ 关于抽象工厂的拓展:
“开闭原则”的倾斜性
工厂模式的退化