26.1 工厂方法模式 VS 建造者模式

26.1.1 按工厂方法建造超人

(1)产品:两类超人,成年超人和未成年超人。

(2)工厂:这里选择简单工厂

【编程实验】工厂方法建造超人

//创建型模式大PK——工厂方法和建造者模式
//实例:利用简单工厂创建的超人
#include <iostream>
using namespace std; //***************************抽象产品接口*********************
//超人接口
class ISuperMan
{
public:
//每个超人都有特殊的技能
virtual void specialTalent() = ; virtual ~ISuperMan(){}
}; //*************************具体产品***********************
//成年超人
class AdultSuperMan : public ISuperMan
{
public:
void specialTalent()
{
cout << "超人力大无穷" <<endl;
}
}; //未成年人超人
class ChildSuperMan : public ISuperMan
{
public:
void specialTalent()
{
cout << "小超人的能力是刀枪不入、快速移动" <<endl;
}
}; //***********************简单工厂****************************
class SuperManFactory
{
public:
static ISuperMan* createSuperMan(string type)
{
//根据输入参数产生不同的超人
if(type == "adult")
{
return new AdultSuperMan();
}
else if (type == "child")
{
return new ChildSuperMan();
}
else
return NULL;
}
}; int main()
{
//模拟生产超人(注意从生产工厂里出来的产品(如adult)都是一个模
//样的,没有特殊的地方,这与后面的建造者模式有很大的不同)
ISuperMan* sm = SuperManFactory::createSuperMan("child");
//展示一下超人的技能
sm->specialTalent(); delete sm; return ;
};

26.1.2 按建造者模式建造超人

(1)产品的三大组成部分:躯体、特殊技能、身份标记

(2)建造者:Builder。注意,与标准的建造者模式不同,这里的部件如何组装的过程由各个具体的建造者负责,而标准的作法是放到Director角色中去完成的。

//创建型模式大PK——工厂方法和建造者模式
//实例:利用建造者模式创建的超人
#include <iostream>
using namespace std; //***************************辅助类*********************
//超人的身驱
class Body
{
string body;
public:
string& getBody(){return body;}
void setBody(string value)
{
body = value;
}
}; //特殊技能
class SpecialTalent
{
string specialTalent;
public:
string& getSpecialTalent(){return specialTalent;}
void setSpecialTalent(string value)
{
specialTalent = value;
}
}; //超人的标志
class SpecialSymbol
{
string symbol;
public:
string& getSymbol(){return symbol;}
void setSymbol(string value)
{
symbol = value;
}
}; //超人
class SuperMan
{
private:
Body body;
SpecialSymbol specialSymbol;
SpecialTalent specialTalent;
public:
string& getBody(){return body.getBody();}
void setBody(string value)
{
body.setBody(value);
} string& getSpecialTalent(){return specialTalent.getSpecialTalent();}
void setSepcialTalent(string value)
{
specialTalent.setSpecialTalent(value);
} string& getSpecialSymbol(){return specialSymbol.getSymbol();}
void setSpecialSymbol(string value)
{
specialSymbol.setSymbol(value);
} virtual ~SuperMan(){}
}; //*************************Builder角色***********************
//抽象建造者
class Builder
{
protected:
SuperMan* superMan;
public:
Builder()
{
superMan = new SuperMan();
} //构建出超人的躯体
void setBody(string value)
{
superMan->setBody(value);
} //构建出超人的特殊技能
void setSpecialTalent(string value)
{
superMan->setSepcialTalent(value);
} //构建出超人的特殊标记
void setSpecialSymbol(string value)
{
superMan->setSpecialSymbol(value);
} //构建出一个完整的超人
//超人的各个部件都准备好了,具体怎么组装由实现类来决定,
//体现建造者模式将复杂对象的构建和表示分离的意图
virtual SuperMan* getSuperMan() = ; virtual ~Builder()
{
delete superMan;
}
}; //成年超人建造者
class AdultSuperManBuilder :public Builder
{
public:
SuperMan* getSuperMan()
{
//1.标准的建造者模式,建造过程是放在Director中进行装配的。
//2.建造者模式关注产品的各个部分,甚至构建顺序,
// 即相同的部件,装配顺序不同,产生的结果也可能不同,
// 这正是建造者模式的意图)
superMan->setBody("强壮的躯体");
superMan->setSepcialTalent("会飞行");
superMan->setSpecialSymbol("胸前带S标记"); return superMan;
}
}; //未成年超人建造者
class ChildSuperManBuilder :public Builder
{
public:
SuperMan* getSuperMan()
{
//建造过程
superMan->setBody("强壮的躯体");
superMan->setSepcialTalent("刀枪不入");
superMan->setSpecialSymbol("胸前带小S标记"); return superMan;
}
}; //导演类
class Director
{
private:
static Builder* adultBuilder;
static Builder* childBuilder;
public:
//本例中,以下函数只是一个空壳,而标准的建造者模式
//其部件的组装过程是在以下两部函数中完成的! //建造一个成人超人
static SuperMan* getAdultSuperMan()
{ return adultBuilder->getSuperMan();
} //建造一个未成年人超人
static SuperMan* getChildSuperMan()
{
return childBuilder->getSuperMan();
}
};
Builder* Director::adultBuilder = new AdultSuperManBuilder();
Builder* Director::childBuilder = new ChildSuperManBuilder(); int main()
{
//建造一个超人
SuperMan* sm = Director::getAdultSuperMan();
//SuperMan* sm = Director::getChildSuperMan(); //展示一个超人的能力
cout << "超人的身体:" << sm->getBody() << endl;
cout << "超人的特殊能力:" << sm->getSpecialTalent() << endl;
cout << "超人带的标志:" << sm->getSpecialSymbol() << endl; return ;
};
/*输出结果
超人的身体:强壮的躯体
超人的特殊能力:会飞行
超人带的标志:胸前带S标记
*/

26.1.3 最佳实践

(1)意图不同

  ①工厂方法模式,关注的是一个产品整体无须关心产品各部分是如何创建出来的。

  ②建造者模式,一个具体产品的产生是依赖各个部件的产生以及装配顺序,它关注的是“由零件一步一步地组装出产品对象

  ③简单理解,工厂模式是一个对象创建的粗线条应用,建造者模式则是通过细线程勾勒出一个复杂对象,关注的是产品组成部分的创建过程。

(2)产品的复杂度不同

  ①工厂方法模式创建的产品一般都是单一性质产品,都是一个模样

  ②建造者模式创建的则是一个复合产品,它则各个部件复合而成,部件不同,产品对象当然不同。

  ③一般来说工厂方法模式创建的产品的粒度比较粗,而建造者模式的产品对象粒度比较细。

(3)方法的选择:如果关注一个产品部件的生产、安装步骤,则选择建造者否则选择工厂方法模式

26.2 抽象工厂模式 VS 建造者模式

26.2.1 抽象工厂模式

(1)产品等级:宝马(BWM)、奔驰(Benz)

(2)产品族:即车型(如商务车型Van、运动型SUV),即每个工厂要生产两种车型

【编程实验】按抽象工厂模式生产车辆

//创建型模式大PK——抽象工厂方法和建造者模式
//实例:利用抽象工厂方法生产汽车
#include <iostream>
using namespace std; //抽象产品
class ICar
{
public:
//获取汽车生产商,即品牌
virtual string getBand() = ;
//获取汽车的型号
virtual string getModel() = ;
}; //抽象宝马车
class AbsBMW : public ICar
{
string BMW_BNAD;
public:
AbsBMW()
{
BMW_BNAD = "宝马汽车";
} string getBand()
{
return BMW_BNAD;
}
}; //宝马商务车
class BMWVan :public AbsBMW
{
string SEVENT_SEARIES;
public:
BMWVan():AbsBMW()
{
SEVENT_SEARIES = "7系列商务车";
}
string getModel()
{
return SEVENT_SEARIES;
}
}; //宝马Suv
class BMWSuv :public AbsBMW
{
string X_SEARIES;
public:
BMWSuv():AbsBMW()
{
X_SEARIES = "x系列Suv";
}
string getModel()
{
return X_SEARIES;
}
}; //抽象奔驰车
class AbsBenz : public ICar
{
string BENZ_BNAD;
public:
AbsBenz()
{
BENZ_BNAD = "奔驰汽车";
} string getBand()
{
return BENZ_BNAD;
}
}; //奔驰商务车
class BenzVan :public AbsBenz
{
string R_SEARIES;
public:
BenzVan():AbsBenz()
{
R_SEARIES = "R系列商务车";
}
string getModel()
{
return R_SEARIES;
}
}; //奔驰Suv
class BenzSuv :public AbsBenz
{
string G_SEARIES;
public:
BenzSuv():AbsBenz()
{
G_SEARIES = "G系列Suv";
}
string getModel()
{
return G_SEARIES;
}
}; //抽象工厂
class CarFactory
{
public:
//生产SUV型
virtual ICar* createSuv() = ;
//生产商务车型
virtual ICar* createVan() = ;
}; //宝马车工厂
class BMWFactory : public CarFactory
{
public:
ICar* createSuv()
{
return new BMWSuv();
} ICar* createVan()
{
return new BMWVan();
}
}; //奔驰车工厂
class BenzFactory : public CarFactory
{
public:
ICar* createSuv()
{
return new BenzSuv;
} ICar* createVan()
{
return new BenzVan();
}
}; int main()
{
//要求生产一辆奔驰车
cout <<"===要求生产一辆奔驰车SUV===" << endl;
//首先找奔驰车的工厂
CarFactory* carFactory = new BenzFactory();
//开始生产
ICar* car = carFactory->createSuv();
//生产完毕,展示一下车辆信息
cout << "===车辆生产完毕,详细信息如下===" << endl;
cout << "汽车品牌:" << car->getBand() <<endl;
cout << "汽车型号:" << car->getModel() <<endl; return ;
};
/*输出结果
===要求生产一辆奔驰车SUV===
===车辆生产完毕,详细信息如下===
汽车品牌:奔驰汽车
汽车型号:G系列Suv
*/

26.2.2 建造者模式

(1)整体:汽车。部分:引擎和车轮

(2)Builder:BenzBuilder和BMWBuilder

【编程实验】按建造者模式生产车辆

//创建型模式大PK——抽象工厂方法和建造者模式
//实例:利用建造者模式生产汽车
#include <iostream>
using namespace std; //**********************辅助类*******************************
//生产蓝图(这个蓝图会交给Director,让他这个要求去生产汽车)
class Blueprint
{
private:
string wheel; //车轮的要求
string engine; //引擎的要求
public:
string getWheel(){return wheel;}
void setWheel(string value)
{
wheel = value;
} string getEngine(){return engine;}
void setEngine(string value)
{
engine = value;
}
}; //车辆产品
class ICar
{
public:
//汽车车轮
virtual string getWheel() = ;
//汽车引擎
virtual string getEngine() = ;
//显示信号
virtual string toString() = ;
virtual ~ICar (){}
}; //具体车辆
class Car : public ICar
{
private:
string engine; //引擎
string wheel; //车轮
public:
Car(string engine, string wheel)
{
this->engine = engine;
this->wheel = wheel;
} string getEngine()
{
return engine;
}
string getWheel()
{
return wheel;
} //演示车辆信息
string toString()
{
return "车的轮子是:" + wheel + "\n车的引擎是:" + engine;
}
}; //抽象建造者
class CarBuilder
{
private:
//ICar* car; //等建造的汽车
Blueprint* bp; //设计蓝图
protected:
//只有具体的建造者才可以查看蓝图
Blueprint* getBlueprint(){return bp;}
public:
//接收一份设计蓝图
void setBlueprint(Blueprint* value)
{
bp = value;
} //部件的构建
virtual string buildWheel() = ;
virtual string buildEngine() = ; //按照顺序生产一辆车
Car* buildCar()
{
return new Car(buildEngine(),buildWheel());
}
virtual ~CarBuilder(){}
}; //宝马车建造车间
class BMWBuilder : public CarBuilder
{
public:
string buildEngine()
{
//按车间主任(Director)手里的蓝图进行设计
return getBlueprint()->getEngine();
} string buildWheel()
{
//按车间主任(Director)手里的蓝图进行设计
return getBlueprint()->getWheel();
}
}; //奔驰车建造车间
class BenzBuilder : public CarBuilder
{
public:
string buildEngine()
{
//按车间主任(Director)手里的蓝图进行设计
return getBlueprint()->getEngine();
} string buildWheel()
{
//按车间主任(Director)手里的蓝图进行设计
return getBlueprint()->getWheel();
}
}; //导演类:Director
class Director
{
private:
//持有建造者的引用
CarBuilder* bmwBuilder;
CarBuilder* benzBuilder;
public:
Director()
{
bmwBuilder = new BMWBuilder();
benzBuilder = new BMWBuilder();
}
//生产车辆
ICar* createCar(CarBuilder* carBuilder, string engine, string wheel)
{
//导演手中的蓝图
Blueprint bp;
bp.setEngine(engine);
bp.setWheel(wheel);
carBuilder->setBlueprint(&bp);
return carBuilder->buildCar();
}
//生产奔驰SUV
ICar* createBenzSuv()
{
return createCar(benzBuilder, "benz的引擎","benz的轮胎");
} //生产宝马商务
ICar* createBMWVan()
{
return createCar(bmwBuilder, "BMW的引擎","BMW的轮胎");
} //生产混合车型
ICar* createComplexCar()
{
return createCar(bmwBuilder, "BMW的引擎","benz的轮胎");
} ~Director()
{
delete benzBuilder;
delete bmwBuilder;
}
}; int main()
{
//定义一个导演类
Director director;
//生成一辆奔驰车SUV
cout <<"===制造一辆奔驰SUV===" << endl;
ICar* benzSuv = director.createBenzSuv();
cout << benzSuv->toString() << endl; cout <<"===制造一辆宝马商务车===" << endl;
ICar* bmwVan = director.createBMWVan();
cout << bmwVan->toString() << endl; cout <<"===制造一辆混合车===" << endl;
ICar* complexCar = director.createComplexCar();
cout << complexCar->toString() << endl; delete benzSuv;
delete bmwVan;
delete complexCar; return ;
};
/*输出结果
===制造一辆奔驰SUV===
车的轮子是:benz的轮胎
车的引擎是:benz的引擎
===制造一辆宝马商务车===
车的轮子是:BMW的轮胎
车的引擎是:BMW的引擎
===制造一辆混合车===
车的轮子是:benz的轮胎
车的引擎是:BMW的引擎
*/

26.2.3 最佳实践

(1)抽象工厂模式只关心一个工厂到底生产了哪些产品,不关心具体怎么生产的。

(2)建造者模式要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新的产品

(3)抽象工厂使用“工厂”来描述产品的构建,它是一种更高层次看对象的构建,而建造者使用“车间”来描述,不同的车间完成不同的创建和装配任务,一个完整的汽车生产过程需要引擎制造车间、引擎装配车间的配合才能完成,它们配合的基础是设计蓝图,而这个蓝图掌握在车间主任(Director)手中,它给建造者车间什么蓝图就能生产什么产品,它更关心建造过程。

(4)相对来说,抽象工厂模式比建造者模式的尺度更大,它关注产品整体,而建造者模式关注的是构建过程

(5)如果希望屏蔽对象的创建过程,只提供一个良好的封装,可以选择抽象工厂模式。如果在构件时通过不同的装配产生出新的对象,可以使用建造者模式。

第26章 创建型模式大PK的更多相关文章

  1. 第28章 行为型模式大PK

    27.1 策略模式 VS 命令模式 27.1.1 策略模式实现压缩算法 //行为型模式大PK——策略模式和命令模式 //实例:用策略模式实现压缩算法 #include <iostream> ...

  2. 设计模式之创建类模式大PK

                                        创建类模式大PK 创建类模式包括工厂方法模式.建造者模式.抽象工厂模式.单例模式和原型模式,他们能够提供对象的创建和管理职责.其 ...

  3. 第27章 结构型模式大PK

    27.1 代理模式 VS 装饰模式 27.1.1 代理模式 (1)场景:客人找运动员代理要求安排运动员参加比赛 (2)说明:代理人有控制权,可以拒绝客人的要求,也可以答应安排,甚至自己下去跑(因为有些 ...

  4. 创建类模式大PK(总结)

    创建类模式包含工厂方法模式.建造者模式.抽象工厂模式.单例模式和原型模式,它们都可以提供对象的创建和管理职责.当中的单例模式和原型模式很easy理解,单例模式是要保持在内存中仅仅有一个对象,原型模式是 ...

  5. Java设计模式之五大创建型模式(附实例和详解)

    一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥 ...

  6. (转)Java经典设计模式(1):五大创建型模式(附实例和详解)

    原文出处: 小宝鸽 一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代 ...

  7. 设计模式GOF23(创建型模式)

    • 创建型模式:  单例模式.工厂模式.抽象工厂模式.建造者模式.原型模式.   • 结构型模式: –适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.   • 行为型模式: 模 ...

  8. Java设计模式之创建型模式

    创建型模式分为五类:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 一.工厂方法模式:接口-实现类.工厂类

  9. 设计模式之美:Creational Patterns(创建型模式)

    创建型模式(Creational Patterns)抽象了对象实例化过程. 它们帮助一个系统独立于如何创建.组合和表示它的那些对象. 一个类创建型模式使用继承改变被实例化的类. 一个对象创建型模式将实 ...

随机推荐

  1. Sublime Text 3汉化中文版

    Sublime Text 3汉化中文版是Sublime Text2的升级版.Sublime Text 是一款流行的文本编辑器软件,有点类似于TextMate,跨平台,可运行在Linux,Windows ...

  2. UITableViewDataSource协议

    前言: 在iOS开发中,表视图UITableView 是我们做UI界面设计时的重要视图. 那么,使用表视图UITableView 需要遵守哪些协议呢? <UITableViewDataSourc ...

  3. [javascript svg fill stroke stroke-width x1 y1 x2 y2 line stroke-opacity fill-opacity 属性讲解] svg fill stroke stroke-width stroke-opacity fill-opacity line绘制线条属性讲解

    <!DOCTYPE html> <html lang='zh-cn'> <head> <title>Insert you title</title ...

  4. Sharepoint学习笔记—习题系列--70-576习题解析 -(Q32-Q35)

    Question 32 You are designing the modification of an existing SharePoint 2010 intranet site for a sc ...

  5. 【CoreData】多个数据库使用

    在实际开发中,往往需要每个模块使用不同数据库,而CoreData也具备这样的功能,使用起来也很方便: 首先我们创建2个模型文件(School和Educationist) // 1.创建模型文件 (相当 ...

  6. 发布一个java Servlet (静态发布)

    Servlet 是sun开发的动态web资源 的技术 让 Servlet 能响应用户请求,必须将 Servlet 配置在 Web 应用中 如何将Servlet用Tomcat发布出去: 编译你的.jav ...

  7. swift学习之UI控件(一)

    // //  ViewController.swift //  test // //  Created by chuangqu on 15/7/23. //  Copyright (c) 2015年 ...

  8. 【Android】OPlayer升级Vitamio到4.1

    前言 很久没有更新OPlayer,还是使用旧版Vitamio 3.0版本(新版已经到4.1),这次更新下. 声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.c ...

  9. iOS-公司开发者账号的申请和注册(博主原创+亲身经历+2016年申请+附带与邓白氏公司的往来邮件截图)

    不吹不黑,此篇博客真乃我的良心之作啊,希望对大家有所帮助! 链接在简书:http://www.jianshu.com/p/9de6a8eb4d88

  10. EMC Documentum DQL整理(一)

    1.Get user SELECT * FROM dm_user WHERE r_is_group = 0   2.Get Group SELECT * FROM dm_group WHERE gro ...