设计模式-抽象工厂模式

相关阅读:

设计模式简介

设计模式-简单工厂模式

设计模式-工厂方法模式


继上一篇文章设计模式-工厂方法模式

我们发现在工厂方法模式中,每个工厂只能创建一类产品,为了解决这个问题,今天来学习一下抽象工厂模式

抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例。

抽象工厂模式与工厂方法模式最大的区别:抽象工厂中每个工厂可以创建多种类的产品;而工厂方法每个工厂只能创建一类

模式中包含的角色及职责:

抽象产品族(AbstractProduct)角色:抽象产品的父类,用于描述抽象产品的公共接口

抽象产品(Product)角色:具体产品的父类 ,用于描述产品的公共接口

具体产品(Concrete Product)角色:抽象产品的子类,工厂类创建的目标类,即产品

抽象工厂(Creator)角色:具体工厂的父类,用于描述及具体工厂的公共接口

具体工厂(Concrete Creator)角色:抽象工厂的子类,被外界调用,用于实例化具体产品对象

使用方法:

1.创建抽象产品族类

2.创建抽象产品类,继承自抽象产品族类,定义具体产品的公共接口

3.创建具体产品类,继承自抽象产品类,定义生产的具体产品

4.创建抽象工厂类

5.创建具体工厂类,继承自抽象工厂类,定义创建对应具体产品的方法

6.外界调用具体工厂类,创建产品实例

实例:

实例代码已上传到GitLab,地址:https://gitlab.com/louisvv/DesignPattern

背景:客户来到了一个手机卖场,想要买手机,发现卖场里有苹果、三星手机专卖店,苹果手机有iphone X,iphone 8,三星手机有note 8,s9

目的:通过抽象工厂方法模式,实现手机的购买

流程:

整个流程如下:

客户要买手机 -> 客户问手机卖场(抽象工厂)有什么牌子的手机 -> 手机卖场说,有苹果和三星的专卖店(具体工厂类) -> 客户说我要买苹果手机 -> 创建苹果手机工厂 -> 到了苹果专卖店,店员问客户要哪个型号的手机,店里有iphone X和iphone 8 -> 客户说要iphone X -> 苹果手机工厂创建具体产品 Iphone X -> 客户买到了手机,心满意足的回家了

1.创建抽象产品族类:

创建手机类:

public interface Phone {
   public void show();
}

2.创建抽象产品类:

苹果手机类:

public abstract class ApplePhone implements Phone {
}

三星手机类:

public abstract class SamsungPhone implements Phone{
}

3.创建具体产品类

苹果具体产品类:

Iphone X:

public class IphoneX extends ApplePhone {
    public void show() {
        System.out.println("Iphone X");
    }
}

Iphone 8:

public class Iphone8 extends ApplePhone {
    public  void show() {
        System.out.println("Iphone 8");
    }
}

三星具体产品类:

Note8:

public class GalaxyNote8 extends SamsungPhone {
    public  void show() {
        System.out.println("Galaxy Note 8");
    }
}

S9:

public class GalaxyS9 extends SamsungPhone {
    public void show() {
        System.out.println("Galaxy S9");
    }
}

4.创建抽象工厂类:

public interface AbstractFactory {
    public Phone getPhone(String phoneType) throws ClassNotFoundException, IllegalAccessException, InstantiationException;
}

5.创建具体工厂类:

苹果手机工厂类:

public class AppleFactory implements AbstractFactory {
    public Phone getPhone(String phoneType) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class iphone=Class.forName(phoneType);
        return (ApplePhone) iphone.newInstance();
    }
}

三星手机工厂类:

public class SamsungFactory implements AbstractFactory {
    public Phone getPhone(String phoneType) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //Class phone=Class.forName(phoneType);
        return (SamsungPhone)Class.forName(phoneType).newInstance();
    }
}

6.这里我们还需要一个工厂创建者,用来根据客户选择,创建对应的工厂

public class FactoryProducer {
    public static AbstractFactory getFactory(String factoryName) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class factory=Class.forName(factoryName);
        return (AppleFactory)factory.newInstance();
    }
}

7.外界调用具体工厂类:

public class Buyer {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        //  先问客户要什么牌子的手机,客户说要苹果的
        //  创建苹果手机工厂
        PhoneFactory appleFcatory = FactoryProducer.getFactory("AbstractFactory.AppleFactory");
        System.out.println("客户想要买iphone X手机");
        Phone iphoneX = appleFcatory.getPhone("AbstractFactory.IphoneX");
        iphoneX.show();

        System.out.println("客户想要买iphone 8手机");
        Phone iphone8=appleFcatory.getPhone("AbstractFactory.Iphone8");
        iphone8.show();

        //  客户说要三星牌子的手机
        //  创建三星手机工厂
        PhoneFactory samsungFcatory = FactoryProducer.getFactory("AbstractFactory.SamsungFactory");
        System.out.println("客户想要买s9手机");
        Phone s9=samsungFcatory.getPhone("AbstractFactory.GalaxyS9");
        s9.show();

        System.out.println("客户想要买note 8手机");
        Phone note8=samsungFcatory.getPhone("AbstractFactory.GalaxyNote8");
        note8.show();
    }
}

结果:

客户想要买苹果iphone X手机
Iphone X
客户想要买苹果iphone 8手机
Iphone 8
客户想要买三星s9手机
Galaxy S9
客户想要买三星note 8手机
Galaxy Note 8


至此,实例演示完毕,我们总结一下抽象工厂模式的优缺点

优点:

1.更符合“开放-关闭”原则

新增一种产品族时,只需要增加相应的具体产品类和相应的工厂子类即可

2.符合单一职责原则

每个具体工厂类只负责创建对应的产品

3.降低耦合

抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展;

4.保证客户端始终只使用同一个产品族中的对象

5.相对于简单工厂,工厂方法模式,抽象工厂模式更加的抽象

缺点:

产品族扩展非常困难,这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

对于新的产品族符合开-闭原则

对于新的产品种类不符合“开-闭”原则,这一特性称为“开-闭”原则的倾斜性

应用场景:

了解其优缺点后,总结一下抽象工厂模式的应用场景:

  • 一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提
  • 这个系统有多个系列产品,而系统中只消费其中某一系列产品
  • 系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现

举个例子:

比如游戏的装备和皮肤系统,就可以用抽象工厂方法模式,每次只能有一套皮肤和一件装备在指定位置上

亲,点个赞呗

赫墨拉

我是一个喜爱大数据的小菜鸡,这里是我分享我的成长和经历的博客

You may also like...

发表评论

邮箱地址不会被公开。