戏说设计模式 - 小米VS华为 - 工厂模式_抽象工厂模式

释放双眼,带上耳机,听听看~!

抽象工厂模式

简介

定义了一个接口用于创建相关或有依赖关系的对象族,而无明确指定具体的类

戏说设计模式 - 小米VS华为 - 工厂模式_抽象工厂模式

组成角色

  • 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
  • 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
  • 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
  • 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

优缺点

  • 优点

    • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
  • 缺点
    • 产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

适用场景

  • 系统的产品有多于一个的产品族,而系统只消费其中某一族的产品

注意事项

  • 产品族难扩展,产品等级易扩展。

案例

小米 VS 华为

大牛:“小鸟,在看啥呢?看的这么入神”

小鸟:“我想买个手机,不知道是买小米的呢,还是买华为的”

小鸟:“小米5的配置,价格:2080”
戏说设计模式 - 小米VS华为 - 工厂模式_抽象工厂模式

小鸟:“华为P9,价格:3380”
戏说设计模式 - 小米VS华为 - 工厂模式_抽象工厂模式

小鸟:“华为P9的各项参数可以说是完胜小米5,但是这价格贵了1000多大洋呢,好纠结啊!”

大牛:“先别纠结这个问题了,我来出个题目考考你,看你最近学的怎么样”

小鸟:“好啊!好啊!”

大牛:“你牛哥我啊!在软件界混了这么多年,现在也算是小有积蓄了,想自己创业,开个手机生产厂,主要生产小米,现在你能帮我制作一个手机生产的软件吗?”

小鸟:“手机主要的组成部分有:屏幕、摄像头、电池、…这里就不一一列举了”

小鸟:“各配件的生产厂家图解如下,这里以屏幕和摄像头为例,各配件的厂家简单举一两个例子”

戏说设计模式 - 小米VS华为 - 工厂模式_抽象工厂模式

工厂方法模式实现

小鸟:“因此我们的代码设计如下:”
屏幕 –> AScreen

定义所有屏幕生产厂家的规范

public abstract class AScreen {
    public abstract void screen();
}

屏幕厂家1:三星屏幕 –> SamsungScreen

它是生产屏幕的,所有它要符合屏幕生产规范,故继承屏幕类

public class SamsungScreen extends AScreen {
    @Override
    public void screen() {
        System.out.println("屏幕厂家:三星");
    }
}

屏幕厂家2:索尼屏幕 –> SonyScreen

它是生产屏幕的,所有它要符合屏幕生产规范,故继承屏幕类

public class SonyScreen extends AScreen {
    @Override
    public void screen() {
        System.out.println("屏幕厂家:索尼");
    }
}

小鸟:“同理,我们可以得到对应的摄像头的具体代码”
摄像头 –> ACamera

public abstract class ACamera {
    public abstract void camera();
}

摄像头1:舜宇 –> ShunYuCamera

public class ShunYuCamera extends ACamera {
    @Override
    public void camera() {
        System.out.println("摄像头厂家:舜宇");
    }
}

摄像头2:玉晶 –> YuJingCamera

public class YuJingCamera extends ACamera {
    @Override
    public void camera() {
        System.out.println("摄像头厂家:玉晶");
    }
}

小鸟:“用配件来组成我们的手机”
手机:Mobile

public class Mobile {

    private AScreen screen; //屏幕
    private ACamera camera; //摄像头

    public Mobile(AScreen screen, ACamera camera) {
        this.screen = screen;
        this.camera = camera;
    }

    public void showMobile() {
        screen.screen();
        camera.camera();
    }

    public AScreen getScreen() {
        return screen;
    }

    public void setScreen(AScreen screen) {
        this.screen = screen;
    }

    public ACamera getCamera() {
        return camera;
    }

    public void setCamera(ACamera camera) {
        this.camera = camera;
    }
}

客户端调用:

客户要求,屏幕:三星 摄像头:国产(舜宇)

AScreen screen = new SamsungScreen();
ACamera camera = new ShunYuCamera();

Mobile mobile = new Mobile(screen, camera);
mobile.showMobile();

大牛:“嗯嗯,小鸟进步很大啊,都会自己分析,并进行抽象,不错不错。”

大牛:“咱们这里生产线交给客户端处理,虽然灵活,但效率并不高,我们是工厂,应该发挥流程化优势。”

抽象工厂模式实现

小鸟:“流程化,流程化,流程化不就是说类似于固定生产线吗!这个容易”,说完,小鸟就写出了代码
手机工厂:MobileFactory

将以前的手机类删除,新增手机工厂

public abstract class MobileFactory {
    public abstract AScreen createAScreen();
    public abstract ACamera createACamera();
}

手机工厂1:SamsungShunYuMoblieFactory

生产具体的手机

  • 屏幕:三星
  • 摄像头:舜宇
public class SamsungShunYuMoblieFactory extends MobileFactory {

    @Override
    public AScreen createAScreen() {
        return new SamsungScreen();
    }

    @Override
    public ACamera createACamera() {
        return new ShunYuCamera();
    }
}

手机工厂2:SamsungYuJingMobileFactory

生产具体的手机

  • 屏幕:三星
  • 摄像头:玉晶
public class SamsungYuJingMobileFactory extends MobileFactory {
    @Override
    public AScreen createAScreen() {
        return new SamsungScreen();
    }

    @Override
    public ACamera createACamera() {
        return new YuJingCamera();
    }
}

客户端调用

MobileFactory factory = new SamsungShunYuMoblieFactory();
factory.createACamera().camera();
factory.createAScreen().screen();

大牛:“不错啊!小鸟,悟性挺高啊!你通过自己的推导,演化出了抽象工厂模式,不错不错.”

小鸟:“这样写我感觉好复杂啊!比方说我要加一个新屏幕厂商和摄像头厂商,重新组成新的生产线,我要分别一个类去继承ACamera、AScreen、MobileFactory,感觉要加的地方好多啊!累死宝宝了”

大牛:“编程得脚踏实地,不能闲累哦!”

工厂模式优化方案

优化学习: Android - raw - properties

小鸟:“牛哥,你教我设计模式,不就是想让我提高代码的复用性吗!牛哥,你今天主动给我出题,肯定不会这么简单。”

大牛:“可以啊!小鸟,不错。今天除了给你讲抽象工厂,确实还想给你引进一个新的概念,对咱们的工厂模式进行优化”

小鸟:“优化,我喜欢。”

大牛:“不知道,你发现没有,简单工厂 –> 工厂类中用了好多case,每增加一个具体的产品,都需要修改工厂类(增加case),违背了开闭原则,之后,我们提出了工厂方法模式 –> 解决了开闭原则的问题,但是我们每增加一个具体的产品,我们就得为其增加一个对应的工厂,这样的做法,直接导致了我们程序中类的个数的直线上升。”

小鸟:“是呢!如果有一种方法,能不违背类的开闭原则,又能不让宝宝写这么多类就好了!”

大牛:“这就是我今天最后要告诉你的,反射 + 配置文件,反射用来解决类个数的问题,配置文件用来对反射进行优化,这里先为你引进这两个概念,具体的你先自己学习一下。等你把这俩学会了,你也就可以解决你抽象工厂遇到的问题了。”

【转自慕课】https://www.imooc.com

JAVA

详细解析Java中抽象类和接口的区别

2022-3-3 19:00:13

JAVA

Java的数据类型--基本数据类型和引用类型的区别

2022-3-3 19:00:42

搜索