简介
定义了一个接口用于创建相关或有依赖关系的对象族,而无明确指定具体的类
组成角色
- 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
- 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
- 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
- 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
优缺点
-
优点
- 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
- 缺点
- 产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
适用场景
- 系统的产品有多于一个的产品族,而系统只消费其中某一族的产品
注意事项
- 产品族难扩展,产品等级易扩展。
案例
小米 VS 华为
大牛:“小鸟,在看啥呢?看的这么入神”
小鸟:“我想买个手机,不知道是买小米的呢,还是买华为的”
小鸟:“小米5的配置,价格:2080”
小鸟:“华为P9,价格:3380”
小鸟:“华为P9的各项参数可以说是完胜小米5,但是这价格贵了1000多大洋呢,好纠结啊!”
大牛:“先别纠结这个问题了,我来出个题目考考你,看你最近学的怎么样”
小鸟:“好啊!好啊!”
大牛:“你牛哥我啊!在软件界混了这么多年,现在也算是小有积蓄了,想自己创业,开个手机生产厂,主要生产小米,现在你能帮我制作一个手机生产的软件吗?”
小鸟:“手机主要的组成部分有:屏幕、摄像头、电池、...这里就不一一列举了”
小鸟:“各配件的生产厂家图解如下,这里以屏幕和摄像头为例,各配件的厂家简单举一两个例子”
工厂方法模式实现
小鸟:“因此我们的代码设计如下:”
屏幕 --> 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),违背了开闭原则,之后,我们提出了工厂方法模式 --> 解决了开闭原则的问题,但是我们每增加一个具体的产品,我们就得为其增加一个对应的工厂,这样的做法,直接导致了我们程序中类的个数的直线上升。”
小鸟:“是呢!如果有一种方法,能不违背类的开闭原则,又能不让宝宝写这么多类就好了!”
大牛:“这就是我今天最后要告诉你的,反射 + 配置文件,反射
用来解决类个数的问题,配置文件
用来对反射进行优化,这里先为你引进这两个概念,具体的你先自己学习一下。等你把这俩学会了,你也就可以解决你抽象工厂遇到的问题了。”
共同学习,写下你的评论
评论加载中...
作者其他优质文章