(转载)Visitor模式---实现家人行为 http://hi.baidu.com/huangrg/blog/item/aa9e46c7feaeebdfd100608c.html
来源:互联网 发布:网络共享没有权限访问 编辑:程序博客网 时间:2024/05/17 08:31
我考虑写一个程序模拟她们的生活.
抽象出老婆,儿子和女儿这三个对象,为了易于统一管理和访问这些对象,同时抽象了一些公共基类:Baby.Baby要提供所有可能的接口. 为了把问题简单化,假设老婆主要照顾两个小宝贝和做家务(^-^); 两个小宝贝还小,基本上就是玩.于是我们建立下面的类模型:
根据这个模型,我们可以发现一些不足的地方:
1)抽象接口提供所有子类的行为接口
抽象基类Baby为Wife,Son和Daughter提供了所有的接口,显得比较复杂。
2)子类必须要重写不属于自己的行为
比如儿子比较小,是不参与家务的,但在程序中,Son必须重写Housework(),只是什么都不做。当然,通过某些方式可以避免这问题出现,但同时也会带来其它新问题。
3)增加新的行为比较烦琐
在任何一个类中增加一个新行为,就要在所有的类中做修改。比如,小孩上小学了,老婆不须要照顾小孩了,要上班;同时儿子可能还要踢足球,女儿要课余要学唱歌、舞蹈等。系统不易扩展,增加新功能容易出错;而且会越来越复杂,不易维护。
有必要对设计进行优化,使系统更易扩展和维护。注意以上类结构的特点:Wife、Son、Daughter,这此元素比较稳定;但她们的行为容易变化。
因此我们很自然想到了采用Visitor,建立下面的类模型:
采用Visitor模式重新设计后,基本上消除了以上的不足之处。特别是要增加一个新行为,只要在Visitor层次增加一个新类,不会使系统越来越复杂。下面是针对采用Visitor后的代码实现。
说明:1)代码实现里的Visitor成员函数通过重载机制统一用Visit命名;
2)为编排简单,所有成员函数定义在类声明里实现.
以下是Visitor层次的代码:
struct Visitor
{
virtual void Visit(Wife& wife) = 0;
virtual void Visit(Son& son) = 0;
virtual void Visit(Daughter& daughter) = 0;
};
class BabysatVisitor : public Visitor
{
public:
virtual void Visit(Wife& wife)
{
std::cout << "Wife is taking care of son and daughter./n";
}
virtual void Visit(Son& son){ }
virtual void Visit(Daughter& daughter){ }
};
HouseworkVisitor也是针对Wife的一个动作,实现和BabysatVisitor类似,略。
class PalyVisitor : public Visitor
{
public:
virtual void Visit(Wife& wife){ }
virtual void Visit(Son& son)
{
std::cout << "Son is playing./n";
}
virtual void Visit(Daughter& daughter)
{
std::cout << "Daughter is playing./n";
}
};
以下元素层次的代码:
struct Baby
{
virtual void Accept(Visitor& visitor) = 0;
};
class Wife : public Baby
{
public:
virtual void Accept(Visitor& visitor)
{
visitor.Visit(*this);
}
};
Son和Daughter用同样的方法实现Accept,略.
最后用Family管理她们。
class Family
{
public:
typedef std::multimap<Baby*, Visitor*> BabyMap;
Family()
{
babies_->insert(BabyMap::value_type(new Wife, new WifeVisitor));
babies_->insert(BabyMap::value_type(new Son, new SonVisitor));
babies_->insert(BabyMap::value_type(new Daughter, new DaughterVisitor));
}
void Behave()
{
for (BabyMap::const_iterator it = babies_.begin(); it != babies_.end(); ++it)
it->first->Accept(*it->second);
}
private:
BabyMap babies_;
};
主函数类似:
Family family;
family.Behave();
最后要说明的, 如果经常娶老婆或者经常有小宝宝出生的话,也就说像Wife这些节点容易变化的话, 使用Visitor模式不一定能带来多少好处.
- (转载)Visitor模式---实现家人行为 http://hi.baidu.com/huangrg/blog/item/aa9e46c7feaeebdfd100608c.html
- (转载)Decorator模式---实现一个验证程序 http://hi.baidu.com/huangrg/blog/item/76fe53ddb58169da8d1029c6.html
- 转载——CRC校验C语言实现http://hi.baidu.com/fudi850/blog/item/2465a2c2d5f2591a0ff477bb.html
- http://hi.baidu.com/heyg/blog/item/9ca8dcc4785706cb38db4937.html
- http://hi.baidu.com/suwey/blog/item/9b4d72c238e7e334e5dd3bc0.html
- http://hi.baidu.com/lhcling/blog/item/0e3e60cfa55aca3ef8dc61c0.html
- http://hi.baidu.com/jmugis/blog/item/ad03b11f89a25ef6e1fe0b18.html
- http://hi.baidu.com/nnffnn/blog/item/e84cd15c1d893943faf2c07c.html
- http://hi.baidu.com/herowzz/blog/item/286e3c546eb23157574e0077.html
- http://hi.baidu.com/kacaca/blog/item/1fd412d644f9f42907088b89.html
- http://hi.baidu.com/sophie198384/blog/item/26960501e9a757021d9583a0.html
- http://hi.baidu.com/123az/blog/item/f482f51980e8e04642a9ad6c.html
- http://hi.baidu.com/zonesky/blog/item/328d9807043c2ccb7a894717.html
- http://hi.baidu.com/shasha1918/blog/item/ee5fdf18f049fc0235fa4187.html
- http://hi.baidu.com/620734263/blog/item/513a102fa4a551424ec226f8.html
- http://hi.baidu.com/jisu3d/blog/item/f7ad4fd0ac727526960a1652.html HLSL
- http://hi.baidu.com/jsjlx2004/blog/item/74409ccbd5741619be09e6a1.html
- http://hi.baidu.com/edeed/blog/item/3e92277f7a15830028388aec.html
- ajax_javascript解析xml
- asp.net用url重写URLReWriter实现任意二级域名
- datatable,dataview和datagrid中一些容易混淆的概念
- 最小带宽
- 辛苦的杀毒历程(!--_--!)
- (转载)Visitor模式---实现家人行为 http://hi.baidu.com/huangrg/blog/item/aa9e46c7feaeebdfd100608c.html
- 在spring中关于CP30数据库连接池使用oracle数据库是存储blog对象出错的问题
- (转载)Decorator模式---实现一个验证程序 http://hi.baidu.com/huangrg/blog/item/76fe53ddb58169da8d1029c6.html
- Applet
- 各大公司电子类招聘题目精选 [转]
- WEBIM1.3上线了
- Linux下网络传输测速程序小记
- 个人空间1.3版下周一测试.
- 从模拟字符串型的枚举说起 [C#]