抽象工厂模式

往期回顾:简单工厂模式/工厂方法模式

在这里插入图片描述


前言

在了解抽象工厂模式前,我们简单回顾一下工厂方法模式。因为抽象工厂模式某些地方可以说是工厂方法模式的升级版。

工厂方法模式
1、“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
2、它定义一个用于创建对象的接口,让子类决定实例化哪一个类。客户需求某些产品的时候,只需要使用对应的工厂就可以拿到对象实例。
3、每个具体工厂类只能创建一个具体产品类的实例

主要理解第三点,因为抽象方法的每个具体工厂类不是只能创建一个具体产品的实例,而是可以创建多个
打个比方!!!
用工厂方法模式去模拟制造汽车工厂,定义一个抽象工厂,里面有一个制造汽车的方法,然后有两个具体工厂,一个是Benz(奔驰)制造厂一个是Bmw(宝马)制造厂

//抽象工厂:提供了产品的生成方法
interface CarFactory{
    public Car createProduct();
}

//具体工厂1:实现了产品的生成方法
class createBenz1 implements CarFactory{
    @Override
    public Car createProduct() {
        return new Benz();
    }
}

//具体工厂2:实现了产品的生成方法
class createBWM1 implements CarFactory{
    @Override
    public Car createProduct() {
        return new Bwm();
    }
}
.....抽象/具体产品省略......

从结构上来看,客户只要在用的时候直接使用抽象工厂的不同实现工厂子类就可以获取想要的产品对象,进而调用产品的方法。若想新增一个产品例如奥迪,只需要增加一个奥迪工厂即可。

但是这个设计模式有局限,工厂方法模式只针对一类产品的生成,每个具体工厂类只能创建一个具体产品类的实例。就好比现实生活中,畜牧场只养动物,这就是一类产品的生产,符合工厂方法模式定义。但如果是放在农场呢,农场既可以养动物也可以种植物对吧?所以这种涉及到多类业务品种的时候,工厂方法模式显然已经不适用了,因为工厂模式针对的是一个产品等级结构,而此时植物产品与动物产品并不在同一个产品等级中,那么我们就要采取抽象工厂模式来解决这类问题。

简单回顾过后,现在来让我们正式来学习下抽象工厂模式,看看它是怎么解决在多个产品结构生成问题。


一、抽象工厂模式定义

抽象工厂模式(Abstract FactoryPattern)
隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象

工厂模式中的每一个形态都是针对一定问题的解决方案,工厂方法针对的是多个产品系列结构;而抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列。

二、适用情况

  • 一个系统要独立于它的产品的创建、组合和表示时。
  • 一个系统要由多个产品系列中的一个来配置时。
  • 需要强调一系列相关的产品对象的设计以便进行联合使用时。
  • 提供一个产品类库,而只想显示它们的接口而不是实现时

----来自百度百科

三、模拟案例

就用农场既可以养动物也可以种植物这个话题,我来模拟一个抽象工厂模式的使用实例。我假设有两个农场A和B,农场A主要负责种小麦和养羊,农场B主要负责种西瓜和养马、

1、首先定义抽象产品和具体产品实现

//抽象产品:动物
interface Animal{
    public void show();
}

//具体产品:羊
class Sheep implements Animal{
    @Override
    public void show() {
        System.out.println("我是一只羊羊羊!");
    }
}

//具体产品:马
class Horse implements Animal{
    @Override
    public void show() {
        System.out.println("我是一只牛牛牛");
    }
}
===================================================
//抽象产品:植物
interface Plant{
    public void show();
}

//具体产品:西瓜
class watermelon implements Plant{
    @Override
    public void show() {
        System.out.println("我是可口的西瓜!");
    }
}

//具体产品:小麦
class wheat implements Plant{
    @Override
    public void show() {
        System.out.println("我是金黄的小麦!");
    }
}

2、定义抽象工厂 – 农场类
其中包括养动物和种植物工厂方法,体现一个抽象工厂类,可以派生出多个具体工厂类

//抽象工厂
interface FarmAbstractFactory{
    public Animal keepAnimal();  //养动物
    public Plant growPlants();   //种植物
}

3、定义具体工厂 – 农场工厂A、农场工厂B
其中包括对多种具体产品的生产,体现每个具体工厂类可以创建多个具体产品类的实例

//具体工厂: 农场A(种小麦和养羊)
class FactoryA implements FarmAbstractFactory {

    //返回 动物->羊对象
    public Animal keepAnimal() {
        return new Sheep();
    }

    //返回 植物->小麦对象
    public Plant growPlants() {
        return new wheat();
    }
}

//具体工厂: 农场B(种西瓜和养马)
class FactoryB implements FarmAbstractFactory {

    //返回 动物->马对象
    public Animal keepAnimal() {
        return new Horse();
    }

    //返回 植物->西瓜
    public Plant growPlants() {
        return new watermelon();
    }
}

4、模拟两个农场对不同产品的生成过程

public class FactoryTest {
    public static void main(String[] args) {
        //1、农场A 种小麦和养羊
        System.out.println("==============农场A=============");
        FarmAbstractFactory factoryA = new FactoryA();  //得到工厂对象
        Plant plant = factoryA.growPlants();//种植业务
        plant.show();
        Animal animal = factoryA.keepAnimal();//牧畜业务
        animal.show();

        //1、农场B 种西瓜和养马
        System.out.println("==============农场B=============");
        FarmAbstractFactory factoryB = new FactoryB();  //得到工厂对象
        Plant plant1 = factoryB.growPlants();//种植业务
        plant1.show();
        Animal animal1 = factoryB.keepAnimal();//牧畜业务
        animal1.show();
    }
}

运行结果:
在这里插入图片描述

四、优缺点

优点
(1)分离了具体的类。客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。
(2)易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂即可使用不同的产品配置。
(3)有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。


缺点
(1)难以支持新种类的产品。因为抽象工厂接口确定了可以被创建的产品集合,所以难以扩展抽象工厂以生产新种类的产品。

五、补充说明

抽象工厂模式也是符合“开闭原则的”

  • 简单工厂模式是不符合开闭原则,因为增加产品会对原本的工厂进行修改。
  • 工厂方法模式是符合开闭原则,因为增加产品只需要再新增相应的工厂类就行,不需要修改原来的代码。
  • 抽象工厂模式既符合也不符合开闭原则。符合开闭原则时,因为增加一个新的产品族时(例如某农场负责的养鸡和种葡萄业务),只需要增加一个新的具体工厂,不需要修改源代码,满足开闭原则。但是当产品族中需要增加一个新的产品时(例如农场又提供衣服产品,如棉衣等具体产品),那么所有的工厂类都需要进行修改,此时不满足开闭原则。

另一方面,当系统中只存在一个等级结构的产品时,抽象工厂模式将退化到工厂方法模式。




参考链接: http://c.biancheng.net/view/1351.html
  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

冰棍hfv

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

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

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

打赏作者

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

抵扣说明:

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

余额充值