设计模式——抽象工厂模式

抽象工厂模式


抽象工厂模式是什么

  • 抽象工厂模式属于创建型模式,是对工厂的一种抽象,可以理解为生产工厂的总工厂,不但工厂是抽象的,并且产品也是抽象的,而且会有多个产品需要创建,因此这个抽象工厂会对应多个实际工厂,每个实际工厂负责创建多个实际产品。
  • 他有两个维度 产品簇产品等级
  • 产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,就好比是一个品牌下的所有产品,如华为下面的手机、电脑、路由器都被称为是华为的产品族。
  • 产品等级:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有各种品牌的电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品登记结构,抽象电视机是父类,而具体品牌的电视机是其子类。

抽象工厂方法模式

  • 这种模式是在原先的层级上多加了一层 实现的效果就是,不由原先的工厂类来实例对象工厂父类来定义创建产品的公共接口, 而各工厂子类对象通过集成来实现这个创建接口, 在这个实现里面去完成究竟应该实例化哪一个具体产品,这样就可以在不影响原先种类的情况下引入新的产品。
  • 示意图如下
    在这里插入图片描述
  • 如图所示 一个具体工厂要实现一整个产品族的创建
  • 每一个具体工厂可以生产属于一个产品族的所有产品,例如生产颜色相同的正方形、圆形和椭圆形,所生产的产品又位于不同的产品等级结构中。如果使用工厂方法模式,图所示结构需要提供15个具体工厂,而使用抽象工厂模式只需要提供5个具体工厂,极大减少了系统中类的个数。

抽象工厂结构图

在这里插入图片描述

  • 其中Factory扮演工厂的抽象角色,在它中规定了两个抽象方法,这两个方法分别是创建产品A和产品B的抽象方法。然后图中的Factory1与Factory2就是实现Factory的具体工厂类,他们在各自的实现方法内来创建自己对应族的实体类。

代码实例

  • 在这个代码实例中,我们将模拟各地风味小吃店订单,有兰州的小吃店中有适合国人的牛肉面和牛肉披
  1. 我们先定义pizza的接口与面的接口
interface IPizzaProduct {
    //准备材料`
    void material();

    void bake();

    void cut();

    void box();
}

interface INoodles {
    //准备材料`
    void material();

    void cook();

    void box();
}

  1. 定义他们的四个实现类
class CheesePizza implements IPizzaProduct {

    String pizzaName = "芝士";

    CheesePizza() {
        this.pizzaName = this.pizzaName + "披萨";
    }

    //准备材料
    public void material() {
        System.out.println("正在准备芝士披萨的材料");
    }

    public void bake() {
        System.out.println("正在烤 " + this.pizzaName);
    }

    public void cut() {
        System.out.println("正在切 " + this.pizzaName);
    }

    public void box() {
        System.out.println("正在打包 " + this.pizzaName);
    }
}

class BeefPizza implements IPizzaProduct {

    String pizzaName = "牛肉";

    BeefPizza() {
        this.pizzaName = this.pizzaName + "披萨";
    }

    //准备材料
    public void material() {
        System.out.println("正在准备牛肉披萨的材料");
    }

    public void bake() {
        System.out.println("正在烤 " + this.pizzaName);
    }

    public void cut() {
        System.out.println("正在切 " + this.pizzaName);
    }

    public void box() {
        System.out.println("正在打包 " + this.pizzaName);
    }
}

class BeefNoodles implements INoodles {
    private String noodleName = "牛肉面";

    @Override
    public void material() {
        System.out.println("正在准备" + noodleName + "所需材料");
    }

    @Override
    public void cook() {
        System.out.println("正在煮" + noodleName);

    }

    @Override
    public void box() {
        System.out.println("正在打包" + noodleName);

    }
}

class VegetableNoodles implements INoodles {
    private String noodleName = "青菜面";

    @Override
    public void material() {
        System.out.println("正在准备" + noodleName + "所需材料");
    }

    @Override
    public void cook() {
        System.out.println("正在煮" + noodleName);

    }

    @Override
    public void box() {
        System.out.println("正在打包" + noodleName);

    }
}
  1. 定义抽象工厂类
interface IProductFactory {
    //制作pizza
    IPizzaProduct pizzaProduct();

    //制作noodles
    INoodles noddlesProduct();
}
  1. 伦敦小吃店和兰州小吃店实现类,继承工厂接口
//定义具体工厂来继承工厂接口
class LanzhouFactory implements IProductFactory{

    @Override
    public IPizzaProduct pizzaProduct() {
        return new BeefPizza();
    }

    @Override
    public INoodles noddlesProduct() {
        return new BeefNoodles();
    }
}

class LDFactory implements IProductFactory{

    @Override
    public IPizzaProduct pizzaProduct() {
        return new CheesePizza();
    }

    @Override
    public INoodles noddlesProduct() {
        return new VegetableNoodles();
    }
}
  1. 在主函数中尝试调用工厂创建具体的产品
  public static void main(String[] args) {
        LDFactory ldFactory = new LDFactory();
        INoodles iNoodles = ldFactory.noddlesProduct();
        iNoodles.material();
        iNoodles.cook();
        iNoodles.box();

        IPizzaProduct pizza = ldFactory.pizzaProduct();
        pizza.material();
        pizza.bake();
        pizza.cut();
        pizza.bake();
        LanzhouFactory lanzhouFactory = new LanzhouFactory();
        IPizzaProduct iPizzaProduct = lanzhouFactory.pizzaProduct();
        iPizzaProduct.material();
        iPizzaProduct.bake();
        iPizzaProduct.cut();
        iPizzaProduct.box();

        IProductFactory factory = new LanzhouFactory();
        INoodles noodles = factory.noddlesProduct();
        noodles.material();
        noodles.cook();
        noodles.box();
    }

运行截图

在这里插入图片描述

抽象工厂的优点

  1. 不关心创建细节: 用户只需要关心产品所对应的工厂,不需要关心它内部是如何创建
  2. 符合开闭原则: 加入新的产品,只需要增加新的工厂类就可以,符合开闭原则,提高了可扩展性
  3. 可以对产品族进行约束 因为有一个抽象的工厂类,其中可以对需要的产品族进行一个总体的约束
  4. 减少了具体工厂类的个数 因为现在只需要创建一个工厂,它可以利用方法创建一整个产品族

抽象工厂的不足

  1. 扩展产品族很困难: 因为现在是产品族约束是在抽象工厂接口里去定义的,所以如果需要增加一种新的产品种类,则之前所有实现这个工厂的具体工厂类都需要增加实现,所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
  2. 增加难度: 增加了系统的抽象性和理解难度(抽象工厂不仅抽象了产品类,同时还抽象了工厂类,增加了系统的抽象性和理解难度)。

设计模式的使用 , 要根据实际的业务场景 , 模型综合平衡考量 , 不能过分遵守设计原则 和 设计模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LvhaoIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值