设计模式:工厂模式(续:虚构造函数和抽象工厂)

在之前的《设计模式:工厂模式》中记录了两种用于创建派生类对象的工厂模式,第一种模式直接使用基类的静态成员函数来创建派生类的对象,在该静态成员函数中直接调用了派生类的构造函数,第二种模式是使用基类工厂的静态成员函数,通过基类工厂中保存的各派生类工厂来创建派生类对象,派生类工厂是派生类的嵌套类,相当于为派生类量身定做的专属工厂,这些专属工厂的存在使得基类工厂不必了解创建派生类对象的细节。今天主要记录另外两种工厂模式:虚构造函数和抽象工厂。虚构造函数模式与前两种工厂模式不同,在前两种工厂模式中,基类是基类,派生类是派生类,在虚构造函数模式中,基类虽然还是基类,但是基类的行为却是派生类的行为,所以从作用效果上看,基类貌似就是派生类了,下面看一个简单的例子:

class Base {
	Base *p;
protected:
	Base() { p = NULL; }
public:
	Base(const string &str);
	~Base();
	virtual void func() { p->func(); }
};

这是基类的定义,基类中有一个基类的指针:p ,这个指针最终将指向一个派生类对象,注意到在基类的成员函数func()中,通过p调用了派生类的func(),所以基类的行为就是派生类的行为,下面我们看一下Base(const string &str)的定义:

Base::Base(const string &str) {
	if(str=="A") p = new A();
	if(str=="B") p = new B();
}

所以当我们调用上述构造函数来创建一个基类对象时,同时将基类的成员指针p指向了一个派生类对象,接下来这个基类对象的所有行为都是派生类的行为,所以基类对象看起来就像一个派生类对象,这就是所谓的“虚构造函数”。下面是完整的代码:

#include<iostream>
#include<string>
using namespace std;

class Base {
	Base *p;
protected:
	Base() { p = NULL; }
public:
	Base(const string &str);
	~Base();
	virtual void func() { p->func(); }
};

class A : public Base {
	A() {}
	A(const A&) {}
	friend class Base;
public:
	void func() { cout<<"This is from A"<<endl; }
};

class B : public Base {
	B() {}
	B(const B&) {}
	friend class Base;
public:
	void func() { cout<<"This is from B"<<endl; }
};

Base::Base(const string &str) {
	if(str=="A") p = new A();
	if(str=="B") p = new B();
}

Base::~Base() {
	delete p;
}

int main() { 

	Base *s = new Base("A");
	s->func();
	delete s;

	return 0;
}

需要注意的是Base中还有一个无参的默认构造函数,这个构造函数将在创建派生类对象的时候被调用,来初始化派生类对象中的基类子对象,即来初始化p,不过这个p对于我们而言是没用的,所以将之初始化为0,不过令p=0还有一个好处,因为在销毁基类对象的时候会调用基类的析构函数,在析构函数中有delete p,这将引发派生类的析构函数,之后派生类的析构函数又会调用基类子对象的析构函数,即会第二次调用基类的析构函数,唯一不同的是此p非彼p,如果此p不为0,可能引发未知的后果。

抽象工厂模式也很简单,其本意是有一大堆派生类工厂,这些派生类工厂根据自己的需要创建合适的对象,直接看代码或许更直观:

class BaseA {};
class A1 : public BaseA{};
class A2 : public BaseA{};

class BaseB {};
class B1 : public BaseB {};
class B2 : public BaseB {};

class Factory {
public:
	virtual BaseA* createA() = 0;
	virtual BaseB* createB() = 0;
};

class OneFactory : public Factory {
	BaseA* createA() { return new A1(); }
	BaseB* createB() { return new B1(); }
};

class TwoFactory : public Factory {
	BaseA* createA() { return new A2(); }
	BaseB* createB() { return new B2(); }
};

Factory提供公共的接口,OneFactory根据自己的需要重新定义createA和createB,生成A1和B1的对象,TwoFactory也是根据自己的需要重新定义createA和createB,来分别生成A2和B2的对象。使用方式如下:

int main() { 

	Factory *p1 = new OneFactory();
	p1->createA();
	Factory *p2 = new TwoFactory();
	p2->createA();
	return 0;
}
时间: 2024-10-19 19:15:54

设计模式:工厂模式(续:虚构造函数和抽象工厂)的相关文章

设计模式(一): abstract factory抽象工厂模式 -- 创建型模式

1.定义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 2.适用场景 1.一个系统要独立于它的产品创建.组合和表示. 2.一个系统要由多个产品系列中的一个来配置. 3.当你要强调一系列相关的产品对象的设计以便进行联合使用. 4.当你提供一个产品类库,而只想显示它们的接口而不是实现. 3.评价 1.它分离了具体的类 2.它使得易于交换产品系列 3.它有利于产品的一致性 4.难以支持新种类的产品 5."开放-封闭"原则要求系统对扩展开放,对修改封闭.通过扩展达到增

设计模式那点事读书笔记(2)----抽象工厂模式

抽象工厂模式: 此模式提供了一个接口,用于创建相关或者依赖对象的家族,而不需要指定具体实现类. 解决什么问题: 抽象工厂模式允许客户在使用抽象接口来创建一组相关的产品,客户类和工厂类分开,客户需要任何产品的时候,只需要向工厂请求即可,客户无须修改就可以获得新产品.从而实现客户从具体的产品中解耦. UML: 代码结构: 代码: 定义抽象产品: package com.demo.factory.model; /** * 抽象产品 */ public abstract class AbstractBa

面向程序员的设计模式 ——GoF《设计模式》读书总结(壹)抽象工厂&amp;生成器

第一部分:创建型模式 创建型模式抽象了实例化过程.它们帮助一个系统独立于如何创建.组合和表示它的那些对象.(把一些小的对象组装成大对象,这个工作由专门的类对象来做) 一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象. 随着系统演化得越来越依赖于对象复合而不是类继承,创建型模式变得更为重要.因为系统定义一个较小的行为集,这些行为可以被组合成任意数目的更复杂的行为. (把行为分散在各类中,用对象组合的方式,根据需要组合成大类) 这些创建型模式有两个特点: 1.它

设计模式系列一创建型之(抽象工厂模式)

1.抽象工厂简介 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作:同时由于需求的变化,往往存在着更多系列对象的创建工作. 如何应对这种变化? 如何绕过常规的对象的创建方法(new)? 如何来避免客户程序和这种“多系列具体对象创建工作”的紧耦合? 然而抽象工厂便可以很好地解决这个问题! 2.意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类. 3.适用性 一个系统要独立与它的产品创建.组合和表示时 一个系统要由多个产品系列中的一个来配置时 当你要强调一系列相关的产

设计模式---(简单工厂模式,工厂模式,抽象工程模式),单例模式,代理模式,装饰器

简单工厂模式    简单工厂模式并不属于GoF的23种设计模式.     那么为什么我要用工厂模式呢?请看下面的一段程序.  #include  <iostream> using  namespace  std; class  Fruit  { public:     Fruit(string  name)  {         this-­‐>name  =  name;         if  (name  ==  "apple")  {      

设计模式-抽象工厂模式(C#)

设计模式--抽象工厂模式(JAVA) 在抽象工厂模式中,一个具体工厂可以生产一组相关的具体产品,这样的一组产品成为产品族,产品族中的每一个产品都属于某一个产品继承等等级结构.当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构.属于不同类型的具体产品时就可以使用抽象工厂模式. 抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建,当一个工

23种设计模式(3):抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,并且无需指定他们的详细类. 类型:创建类模式 类图: 抽象工厂模式与工厂方法模式的差别 抽象工厂模式是工厂方法模式的升级版本号,他用来创建一组相关或者相互依赖的对象.他与工厂方法模式的差别就在于,工厂方法模式针对的是一个产品等级结构:而抽象工厂模式则是针对的多个产品等级结构.在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的全部产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类

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

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

JAVA设计模式之抽象工厂模式

本文继续介绍23种设计模式系列之抽象工厂模式. 前面已经介绍过简单工厂模式和工厂方法模式,这里继续介绍第三种工厂模式-抽象工厂模式,还是以汽车的制造为例. 例子背景: 随着客户的要求越来越高,宝马车需要不同配置的空调和发动机等配件.于是这个工厂开始生产空调和发动机,用来组装汽车.这时候工厂有两个系列的产品:空调和发动机.宝马320系列配置A型号空调和A型号发动机,宝马230系列配置B型号空调和B型号发动机. 概念: 抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象.比如