简单工厂模式、工厂方法模式和抽象工厂模式-设计模式学习

1、简单工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

工厂(Creator)角色

简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。

抽象产品(Product)角色

简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

具体产品(Concrete Product)角色

是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

优点

工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。

缺点

由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。

当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;

这些缺点在工厂方法模式中得到了一定的克服。

UML类图

//简单工厂模式
#include <iostream>

using namespace std;

class Product
{
public:
    virtual void show() = 0;
};

class Product1 : public Product
{
public:
    virtual void show()
    {
        cout<<"I am Product1"<<endl;
    }
};
class Product2 : public Product
{
public:
    virtual void show()
    {
        cout<<"I am Product2"<<endl;
    }
};

class Factory
{
public:
    Product *create(int n)
    {
        switch(n)
        {
        case 1:
            return new Product1;
        case 2:
            return new Product2;
        default:
            cout<<"I dont't know"<<endl;
            return NULL;
        }
    }
};

int main(void)
{
    Factory fac;
    Product *p1 = fac.create(1);
    Product *p2 = fac.create(2);

    p1->show();
    p2->show();

    delete p1;
    delete p2;

    return 0;
}

2、工厂方法模式

工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。

工厂方法模式对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

抽象工厂(Creator)角色

是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

具体工厂(Concrete Creator)角色

这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。在上图中有两个这样的角色:BulbCreator与ubeCreator。

抽象产品(Product)角色

工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。

具体产品(Concrete Product)角色

这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

UML类图

//工厂方法模式
#include <iostream>

using namespace std;

class Product
{
public:
    virtual void show() = 0;
};

class Product1 : public Product
{
public:
    virtual void show()
    {
        cout<<"I am Product1"<<endl;
    }
};
class Product2 : public Product
{
public:
    virtual void show()
    {
        cout<<"I am Product2"<<endl;
    }
};

class IFactory
{
public:
    virtual Product *create() = 0;
};

class Product1Factory : public IFactory
{
public:
    virtual Product *create()
    {
        return new Product1;
    }
};

class Product2Factory : public IFactory
{
public:
    virtual Product *create()
    {
        return new Product2;
    }
};

int main(void)
{
    IFactory *fac1 = new Product1Factory;
    Product *p1 = fac1->create();

    p1->show();

    delete p1;
    delete fac1;

    return 0;
}

3、抽象工厂模式

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据LSP原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

UML类图

产品族是指位于不同产品等级结构中,功能相关联的产品组成的家族。一般是位于不同的等级结构中的相同位置上。显然,每一个产品族中含有产品的数目,与产品等级结构的数目是相等的,形成一个二维的坐标系,水平坐标是产品等级结构,纵坐标是产品族。

当有多个不同的等级结构的产品时,如果使用工厂方法模式就势必要使用多个独立的工厂等级结构来对付这些产品的等级结构。如果这些产品等级结构是平行的,会导致多个平行的工厂等级结构。

抽象工厂模式使用同一个工厂等级结构负责这些不同产品等级结构产品对象的创建。

对于每一个产品族,都有一个具体工厂。而每一个具体工厂创建属于同一个产品族,但是分属于不同等级结构的产品。

通过引进抽象工厂模式,可以处理具有相同(或者相似)等级结构的多个产品族中的产品对象的创建问题。

由于每个具体工厂角色都需要负责两个不同等级结构的产品对象的创建,因此每个工厂角色都需要提供两个工厂方法,分别用于创建两个等级结构的产品。既然每个具体工厂角色都需要实现这两个工厂方法,所以具有一般性,不妨抽象出来,移动到抽象工厂角色中加以声明。

//抽象工厂模式
#include <iostream>

using namespace std;

class ProductA
{
public:
    virtual void show() = 0;
};

class ProductB
{
public:
    virtual void show() = 0;
};

class ProductA_1 : public ProductA
{
public:
    virtual void show()
    {
        cout<<"I am ProductA_1"<<endl;
    }
};

class ProductA_2 : public ProductA
{
public:
    virtual void show()
    {
        cout<<"I am ProductA_2"<<endl;
    }
};

class ProductB_1 : public ProductB
{
public:
    virtual void show()
    {
        cout<<"I am ProductB_1"<<endl;
    }
};

class ProductB_2 : public ProductB
{
public:
    virtual void show()
    {
        cout<<"I am ProductB_2"<<endl;
    }
};

class IFactory
{
public:
    virtual ProductA *createA() = 0;
    virtual ProductB *createB() = 0;
};

class Factory1 : public IFactory
{
public:
    virtual ProductA *createA()
    {
        return new ProductA_1;
    }
    virtual ProductB *createB()
    {
        return new ProductB_1;
    }
};

class Factory2 : public IFactory
{
public:
    virtual ProductA *createA()
    {
        return new ProductA_2;
    }
    virtual ProductB *createB()
    {
        return new ProductB_2;
    }
};
int main(void)
{
    IFactory *p1ifac = new Factory1;
    IFactory *p2ifac = new Factory2;

    ProductA *pa1 = p1ifac->createA();
    ProductB *pb2 = p2ifac->createB();

    pa1->show();
    pb2->show();

    delete pa1;
    delete pb2;
    delete p1ifac;
    delete p2ifac;

    return 0;
}

抽象工厂模式与工厂模式区别:

工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。

一个抽象工厂类,可以派生出多个具体工厂类。

每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。

一个抽象工厂类,可以派生出多个具体工厂类。

每个具体工厂类可以创建多个具体产品类的实例。

参考资料

1、简单工厂模式-百度百科

2、工厂方法模式-百度百科

3、抽象工厂模式-百度百科

4、《大话设计模式》的讲解工厂模式章节

时间: 2024-08-05 11:17:16

简单工厂模式、工厂方法模式和抽象工厂模式-设计模式学习的相关文章

工厂模式总结(简单工厂,工厂方法,抽象工厂)

工厂模式属于创建型模式,大致可以分为三类,简单工厂模式.工厂方法模式.抽象工厂模式. 通过两个例子讲解这三种工厂模式 示例一 简单工厂模式 首先介绍简单工厂模式,它的主要特点是需要在工厂类中做判断,从而创造相应的产品.当增加新的产品时,就需要修改工厂类.有点抽象,举个例子就明白了.有一家生产处理器核的厂家,它只有一个工厂,能够生产两种型号的处理器核.客户需要什么样的处理器核,一定要显示地告诉生产工厂.下面给出一种实现方案. 1 enum CTYPE {COREA, COREB}; 2 class

iOS设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)

1. 简单工厂模式 如何理解简单工厂,工厂方法, 抽象工厂三种设计模式? 简单工厂的生活场景,卖早点的小摊贩,他给你提供包子,馒头,地沟油烙的煎饼等,小贩是一个工厂,它生产包子,馒头,地沟油烙的煎饼.该场景对应的UML图如下所示: 图1:简单工厂模式UML图 简单工厂模式的参与者: 工厂(Factory)角色:接受客户端的请求,通过请求负责创建相应的产品对象. 抽象产品(Abstract Product)角色: 是工厂模式所创建对象的父类或是共同拥有的接口.可是抽象类或接口. 具体产品(Conc

【JS设计模式】温习简单工厂模式、工厂方法模式、抽象工厂模式概念

注:空心箭头表示的是种继承关系,工厂类和产品类之间是一种依赖关系.是用箭头加虚线表示的,以下的模型图是用的实线是不正确(时间不够用,在这里我偷懒了.这个习惯不好,呵呵) 简单工厂模式(Simple Factory Pattern): 使用一个类(通常为单体)来创建实例;简单工厂模式也叫静态工厂方法模式(Static FactoryMethod Pattern). 接口的定义通常是以I开头标识符,在JS中未定义接口或抽象类的语法: var MacBikeFactory = { createBike

iOS常用设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)

1. 简单工厂模式 如何理解简单工厂,工厂方法, 抽象工厂三种设计模式? 简单工厂方法包含:父类拥有共同基础接口,具体子类实现子类特殊功能,工厂类根据参数区分创建不同子类实例.该场景对应的UML图如下所示: 代码结构如下 Animal 类 @interface Animal :NSObject @proterty(nonatomic,strong) NSString *name; -(void)laugh; @end Dog类 @interface Dog:Animal @end Cat类 @i

工厂模式:简单工厂模式、工厂方法模式和抽象工厂模式

我们一般制造对象时,采用操作符new来进行创建.但是慢慢我们了解到实例化这个活动不应该总是公开地进行,同时初始化还经常造成"耦合"的问题. 如果我们不希望出现上述问题,那么我们就有必要认识一下"工厂模式",它将有助于我们从复杂的依赖中解脱出来. 1)为什么说"new"不好? 当看到"new",就会想到"具体". 我们不应该总是针对实现编程,但是当我们每次使用new时,正是在针对实现编程而不是接口,这很不符合

Java设计模式—工厂方法模式&amp;抽象工厂模式

工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义:Creator为抽象创建 类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的. 工厂方法模式的扩展方式有很多种,下边是工厂方法模式一个比较实用的源代码: 抽象产品类: pub

工厂方法模式And抽象工厂模式

一.工厂方法模式 简单工厂模式的缺陷就是类的创建太过于依赖工厂,一旦需要进行程序扩展,就必须修改工厂类的代码 这违背了背包原则. 而工厂方法模式针对这一问题进行了改进. public interface Sender { public void send(); } public interface producer { public Sender produce(); } public class MailFactory implements producer{ public Sender pr

设计模式:工厂方法模式(Factory Method)和抽象工厂模式(Abstact Factory)

?在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象. 在这些情况,新对象的建立就是一个 "过程",不仅是一个操作,像一部大机器中的一个齿轮传动. 分类 ?工厂模式主要是为创建对象提供过渡接口,以便将创建对象的

工厂方法模式与抽象工厂模式

本文转自:http://laughingchs.iteye.com/blog/1169986 一.引子       话说十年前,有一个暴发户,他家有三辆汽车——Benz奔驰.Bmw宝马.Audi奥迪,还雇了司机为他开车.不过,暴发户坐车时总是怪怪的:上Benz车后跟司机说“开奔驰车!”,坐上Bmw后他说“开宝马车!”,坐上Audi说“开奥迪车!”.你一定说:这人有病!直接说开车不就行了?!       而当把这个暴发户的行为放到我们程序设计中来时,会发现这是一个普遍存在的现象.幸运的是,这种有病