您的位置:首页 > 其它

【设计模式】穿什么有这么重要? --- 装饰模式

2012-06-22 23:05 411 查看
一,定义

英文名字:Decorator Pattern,又称装饰者模式。

装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

二,总结

装饰模式什么时候实用?

当系统需要新功能的时候,向旧的类中添加新的代码,而新的代码装饰了原有类的核心职责或主要行为。

如果在主类中添加新的字段,新的方法和新的逻辑,从而增加了主类的复杂度。而这些新添加的类仅仅是满足特定情况的特殊需要。

解决方案:装饰模式,把每个要装饰的功能放在单独的类中,并让这个类包装它要装饰的对象,因此要执行特殊行为时,客户端可以在运行时候有顺序,有选择的装饰包装对象。

三,例子

取自大话设计模式,小菜穿衣服。根据所穿不同衣服,穿衣服的顺序分析一个人风格?内裤内穿是普通人,内裤外穿是超人。

1)小菜扮靓第一版

下面程序,通过控制台可以完成扮靓的基本衣服类型。

缺点:

如果要增加 “超人” 的装扮(内裤外穿),怎么办?

更改Person 类就违背了 开放 - 封闭原则,如何优化呢?把服饰写成子类,方便扩展衣物子类。

#include <iostream>
using namespace std;

class Person
{
private:
string name;
public:
Person(string Iname)//最好和 name 区分(不要再采用name)
{
name = Iname; //name没有this
}
~Person(){}
void WearTShirts()
{
cout<<"t恤"<<endl;
}
void WearBigTrouser()
{
cout<<"垮裤"<<endl;
}
void WearSneakers()
{
cout<<"破球鞋"<<endl;
}
void WearSuit()
{
cout<<"西装"<<endl;
}
void WearTie()
{
cout<<"领带"<<endl;
}
void WearLeaterShoes()
{
cout<<"皮鞋"<<endl;
}

void show()
{
cout<<"装扮的"<<this->name<<endl;
}

};

int main()
{
Person xiaocai("小菜"); //没有new的创建对象方法
cout<<"第一种装扮"<<endl;

xiaocai.WearTShirts();
xiaocai.WearBigTrouser();
xiaocai.WearSneakers();
xiaocai.show();

Person *daniu =new Person("大牛"); //没有new
cout<<"第二种装扮"<<endl;

daniu->WearSuit();
daniu->WearTie();
daniu->WearLeaterShoes();
daniu->show();

return 0;
}


2)小菜扮靓第二版

改进:增加了Finery 服饰抽象类,和各种具体服饰子类,方便了扩展各种服饰子类,而不必更改Person类,符合开放--封闭原则。

缺点:要显示穿的什么,还得在客户端dtx.show() //显示t恤 , kk.show() //显示垮裤。相当于光着身子在大庭广众之下穿衣服,如何改进?

要内部组装完毕,然后显示出穿的什么来。这个貌似建造者模式(但是建造者模式要求建造过程是稳定的,这里可以内穿西装外套t恤)

#include <iostream>
using namespace std;

class Person
{
public:
Person(string name)
{
m_Name = name;
};

void Show(void)
{
cout << "装扮的"<< m_Name <<endl;
};
private:
string m_Name;
};

class Finery//服饰抽象类
{
public:
virtual void Show(void) = 0;
};

class TShirts :public Finery
{
public:
void Show(void)
{
cout << "大T恤" <<endl;
};
};

class BigTrouser :public Finery
{
public:
void Show(void)
{
std::cout << "垮裤" <<endl;
};
};

class Sneakers :public Finery
{
public:
void Show(void)
{
cout << "破球鞋" <<endl;
};
};

class Suit :public Finery
{
public:
void Show(void)
{
cout << "西装" <<endl;
};
};

class Tie :public Finery
{
public:
void Show(void)
{
cout << "领带" <<endl;
};
};

class LeatherShoe :public Finery
{
public:
void Show(void)
{
cout << "皮鞋" << endl;
};
};

int main()
{
Person* xiaocai = new Person("小菜");
Finery* dtx = new TShirts();
Finery* kk = new BigTrouser();
Finery* pqx = new Sneakers();

dtx->Show();
kk->Show();
pqx->Show();
xiaocai->Show();
return 0;
}


3)小菜扮靓第三版

结构:Person类需要穿衣服,让抽象装饰类继承Person类。然后继承抽象服饰类,初始化服饰子类。

改进:相对于第二版,可以先将衣服穿好 (装饰过程)



Sneakers* pqx = new Sneakers();

BigTrouser* kk = new BigTrouser();

TShirts* dtx = new TShirts();

pqx->Decorator(xiaocai);

kk->Decorator(pqx);

dtx->Decorator(kk);



然后再显示出来 dtx.show()

#include <string>
#include <iostream>

class Person
{
public:
Person(std::string name)
{
m_name = name;
};
virtual void Show(void)
{
std::cout << "装扮的" << m_name << std::endl;
};
Person(){};
private:
std::string m_name;
};

//服饰类
class Finery :public Person
{
public:
void Decorator(Person* comp)
{
this->m_pComponent = comp;
};

void Show(void)
{
if (m_pComponent != NULL)
{
m_pComponent->Show();
}
};
protected:
Person* m_pComponent;
};

//具体服饰类
class TShirts :public Finery
{
public:
void Show(void)
{
std::cout << "大T恤" << std::endl;
Finery::Show();
}
};

class BigTrouser :public Finery
{
public:
void Show(void)
{
std::cout << "垮裤" << std::endl;
Finery::Show();
};
};

class Sneakers :public Finery
{
public:
void Show(void)
{
std::cout << "破球鞋" << std::endl;
Finery::Show();
};
};

class Suit :public Finery
{
public:
void Show(void)
{
std::cout << "西装" << std::endl;
Finery::Show();
};
};

class Tie :public Finery
{
public:
void Show(void)
{
std::cout << "领带" << std::endl;
Finery::Show();
};
};

class LeatherShoe :public Finery
{
public:
void Show(void)
{
std::cout << "皮鞋" << std::endl;
Finery::Show();
};
};

int main()
{
Person* xiaocai = new Person("小菜");
std::cout << "第一个装扮" << std::endl;

Sneakers* pqx = new Sneakers();
BigTrouser* kk = new BigTrouser();
TShirts* dtx = new TShirts();

pqx->Decorator(xiaocai);
kk->Decorator(pqx);
dtx->Decorator(kk);
dtx->Show();

std::cout << "第二个装扮" << std::endl;
LeatherShoe* px = new LeatherShoe();
Tie* tie = new Tie();
Suit* suit = new Suit();
px->Decorator(xiaocai);
tie->Decorator(px);
suit->Decorator(tie);
suit->Show();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: