设计模式(十三)抽象工厂模式

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/itachi85/article/details/54755390

相关文章
设计模式(一)设计六大原则
设计模式(二)单例模式的七种写法
设计模式(三)建造者模式
设计模式(四)简单工厂模式
设计模式(五)观察者模式
设计模式(六)代理模式
设计模式(七)装饰模式
设计模式(八)外观模式
设计模式(九)模版方法模式
设计模式(十)工厂方法模式
设计模式(十一)策略模式
设计模式(十二)享元模式

前言

此前讲解过简单工厂模式和工厂模式,这一篇我们来学习工厂系列的最后一个模式抽象工厂模式,建议在阅读此文前,请先阅读设计模式(四)简单工厂模式设计模式(十)工厂方法模式这两篇文章。

抽象工厂模式定义

抽象工厂模式可以说是是工厂方法模式的升级版,当需要创建的产品有多个产品线(产品族)时使用抽象工厂模式是比较好的选择。那什么是多个产品线呢?拿我们在设计模式(四)简单工厂模式设计模式(十)工厂方法模式中学习的生产电脑的例子来举例,我们一直都是生产联想和惠普的电脑,但是电脑也有多个产品线:台式机、笔记本和平板等等,联想和惠普都在生产这些不同产品线上的电脑,使用工厂方法模式已经满足不了需求,这一篇文章我们就用抽象工厂模式来解决这一问题。

抽象工厂模式定义
为创建一组相关或者相互依赖的对象提供一个接口,而无需指定它们的具体类。

抽象工厂模式UML图
这里写图片描述

在抽象工厂模式中有如下角色:
- AbstractFactory:抽象工厂,它声明了用来创建不同产品的方法。
- ConcreteFactory:具体工厂,实现抽象工厂中定义的创建产品的方法。
- AbstractProduct:抽象产品,为每种产品声明业务方法。比如上图的AbstractProductA和 AbstractProductB。
- ConcreteProduct:具体产品,定义具体工厂生产的具体产品,并实现抽象产品中定义的业务方法。

抽象工厂模式简单实现

联想和惠普生产的电脑分为了两个产品线,一个台式机,一个是笔记本。为了解决增加产品线的问题,我们用抽象工厂模式来进行实现。

抽象产品
首先定义抽象产品类:

public abstract class DesktopComputer {
  public abstract void start();
}
public abstract class NotebookComputer {
   public abstract void start();
}

两个抽象产品类分别为DesktopComputer和NotebookComputer ,用来定义两个产品线:台式机和笔记本。它们都定义了start方法,用来启动电脑。
具体产品
具体产品为联想和惠普旗下的台式机和笔记本,如下所示。

public class LenovoDesktopComputer extends DesktopComputer {
    @Override
    public void start() {
        System.out.println("联想台式电脑启动");
    }
}

public class HpDesktopComputer extends DesktopComputer {
    @Override
    public void start() {
        System.out.println("惠普台式电脑启动");
    }
}

public class LenovoNotebookComputer extends NotebookComputer {
    @Override
    public void start() {
        System.out.println("联想笔记本电脑启动");
    }
}
public class HpNotebookComputer extends NotebookComputer {
    @Override
    public void start() {
        System.out.println("惠普笔记本电脑启动");
    }
}

抽象工厂
接着创建生产电脑的抽象工厂,如下所示,

public abstract class ComputerFactory {
    public abstract DesktopComputer createDesktopComputer();
    public abstract NotebookComputer createNotebookComputer();
}

定义了两个方法,分别用来生产台式电脑和笔记本电脑。

具体工厂
定义联想和惠普工厂:

public class LenovoFactory extends ComputerFactory {
    @Override
    public DesktopComputer createDesktopComputer() {
        return new LenovoDesktopComputer();
    }
    @Override
    public NotebookComputer createNotebookComputer() {
        return new LenovoNotebookComputer();
    }
}

public class HpFactory extends ComputerFactory {
    @Override
    public DesktopComputer createDesktopComputer() {
        return new HpDesktopComputer();
    }

    @Override
    public NotebookComputer createNotebookComputer() {
        return new HpNotebookComputer();
    }
}

联想工厂和惠普工厂用来生产台式机和笔记本这两个不同产品线的电脑。

客户端调用
最后编写客户端:

public class Client {
    public static void main(String[]args) {
        ComputerFactory lenocoFactory=new LenovoFactory();
        lenocoFactory.createDesktopComputer().start();
        lenocoFactory.createNotebookComputer().start();
        ComputerFactory hpFactory=new HpFactory();
        hpFactory.createDesktopComputer().start();
        hpFactory.createNotebookComputer().start();
    }
}

分别用LenovoFactory和HpFactory生产台式和笔记本电脑,并调用start方法启动它们。
运行结果为:
联想台式电脑启动
联想笔记本电脑启动
惠普台式电脑启动
惠普笔记本电脑启动

接下来给出这个例子的UML图,更便于理解,如下所示。
这里写图片描述

抽象工厂模式的优缺点

优点
具体类的创建实例过程与客户端分离,客户端通过工厂的抽象接口操纵实例,客户端并不知道具体的实现是谁。

缺点
如果增加新的产品族则也需要修改抽象工厂和所有的具体工厂。

抽象工厂模式的使用场景

  • 一个系统不依赖于产品线实例如何被创建、组合和表达的细节。
  • 系统中有多于一个的产品线,而每次只使用其中某一产品线。
  • 一个产品线(或是一组没有任何关系的对象)拥有相同的约束。

参考资料
《大话设计模式》
《设计模式之禅》
《Android源码设计模式》


欢迎关注我的微信公众号,第一时间获得博客更新提醒,以及更多成体系的Android相关原创技术干货。
扫一扫下方二维码或者长按识别二维码,即可关注。

展开阅读全文

设计模式抽象工厂模式

05-27

抽象工厂模式 别名:Kitrn遵循原则:依赖倒置rn意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类;rn适用:rn1、系统独立于它的产品的创建、组合、表示时rn2、系统需要多个产品系列配置时rn3、一系列相关产品进行联合使用时rn4、提供产品类库,而只想显示它们的接口而不是实现时rn参与者:rnAbstractFactoryrnConcretefactoryrnAbstractProductrnConcreteProductrnClientrn效果:rn1、分离了具体的类rn2、易于交换产品系列rn3、有利于产品的一致性rn缺点:rn难于支持新种类产品rn参与者:rnAbstractFactory、ConcreteFactory、AbstractProduct、ConcreteProduct、Clientrn实现:rn1、工厂通常采用单件类实现;rn2、创建产品通常为每一产品定义一工厂方法。有可能出现不同系列的产品差别很小,但却要定义一个具体工厂;多个产品系列中的具体工厂可以通过原型实现,具体工厂使用产品系列中的每个产品的原型实例来初始化,这样可使得不必每个新产品系列都需要一个新的具体工厂;rn3、定义可扩展的工厂:采用标识性参数利用一个方法创建一组产品,虽灵活但不安全,在类C++语言中需要这些产品具体相同的基类或客户端可以安全地进行类型转换时,但支持类类型的语言中没有此约束;rn相关:工厂方法[一般用来实现抽象工厂]、原型[抽象工厂的实现过程中的一种技巧]、单件[一般为单件类]rn延伸:rnMicrosoft:IDbConnection类采用抽象工厂模式创建IDbCommand,但IDbCommand未采用抽象工厂模式创建IDbAdapterrn示例:rnC#rn下面这个类扩展了DataCommandrnnamespace Sysnet.Datarnrn public static class DataAdapterHelperrn rn public static DataAdapterBuilder Builder get; set; rn static DataAdapterHelper()rn rn Builder = new DataAdapterBuilder();rn rn public static IDataAdapter CreateDataAdapter(this IDbCommand command)rn rn return Builder.CreateDataAdapter(command);//采用一个Builder主要是方便,将DataAdapter的创建功能的实现与接口进行分离,其思想是桥接模式rn rn public static DataSet FillDataSet(this IDataAdapter adapter)rn rn DataSet ds = new DataSet();rn adapter.Fill(ds);rn return ds;rn rn rn rnrnrnC++rnclass SQCOMMON_API CCommunicationInterfacernrnrnprivate:rn DECLARE_PROPERTY(KeepOpen,bool)rnpublic:rn //通讯方式的枚举定义rn enum CommunicationMethod rn rn //串口通讯方式rn EnumCommuSerial,rn //Socket通讯方式rn EnumCommuSocket,rn //数据库通讯方式rn EnumCommuDatabase,rn //文件通讯方式rn EnumCommuFile rn ;rnprotected:rn //获取当前通讯接口下的一个通讯结点类型,此方法为工厂的产品方法rn virtual CCommuEndPoint * get_ACommuEndPoint();rnpublic:rn //创建通讯接口rn static CCommunicationInterface * CreateCommunication(CommunicationMethod commuMethod,map &paramters);rn;rnrn 论坛

没有更多推荐了,返回首页