设计思想学习—抽象工厂模式

来源:互联网 发布:化纤衣服危害 知乎 编辑:程序博客网 时间:2024/06/05 11:50

抽象工厂模式

抽象工厂模式(Abstract Factory):为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

抽象工厂模式组成

  • 抽象工厂(Creator)角色:这是工厂方法模式的核心,定义了创建产品的方法。与应用系统无关。具体工厂角色必须实现这个接口才能创建对象。

  • 具体工厂(Concrete Creator)角色:实现了抽象工厂角色的接口,含有与应用密切相关的逻辑,并且接受应用程序的调用以创建产品对象。

  • 抽象产品(Product)角色:定义了产品的共性,实现对产品最抽象的定义。

  • 具体产品(Concrete Product)角色:实现抽象产品角色的接口。工厂方法所创建的对象就是该角色的实例。

UML图
这里写图片描述

个人理解
首先我要说的是对于定义我并不能很好的理解

网络上面资料都是说抽象工厂和工厂方法不同的是:

  • 工厂方法针对一个产品类,抽象工厂针对多个产品类
  • 工厂方法针对一个产品等级,抽象工厂针对多个产品等级
  • 工厂方法每个具体工厂类只能创建一个具体产品类的实例,抽象工厂每个具体工厂类可以创建多个具体产品类的实例

然而这里引入了产品等级的概念,而在抽象工厂中还有一个产品族的概念
在这里我把产品等级理解成可以抽象成一类产品的不同产品
产品族理解成相互关联的不同产品类的产品,就好像小米手机和小米电视,他们的关系就是同属于小米的产品但是又分属于手机类和电视类,图片里面有一点点错误,我应该把工厂给去掉的。
话不多说用代码来实现

举个例子

interface MyFactory{    Car produceCar();    Plane producePlane();}interface Car{    void carSay();}class ACar implements Car{    @Override    public void carSay() {        System.out.println("我是奥迪");    }}class BCar implements Car{    @Override    public void carSay() {        System.out.println("我是红旗");    }}interface Plane{    void planeSay();}class APlane implements Plane{    @Override    public void planeSay() {        System.out.println("我是波音747");      }}class BPlane implements Plane{    @Override    public void planeSay() {        System.out.println("我是C919");       }}class ChinaFactory implements MyFactory{    @Override    public Car produceCar() {        return new ACar();    }    @Override    public Plane producePlane() {        return new APlane();    }   }class foreignFactory implements MyFactory{    @Override    public Car produceCar() {        return new BCar();    }    @Override    public Plane producePlane() {        return new BPlane();    }}public class Client {    public static void main(String[] args) {        MyFactory one=new ChinaFactory();        Car car =one.produceCar();        Plane plane=one.producePlane();        car.carSay();        plane.planeSay();        one=new foreignFactory();        car =one.produceCar();        plane=one.producePlane();        car.carSay();        plane.planeSay();    }}

这里输出的是:
我是奥迪
我是波音747
我是红旗
我是C919

在这里运用抽象工厂方法增加一类存在产品族的产品非常容易只要增加一类产品,然后更改抽象工厂、具体工厂的方法。

虽然增加简单了,但是难点确是在那一类产品必须是存在于产品族中的。
还有一点是修改抽象工厂和具体工厂方法违背了开闭原则。

然而我看设计思想一书中给出的解决办法是:把抽象工厂类和具体工厂全部替换成一个简单工厂,然后通过配置文件加反射的办法来替换掉switch语句。

我知道设计思想不是看了就能会就能十分通透,还需要不少代码量积累和学习,所以我的目标仅仅是先理解一点,然后去带着理解去看一些别人的代码或者一些框架和底层源码,所以这里我就不去深究怎么用反射来解决这个问题了,有兴趣的小伙伴可以自己去研究。

套用一个别人的总结 (^__^) 嘻嘻

无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。

在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。
所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。

原创粉丝点击