原创 读《大话设计模式》---外观模式(Facade) 收藏
-
Upload
wensheng-wei -
Category
Technology
-
view
222 -
download
0
Transcript of 原创 读《大话设计模式》---外观模式(Facade) 收藏
读《大话设计模式》---外观模式 (Facade)
外观模式:
为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得一个子系统更加容易使用
外观模式结构图
外观模式的一般实现方法: 1. #include <iostream> 2. using namespace std; 3. class SubSystemOne 4. { 5. public: 6. void MethodOne() 7. { 8. cout << " 子系统方法一" << endl; 9. } 10. }; 11. class SubSystemTwo 12. { 13. public: 14. void MethodTwo() 15. { 16. cout << " 子系统方法二" << endl; 17. } 18. };
19. class SubSystemThree 20. { 21. public: 22. void MethodThree() 23. { 24. cout << " 子系统方法三" << endl; 25. } 26. }; 27. class SubSystemFour 28. { 29. public: 30. void MethodFour() 31. { 32. cout << " 子系统方法四" << endl; 33. } 34. }; 35. //外观类,它需要了解所有子系统的方法和属性,进行组合,以备外界使用。 36. class Facade 37. { 38. private: 39. SubSystemOne * one; 40. SubSystemTwo * two; 41. SubSystemThree * three; 42. SubSystemFour * four; 43. public: 44. Facade() 45. { 46. one = new SubSystemOne(); 47. two = new SubSystemTwo(); 48. three = new SubSystemThree(); 49. four = new SubSystemFour(); 50. } 51. ~Facade() 52. { 53. delete one; 54. delete two; 55. delete three; 56. delete four; 57. } 58. void MethodA() 59. { 60. cout << "\n 方法组 A() ---- " << endl; 61. one->MethodOne(); 62. two->MethodTwo(); 63. four->MethodFour(); 64. } 65. 66. void MethodB() 67. { 68. cout << "\n 方法组 B() ---- " << endl; 69. two->MethodTwo(); 70. three->MethodThree(); 71. } 72. }; 73. //由于 Facade 的存在,客户端根本不需要知道子系统的存在 74. int main() 75. { 76. Facade * facade = new Facade(); 77. facade->MethodA(); 78. facade->MethodB(); 79. delete facade; 80. return 0; 81. }
Facade 模式的具体实现 1. //投资基金代码 2. #include <iostream> 3. using namespace std; 4. //股票 1 5. class Stock1 6. { 7. //卖股票 8. public: 9. void Sell() 10. { 11. cout << " 股票 1 卖出" << endl; 12. } 13. 14. //买股票
15. void Buy() 16. { 17. cout << " 股票 1 买入" << endl; 18. } 19. }; 20. //股票 2 21. class Stock2 22. { 23. //卖股票 24. public: 25. void Sell() 26. { 27. cout << " 股票 2 卖出" << endl; 28. } 29. 30. //买股票 31. void Buy() 32. { 33. cout << " 股票 2 买入" << endl; 34. } 35. }; 36. //股票 3 37. class Stock3 38. { 39. //卖股票 40. public: 41. void Sell() 42. { 43. cout << " 股票 3 卖出" << endl; 44. } 45. 46. //买股票 47. void Buy() 48. { 49. cout << " 股票 3 买入" << endl; 50. } 51. }; 52. //国债 1 53. class NationalDebt1 54. { 55. //卖国债 56. public: 57. void Sell() 58. { 59. cout << " 国债 1 卖出" << endl; 60. } 61. 62. //买国债 63. void Buy() 64. { 65. cout << " 国债 1 买入" << endl; 66. } 67. }; 68. //房地产 1 69. class Realty1 70. { 71. //卖房地产 72. public: 73. void Sell() 74. { 75. cout << " 房产 1 卖出" << endl; 76. } 77. 78. //买房地产 79. void Buy() 80. { 81. cout << " 房产 1 买入" << endl; 82. } 83. }; 84. class Fund 85. { 86. private: 87. Stock1 * gu1; 88. Stock2 * gu2; 89. Stock3 * gu3; 90. NationalDebt1 * nd1; 91. Realty1 * rt1; 92.
93. public: 94. Fund() 95. { 96. gu1 = new Stock1(); 97. gu2 = new Stock2(); 98. gu3 = new Stock3(); 99. nd1 = new NationalDebt1(); 100. rt1 = new Realty1(); 101. } 102. ~Fund() 103. { 104. delete gu1; 105. delete gu2; 106. delete gu3; 107. delete nd1; 108. delete rt1; 109. } 110. void BuyFund() 111. { 112. gu1->Buy(); 113. gu2->Buy(); 114. gu3->Buy(); 115. nd1->Buy(); 116. rt1->Buy(); 117. } 118. void SellFund() 119. { 120. gu1->Sell(); 121. gu2->Sell(); 122. gu3->Sell(); 123. nd1->Sell(); 124. rt1->Sell(); 125. } 126. }; 127. int main() 128. { 129. Fund * fund = new Fund(); 130. 131. fund->BuyFund(); 132. fund->SellFund(); 133. 134. delete fund; 135. return 0; 136. }
何时使用外观模式: 1.在设计阶段初期,要有意识的将不同的两个层分离,比如经典的三层架构,就需要考虑在数据访问层和业务逻辑层、业务逻辑层和表示层的层与层之间建立外观 Facade,这样可以为复杂的子系统提供一个简单的接口,使得耦合大大降低。 2.在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂。增加外观 Facade 可以提供一个简单的接口,减少它们之间的依赖 3.在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,可以为新系统开发一个外观 Facade 类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与 Facade 对象交互,Facade 与遗留代码交互所有复杂的工作。
[说明]
简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。 简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例。工厂模式的几种形态工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。工厂模式有以下几种形态:
1. 简单工厂(Simple Factory)模式,又称静态工厂方法模式(Static Factory MethodPattern)。 2. 工厂方法(Factory Method)模式,又称多态性工厂(Polymorphic Factory)模式或虚拟构造子(Virtual Constructor)模式; 3. 抽象工厂(Abstract Factory)模式,又称工具箱(Kit 或 Toolkit)模式。
注意:简单工厂模式并不包含在 23 种模式之内。
//下面是一个计算器了例子,用到了简单工厂模式 class operation
{
private:
double numberA;
double numberB;
double result;
public:
virtual double GetResult()
{
return result ;
}
}
class operationAdd :operation
{
public:
operationAdd(double A,double B)
virtual double GetResult()
{
result = numberA+numberB;
return result ;
}
}
class operationSub:operation
{
public:
operationSub(double A,double B)
virtual double GetResult()
{
result = numberA - numberB;
return result;
}
}
//简单工厂 class operationFactory
{
public:
static operation * CreateOperation(string operation)
{
operation * oper = NULL;
switch(operation)
{
case "+":
oper = new operationAdd();
break;
case "-"
oper = new operationSub();
break;
}
return oper;
}
}
因为对 C#不是很熟,所以将 C#的程序转成了 C++的。
// 一个超市打折的实例 #include "stdafx.h"#include "stdio.h"
//抽象类class CashSuper{public: virtual double acceptCash(double money) = 0;};
//正常收费子类class CashNormal : public CashSuper{public: virtual double acceptCash(double money) { return money; }};
//打折收费子类class CashRebate : public CashSuper{private: double moneyRebate;
public: CashRebate(double Rebate = 0.0):moneyRebate(Rebate) {
} virtual double acceptCash(double money) { return money * moneyRebate; }};
//返利收费子类class CashReturn : public CashSuper{private: double moneyCondition; double moneyReturn;public: CashReturn(double Condition = 0.0, double Return = 0.0):moneyCondition(Condition), moneyReturn(Return) {
} virtual double acceptCash(double money) { double result = money; if(money >= moneyCondition) result = money - (money / moneyCondition) * moneyReturn; return result; }};
class CashFactory{public: static CashSuper * createCashAccept(int type) //现金收取工厂 { CashSuper * cs = 0; switch(type) { //正常收费 case 0: cs = new CashNormal(); break; case 1: cs = new CashReturn(300, 100); break; case 2: cs = new CashRebate(0.8); break; } return cs; }};
int main(int argc, char* argv[]){ double totle; int type = 1;
CashSuper * csuper = CashFactory::createCashAccept(type); printf("%2.2f\n",csuper->acceptCash(1000));
return 0;}
工厂方法模式(factory method) :
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到他的子类。
简单工厂模式和工厂方法模式的区别: 1.简单工厂模式 简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。 2.工厂方法模式 工厂方法模式实现时,客户需要决定实例化哪一个工厂来决定产品类,判断选择的问题还是存在的,也就是说:工厂方法把简单工厂的内部逻辑判断移到了客户端代码来实现。你想要加功能,本来是修改工厂类的,而现在是修改客户端。
工厂方法模式的一般形式: 1. //定义工厂方法所创建的对象的接口 2. class Product 3. { 4. public:
5. void performance(); 6. }; 7. //具体的产品,实现 Product 接口 8. class ConcreteProduct : public Product 9. { 10. public: 11. } 12. //声明工厂方法,该方法返回一个 Product 类型的对象 13. class Creator 14. { 15. public: 16. virtural Product * Create() = 0; 17. } 18. //重定义工厂方法以返回一个 ConcreteProduct 实例 19. class ConcreteCreator : public Creator 20. { 21. public: 22. Product * Create() 23. { 24. return new ConcreteProduct(); 25. } 26. } 一个具体的工厂方法模式的实例: 1. #include <iostream> 2. using namespace std; 3. //志愿者 4. class volunteer 5. { 6. public: 7. void regular() 8. { 9. cout << "维持秩序" << endl; 10. } 11. void guid() 12. { 13. cout << "向导" << endl; 14. } 15. void help() 16. { 17. cout << "助人为乐" << endl; 18. } 19. }; 20. //大学生志愿者 21. class undergraduate : public volunteer 22. { 23. }; 24. //社会志愿者 25. class society : public volunteer 26. { 27. 28. }; 29. //抽象工厂(用来生产志愿者,虽然听起来很别扭,呵呵) 30. class factory 31. { 32. public: 33. virtual volunteer * CreateVolunteer() = 0; 34. }; 35. //具体工厂(用来生产大学生志愿者) 36. class undergraduatefactory : public factory 37. { 38. public: 39. volunteer * CreateVolunteer() 40. { 41. cout << "创建大学生志愿者:" << endl; 42. return new undergraduate(); 43. } 44. }; 45. //具体工厂(用来生产社会志愿者) 46. class societyfactory : public factory 47. { 48. public: 49. volunteer * CreateVolunteer() 50. { 51. cout << "创建社会志愿者:" << endl; 52. return new society(); 53. } 54. }; 55. int main()
56. { 57. factory * _afactory = new undergraduatefactory(); 58. volunteer * _avolunteer = _afactory->CreateVolunteer(); 59. _avolunteer->guid(); 60. factory * _bfactory = new societyfactory(); 61. volunteer * _bvolunteer = _bfactory->CreateVolunteer(); 62. _bvolunteer->regular(); 63. return 0; 64. }
[案例]
朋友从美国给我带回一个微波炉,但因为美国的生活用电电压是 110V,而中国的电压是 220V,所以我不能使用,幸好朋友有先见之明,给我带回一个变压器,能把 220V 电压转换成 110V 电压,我才可以放心使用了。 [意图]
把一个类的借口转换成客户端所期待的另一种接口,从而使原接口不匹配而无法在一起工作的两个类能在一起工作。本程序通过适配,使 c220 类能在 c110 类中使用。
程序代码: #include <iostream.h>
class c220v
{
public:
void DianYa220v()
{
cout<<"220v 电压!"<<endl;
}
};
class c110v
{
public:
virtual void DianYa110v()=0;
};
class adaper:public c110v
{
private:
c220v *c220obj;
public:
adaper(c220v* obj)
{
c220obj=obj;
}
void DianYa110v()
{
c220obj->DianYa220v();
cout<<"经变压器转换成"<<endl;
cout<<"110v 电压"<<endl;
}
};
int main()
{
c220v *c220vobj=new c220v;
adaper adobj(c220vobj);
adobj.DianYa110v();
return 1;
}
运行结果: 220v 电压!
经变压器转换成 110v 电压 Press any key to continue
案例分析: 一个普通的开关控制的电灯、电风扇等等,都是桥接的例子。开关的目的是将设备打开或关闭。实际的开关可以是简单的双刀拉链开关,也可以是调光开关。
意图: 桥接模式将抽象部分与它的实现分离,使它们能够独立地变化。案例中开关控制的对象和具体开关的类型都是可能变化的,本程序就将它们封装,具体的实现在起各自的派生类中完成。
结构图:
程序代码: #include <iostream.h>
//主要目的是为了将实现和抽象分离 //以下的类为实现部分,用来将实现分离出来class KaiGuan{public: virtual void open()=0; virtual void close()=0;};
class ShuanDaoKaiGuan: public KaiGuan{public: ShuanDaoKaiGuan() { cout<<"双刀开关!"<<endl; } void open() { cout<<"打开!"<<endl; } void close() { cout<<"关闭!"<<endl; }};
class DiaoGuangKaiGuan: public KaiGuan{public: DiaoGuangKaiGuan() { cout<<"调光开关!"<<endl; } void open() { cout<<"调节!"<<endl; } void close() { cout<<"关闭!"<<endl;
}};
//以下的类为抽象部分,通过引用实现的指针来为客户端提供接口class QJKG{public: KaiGuan *kgobj;
public: virtual void open()=0; virtual void close()=0;};
class QiaoJieKG: public QJKG{public: QiaoJieKG(KaiGuan* obj) { kgobj=obj; }
void open() { kgobj->open(); }
void close() { kgobj->close(); }};
//桥接模式的结构分成三部分//1.Client 也就是下面的主函数//2.Implementor 也就是上面的三个类(KaiGuan, ShuanDaoKaiGuan, DiaoGuangKaiGuan)//3.Abstraction 也就是上面的两个类(QJKG, QiaoJieKG)//这样做的结果就是当实现改变时,客户端并不需要做任何的改变 int main(){ QiaoJieKG *obj=new QiaoJieKG(new ShuanDaoKaiGuan); obj->open(); obj->close();
obj=new QiaoJieKG(new DiaoGuangKaiGuan); obj->open(); obj->close(); return 1;}
运行结果: 双刀开关!
打开!
关闭!
调光开关!
调节!
关闭!
Press any key to continue
案例分析: 每台汽车都要有发动机和轮胎等部件,但不同品牌的汽车所用的部件应该是不同的,汽车生产厂可以有不同的生产线,每个生产线负责生产某一型号的汽车部件。例如某厂有两条生产线,一条生产宝马的部件,一条生产宝莱车的部件。客户要买什么车,就启动相应的生产线。
意图: 提供一个创建一系列相关会相互依赖对象的接口,而无须制定他们具体的类。这里结合案例将创建两条生产线,分别生产宝马和宝莱汽车的轮胎和引擎。
结构图:
程序代码:
#include <iostream.h>
class LunTai
{
public:
virtual void display()=0;
};
class YinQing
{
public:
virtual void display()=0;
};
//
class BaoMaCarLunTai:public LunTai
{
public:
void display()
{
cout<<"宝马轮胎!"<<endl;
}
};
class BaoCaiCarLunTai:public LunTai
{
public:
void display()
{
cout<<"宝菜轮胎!"<<endl;
}
};
//
class BaoMaCarYinQing:public YinQing
{
public:
void display()
{
cout<<"宝马引擎!"<<endl;
}
};
class BaoCaiCarYinQing:public YinQing
{
public:
void display()
{
cout<<"宝菜引擎!"<<endl;
}
};
//
class CarFactory
{
public:
virtual LunTai* getCarLunTai()=0;
virtual YinQing* getCarYinQing()=0;
};
class BaoMaCarFactory:public CarFactory
{
public:
LunTai* getCarLunTai()
{
return new BaoMaCarLunTai;
}
YinQing* getCarYinQing()
{
return new BaoMaCarYinQing;
}
};
class BaoCaiCarFactory:public CarFactory
{
public:
LunTai* getCarLunTai()
{
return new BaoCaiCarLunTai;
}
YinQing* getCarYinQing()
{
return new BaoCaiCarYinQing;
}
};
int main()
{
BaoMaCarFactory BaoMaFactory;
BaoMaCarLunTai* BaoMaLunTai=(BaoMaCarLunTai*)BaoMaFactory.getCarLunTai();
BaoMaLunTai->display();
BaoMaCarYinQing* BaoMaYinQing=(BaoMaCarYinQing*)BaoMaFactory.getCarYinQing();
BaoMaYinQing->display();
BaoCaiCarFactory BaoCaiFactory;
BaoCaiCarLunTai* BaoCaiLunTai=(BaoCaiCarLunTai*)BaoCaiFactory.getCarLunTai();
BaoCaiLunTai->display();
BaoCaiCarYinQing* BaoCaiYinQing=(BaoCaiCarYinQing*)BaoCaiFactory.getCarYinQing();
BaoCaiYinQing->display();
return 1;
}
运行结果: 宝马轮胎!
宝马引擎! 宝菜轮胎! 宝菜引擎! Press any key to continue
案例分析: 工厂方法定义一个用于创建对象的接口,但是让子类决定实例化哪个类。压注成型演示了这种模式。塑料玩具制造商加工塑料粉,将塑料注入到希望形状的模具中。玩具的类别(车,人物等等)是由模具决定的。 意图: 它的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将创建的工作交给子类去做。这个核心类成为一个抽象工厂的角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类实例化的细节。 结构图:
程序代码: #include <iostream.h>
class cMaMoJu
{
public:
cMaMoJu()
{
cout<<"生产玩具马模具"<<endl;
}
};
class cCheMoJu
{
public:
cCheMoJu()
{
cout<<"生产模具车模具"<<endl;
}
};
class cWanJuGongChang
{
public:
void ZhiZaoWanJu()
{
MakeMoJu();
ZhuFen();
MeiHua();
}
protected:
virtual void MakeMoJu()=0;
virtual void ZhuFen()=0;
virtual void MeiHua()=0;
};
class cWanJuMaGongChang:public cWanJuGongChang
{
protected:
void MakeMoJu()
{
cMaMoJu obj;
}
void ZhuFen()
{
cout<<"给该模具注入材料,使其成形"<<endl;
}
void MeiHua()
{
cout<<"美化产品,完成产品生产"<<endl;
}
};
class cWanJuCheGongChang:public cWanJuGongChang
{
protected:
void MakeMoJu()
{
cCheMoJu obj;
}
void ZhuFen()
{
cout<<"给该模具注入材料,使其成形"<<endl;
}
void MeiHua()
{
cout<<"美化产品,完成产品生产"<<endl;
}
};
int main()
{
cWanJuGongChang* obj=new cWanJuMaGongChang;
obj->ZhiZaoWanJu();
cout<<endl;
obj=new cWanJuCheGongChang();
obj->ZhiZaoWanJu();
return 0;
}
运行结果: 生产玩具马模具 给该模具注入材料,使其成形 美化产品,完成产品生产
生产模具车模具 给该模具注入材料,使其成形 美化产品,完成产品生产 Press any key to continue
Flyweight享元设计模式是一种结构型设计模式,它主要解决的问题是:由于(同类)对象的数量太大,采用面向对象时给系统带来了难以承受的内存开销。比如有这样一个场景:一个停车场中有 1000辆汽车,我们所定义的汽车对象占用内存 0.3M,那么要实例化 1000辆就是 300M。由此可见,在这种情况下采用一般的面向对象方式出现了大量细粒度的对象会很快充斥在系统中,从而带来很高的运行是代价(这里指的代价是内存开销的代价)。 GoF《设计模式》中说道:运用共享技术有效的支持大量细粒度的对象。 案例分析 定义一个场景:有一个汽车类型,客户程序要实例化 20000 个,实例化后查看一下内存分配情况。 #include "stdafx.h"#include "windows.h"#include "iostream.h"#include <string>#include <list>#include <map>#pragma warning (disable: 4786)
/*class Car{ private: std::string Body; std::string Wheel; std::string Engine; std::string Brand; std::string Color; public: Car(std::string body,std::string wheel,std::string engine,std::string brand,std::string color) { Body = body; Wheel = wheel; Engine = engine; Brand = brand; Color = color; } }; int main(int argc, char* argv[]){ unsigned long MemCount = 0; MEMORYSTATUS MemInfo; MemInfo.dwLength = sizeof(MEMORYSTATUS); GlobalMemoryStatus(&MemInfo); cout << "内存分配情况如下:" << endl; MemCount = MemInfo.dwAvailVirtual; cout << "实例化前:" << MemInfo.dwAvailVirtual << endl; std::list<Car> m_list; for(int i = 0;i < 20000;i++) { Car * car = new Car("4.2M","Wheel","NeedForSpeed","BMW","Black"); //m_list.push_back(*car); } GlobalMemoryStatus(&MemInfo); cout << "实例化后:" << MemInfo.dwAvailVirtual << endl; cout << "实例化后:" << MemCount - MemInfo.dwAvailVirtual << endl; return 0;}*/ /*内存分配情况如下:实例化前:2140868608实例化后:2125139968实例化后:15728640*/
class CarBody{ private: std::string Body; std::string Wheel; std::string Engine; std::string Color; public: CarBody(){}; CarBody(std::string body,std::string wheel,std::string engine,std::string color) { Body = body; Wheel = wheel; Engine = engine; Color = color; }}; class FlyWeightCar{ public: std::string Brand; CarBody * carbody; public: FlyWeightCar(){};};
class FlyWeightFactory{ private: static FlyWeightCar * Car; static std::map<std::string,FlyWeightCar> table; public: static FlyWeightCar * CreateInit(std::string body,std::string wheel,std::string engine,std::string brand,std::string color) { FlyWeightCar * car = Car; if(brand.compare("BMW") == 0)
{ //car = &(FlyWeightCar)table[brand]; car = Car; } else { car->Brand = brand; car->carbody = new CarBody(body,wheel,engine,color); std::pair<std::string,FlyWeightCar> item (brand, *car); table.insert(item); } return car; }}; FlyWeightCar * FlyWeightFactory::Car = new FlyWeightCar(); std::map<std::string,FlyWeightCar> FlyWeightFactory::table; int main(int argc, char* argv[]){ unsigned long MemCount = 0; MEMORYSTATUS MemInfo; MemInfo.dwLength = sizeof(MEMORYSTATUS); GlobalMemoryStatus(&MemInfo); cout << "内存分配情况如下:" << endl; MemCount = MemInfo.dwAvailVirtual; cout << "实例化前:" << MemInfo.dwAvailPhys << endl; std::list<FlyWeightCar> m_list; for(int i = 0;i < 10000;i++) { FlyWeightCar * car = FlyWeightFactory::CreateInit("4.2M","Wheel","NeedForSpeed","Benz","Black"); //m_list.push_back(*car); } for(i = 0;i < 10000;i++) { FlyWeightCar * car = FlyWeightFactory::CreateInit("4.2M","Wheel","NeedForSpeed","BMW","Black"); //m_list.push_back(*car); } GlobalMemoryStatus(&MemInfo); cout << "实例化后:" << MemInfo.dwAvailPhys << endl; cout << "占用内存:" << MemCount - MemInfo.dwAvailVirtual << endl; return 0;}
/*内存分配情况如下:实例化前:328978432实例化后:324227072占用内存:7340032*/ 从数字上不难看出内存分配的容量节省了不少,而且随着数量的增加,差距会更大,当数量教少时,普通方式的内存分配更小一些,所以,在使用时,我们一定要对所实例化对象的个数进行评估,否则的话会适得其反。 Flyweight 模式的几个要点: 1、面向对象很好的解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight 设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。 2、Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象的状态处理。 3、对象的数量太大从而导致对象内存开销加大(这个数量要经过评估,而不能凭空臆断)
案例分析 小李想要看奥运会的比赛,这样的话,他必须提前订票,可以通过组委会定票,然后在规定的日子去取票,不光小李,所有的观众必须都通过这个途径订票。
意图 Proxy 代理模式是一种结构型设计模式,主要解决的问题是:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某
些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层
描述 为其他对象提供一种代理以控制对这个对象的访问。
程序 #include "stdafx.h"#include <iostream>
class audience{ public: audience(){}; virtual void preconcert() = 0;};
class xiaoli: public audience{public: xiaoli(){}; virtual void preconcert() { std::cout << "xiaoli preconcert ticket" << std::endl; }};
class ticketproxy: public audience{public: ticketproxy(xiaoli * _xiaoli) { pxiaoli = _xiaoli; } virtual void preconcert() { pxiaoli->preconcert(); } private: xiaoli * pxiaoli;};
int main(){ xiaoli * _xiaoli = new xiaoli; //a RealSubject ticketproxy _ticketproxy(_xiaoli); //代理 _ticketproxy.preconcert(); delete _xiaoli; return 0;}
运行结果: xiaoli preconcert ticket
案例分析: 一个支持在屏幕上绘图的类 View。一个视图只有在进入焦点状态后时才可以设定合适的特定绘图状态,因而只有成为“焦点”之后才可以进行绘图。View 类强制其子类遵循这个规则。我们用D isplay 模板方法来解决这个问题。View 定义两个具体方法,SetFocus 和 ResetFocus,分别设定和清除绘图状态。 View 的Dodisplay钩子操作实施真正的绘图功能。
意图: 定义一个操作中算法的框架,将一些步骤延迟到其子类中。这里就是将绘图的具体工作,延迟到 View 类的派生类中。
结构图:
程序代码: #include <iostream.h>
class View
{
public:
void Display()
{
// cout<<"模版方法定义算法框架"<<endl;
SetFocus();
Dodisplay();
ResetFocus();
}
void SetFocus()
{
cout<<"获得焦点"<<endl;
}
void ResetFocus()
{
cout<<"失去焦点"<<endl;
}
virtual void Dodisplay()
{
cout<<"基类绘图函数"<<endl;
}
};
class FlashView:public View
{
public:
void Dodisplay()
{
cout<<"实现 falsh绘图"<<endl;
}
};
class PhotoShopView:public View
{
public:
void Dodisplay()
{
cout<<"实现 photoshop绘图"<<endl;
}
};
int main()
{
View* pview=new FlashView;
pview->Display();
pview=new PhotoShopView;
pview->Display();
return 1;
}
运行结果: 获得焦点 实现 falsh绘图 失去焦点 获得焦点 实现 photoshop绘图 失去焦点 Press any key to continue
案例分析: 我们去超市买东西,会收到购物小票,上面是你购买的物品名称、数量、单价及总价等信息,以及购物时间,收银员号码等最基本的信息,这些是基本不变的。不过有时超市还会在这张票据的上面或下面打印其他信息,例如:欢迎辞、促销广告等,而且这些信息的内容及打印位置也不固定,相当于是对购物小票的额外装饰了。 意图: 为一个对象动态连接附加的指责。根据案例,本程序可为购物小票动态添加各种抬头和注释。 描述: 装饰模式是一种对象结构型模式,这种模式主要用于对象 结构图:
程序代码: #include <iostream.h>
class cxiaopiao
{
public:
virtual void DaYinXiaoPiao()=0;
};
class cjutixiaopiao:public cxiaopiao
{
public:
void DaYinXiaoPiao()
{
cout<<"票据正文"<<endl;
}
};
class czhuangshixiaopiao:public cxiaopiao
{
protected:
cxiaopiao* xpobj;
public:
czhuangshixiaopiao(cxiaopiao* obj)
{
xpobj=obj;
}
virtual void DaYinXiaoPiao()=0;
};
class header1xiaopiao:public czhuangshixiaopiao
{
public:
header1xiaopiao(cxiaopiao* obj):czhuangshixiaopiao(obj){}
void DaYinXiaoPiao()
{
cout<<"抬头 1"<<endl;
xpobj->DaYinXiaoPiao();
}
};
class header2xiaopiao:public czhuangshixiaopiao
{
public:
header2xiaopiao(cxiaopiao* obj):czhuangshixiaopiao(obj){}
void DaYinXiaoPiao()
{
cout<<"抬头 2"<<endl;
xpobj->DaYinXiaoPiao();
}
};
class footer1xiaopiao:public czhuangshixiaopiao
{
public:
footer1xiaopiao(cxiaopiao* obj):czhuangshixiaopiao(obj){}
void DaYinXiaoPiao()
{
xpobj->DaYinXiaoPiao();
cout<<"脚注 1"<<endl;
}
};
class footer2xiaopiao:public czhuangshixiaopiao
{
public:
footer2xiaopiao(cxiaopiao* obj):czhuangshixiaopiao(obj){}
void DaYinXiaoPiao()
{
xpobj->DaYinXiaoPiao();
cout<<"脚注 2"<<endl;
}
};
int main()
{
czhuangshixiaopiao* xiaopiao=new header1xiaopiao(new footer2xiaopiao(new footer1xiaopiao(new cjutixiaopiao)));
xiaopiao->DaYinXiaoPiao();
cout<<endl;
xiaopiao=new header1xiaopiao(new header2xiaopiao(new footer1xiaopiao(new footer2xiaopiao (new cjutixiaopiao))));
xiaopiao->DaYinXiaoPiao();
return 0;
}
运行结果: 抬头 1
票据正文 脚注 1
脚注 2
抬头 1
抬头 2
票据正文 脚注 2
脚注 1
Press any key to continue