最新评论
Re:设计模式随笔-用奶箱订报纸 风筝blog 2012-02-15 09:57
观察者模式,如果不用委托(或事件)实现的话,会非常清楚、不易混乱而且易于理解,但是不善变化(比如楼主示例);而如果用委托的话,可变性大大增加,而且实现简单化了许多,可是容易产生误解(比如,楼主的邻居看到奶箱,可能会误认为里面一定是牛奶。。。),我个人感觉,如果一般情况的话,可以仅使用观察者模式就OK了,如果需要很多类(比如,楼主家有报纸箱、牛奶箱、信件箱等等)使用委托就比较简单了(不需要定义很多接口)。
谢谢楼主!
Re:设计模式随笔-发大米喽 风筝blog 2012-02-14 16:44
#14楼“所谓拉模式是指观察者在响应消息通知时从被观察者那里"拉"出所需要的信息;而推模式是指被观察者在通知观察者时就把所需要的信息"推"过去.”,这种说法挺绕的,不过挺好的,易于理解。
但是感觉“观察者”(Teacher)不应该占有“被观察者”(private GongHui g;)的引用,因为这样就有种“拉模式”的感觉了,而且,如果每个“观察者”都有“被观察者”的引用,也就是可以访问“被观察者”的公共方法,如果有一个“观察者”不小心调用并修改了“被观察者”的状态(比如:RiceArrived(int n)。。。),就会引起混乱。
而当教工领到米后必须要把工会中米的数量-1,所以我觉得,应该“观察者”(教工)和“被观察者”(工会)之间应该通过一个“桥”来连接,使用“桥接模式”,让“观察者”只得到需要的信息!
然后解决刚才的工会米数量-1的问题,可以这样解决:教工中引用一个“桥”接口对象,然后注册给“桥”,而“桥”的另一边连接着工会(怎么连接就不说了),当工会来米了,通过“桥”通知给所有“注册过的”教工,然后教工得到信息后,来领米(教工的私有方法),当领米时,又通知了“桥”,进而通知了工会,工会中米的数量-1。
这样可以避免“被观察者”透露过多的信息给“观察者”,这样比较安全。
以上只是个人看法,希望正确。感谢楼主!
Re:设计模式随笔-锦囊妙计 风筝blog 2012-02-14 16:02
#19楼,楼主说的链接不见了,#9楼说的“赵云似乎在模式中的身份更应该是 involker ”,我觉得不妥,在楼主上面的例子中并没有显示指出谁是“请求者”,我个人认为,是从“三国剧情”或者“命令模式”上来说,诸葛亮(ZhuGeLiang)更像一个请求者,只不过这个请求者又自己制作了3条命令,而赵云是一个接受者,因为他是“执行命令”的人,突然发现楼主的代码中“命令”仅仅是“String字”而已,没有起到“命令模式中命令”的作用,不知道自己理解对不对,因为按照“命令模式”,“命令”应该可以接受“请求者”的请求,还可以“执行接受者”的方法,作为一个“解耦”的桥梁,所以感觉这个例子不太妥当,不过对于理解“命令模式”真的很有帮助!感谢楼主!
#6楼楼主说得很好,是有可能自己改变了东西也需要通知自己(比如发邮件,没有预览,有时也需要给自己发一份。。。)。
观察者模式,是“被观察者角色所知道的只是一个具体现察者聚集,每一个具体现察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。”,可以在另一个角度说“实现了表现层和逻辑层的分离”,我感觉这是一种创新的模式,有别于其他模式,原来的思想是:客户想知道对象状态,自己需要访问,然后得到相应的状态(因信息有时效性,所以有时得到的信息不准确),而观察者模式恰恰将这种模式翻转了过来!让“变化”本身去通知对“变化”感兴趣的对象,个人感觉这是一种新的思维。谢谢楼主!
@xglu
你可以添加一个方法,用来以集合的方式来添加、删除观察者,不过楼主在下面“观察者模式的缺点”中已经说了,如果被观察对象有很多观察者的话,全部通知到需要占用很多时间,这就需要自己平衡了。哈哈,自己理解的。
在下面的情况下应当考虑使用命令模式:
1、使用命令模式作为"CallBack"在面向对象系统中的替代。"CallBack"讲的便是先将一个函数登记上,然后在以后调用此函数。
2、需要在不同的时间指定请求、将请求排队。一个命令对象和原先的请求发出者可以有不同的生命期。换言之,原先的请求发出者可能已经不在了,而命令对象本身仍然是活动的。这时命令的接收者可以是在本地,也可以在网络的另外一个地址。命令对象可以在串形化之后传送到另外一台机器上去。
3、系统需要支持命令的撤消(undo)。命令对象可以把状态存储起来,等到客户端需要撤销命令所产生的效果时,可以调用undo()方法,把命令所产生的效果撤销掉。命令对象还可以提供redo()方法,以供客户端在需要时,再重新实施命令效果。
4、如果一个系统要将系统中所有的数据更新到日志里,以便在系统崩溃时,可以根据日志里读回所有的数据更新命令,重新调用Execute()方法一条一条执行这些命令,从而恢复系统在崩溃前所做的数据更新。
5、一个系统需要支持交易(Transaction)。一个交易结构封装了一组数据更新命令。使用命令模式来实现交易结构可以使系统增加新的交易类型。
----------------------------------------------
看了好久,终于明白了“接受者”(比“接收者”感觉要更好些)和请求者、命令对象的区别和联系,命令模式是把“简单”的事搞“复杂”了,不过“复杂”后,便于降低耦合(分离)、追踪和审计,还有可以实现“事务”回滚操作,真的很强大,但是怕用错了地方,所以引用楼主的“命令模式使用环境”,感谢楼主!
“责任链模式并不创建责任链。责任链的创建必须由系统的其它部分创建出来。”这句话是不是说责任链模式只是起到指导作用,不想一些模式一样,需要创建管理者或者种种接口?责任链比较简单,目的就是为了更方便的解决客户问题,至于纯与不纯,讨论也没有什么意义。谢谢老师~~~
http://www.cnblogs.com/zhenyulu/articles/67016.html
楼主的另一篇:蜡笔和毛笔的故事 将桥接模式的一个好处和使用原则体现了出来,非常易于理解。大家可以看看~~
Re:设计模式随笔-蜡笔与毛笔的故事 风筝blog 2012-02-13 17:09
的确对于入门来说挺好的一个例子,桥接模式的精髓是:将抽象和实现分离,用组合代替继承。不过,现在觉得只理解了2成,8成还没有理解。加油!谢谢楼主!
门面模式也就是外观模式了,就是相当于总管家,管理很多事情,可以让整个庭院看成一个人,外面的人就可以直接同一个人接触了,也好像购票窗口,可以出售火车票、飞机票还有客车票,都是同一个窗口,给顾客节省了很多麻烦~~
我觉得享元模式是归类总结,这当然需要很多要求,比如系统不要求识别每一个对象,对象的状态成员等是可以共享的,没有被改变的部分,至于享元模式的外蕴部分,我觉得是应用的时候添加的,和享元模式的本身意义没有太大的关系。享元模式一是有需求(很多对象,很多资源消耗),二是对象可以共享(不会被改变)。谢谢老师。
Re:痛苦的选择:不再只专注于技术 风筝blog 2012-02-10 16:13
不知道写什么好了,顶一下!
代理模式自己独到的特点或功能是:使客户端可以通过访问代理对象来获得被代理对象的功能,可以将代理对象和被代理对象看成一个对象,而且本质没有变化(没有添加另外的许多成员和方法等等)。代理对象可以做很多事情来完成一定的目的:方便、实时、快捷、计数等等,可能其中的一些功能和其他模式相仿或相同,但是出发点不同,这是最大的区别!谢谢老师。
个人感觉装饰模式或者包裹模式和继承没有太大关系,包裹模式更多的好处在于:可以在各个平行类之间自由组合(#17楼),而且可能只是一点两点的修改,如果继承的话,需要考虑很多(比如层次、可访问性等等),而且包裹模式可以不访问被装饰类,可以扩展已有代码,换句话:has-a比is-a要好!老师在六、2优点:“通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合”说得很好!
我的理解:适配器模式应该是为了和现有或者将来的(代码)设计保持一致或者是使之具有统一的标准,而对现有代码的改造工作,可能也有“如虎添翼”的效果。
看完了原型模式,感觉不是很懂,不知道是原型模式本身很复杂还是我给想复杂了,说说我的理解。
原型模式简言之就是克隆一个对象,这种需求可能是由于以下原因:
1、新建一个对象需要花费很大的资源和时间或者太过繁琐(如:远程调用);
2、无法创建一个完全相同的对象(如上面评论所说:只有父类或者已有对象的指针,由于隔离无法访问原类);
3、没有必要创建一个全新对象。
原型模式需要一个原型实体(可能有上层的抽象类或接口),这个原型实体必须有clone()方法或者其他可以得到复制对象的方法,以返回一个完全相同对象。
也可有原型管理器来管理原型,不过仅仅起到管理的作用和原型模式不太相关。
总觉得和单例模式有所联系,但是又讲不清楚。。。
完整的看了,将自己对于建造者模式的理解写下来。
建造者模式主要是为了分步骤完成对象(产品)的建造工作,而且可以建造出不同类型的对象,一般包括指导者(Director)、建造者(ConcreteBuilder)和对象(产品)。
一般有一个抽象建造者类,说明建造对象需要的不同工序,而实际的建造工作是由实体建造者(实现抽象建造者)来完成的,而实体建造者不止一个,如一个车模(图纸-抽象)说明了车需要的建造工序(如:建造框架、建造轮子、喷漆和调试等等),而具体的建造者可以有自行车建造者、摩托车建造者和汽车建造者等等,而用户只知道自己想要自行车,并不知道如何建造,所以请求指导者帮忙,指导者接受一个(抽象)建造者对象,然后按照次序(如:先安装框架,然后喷漆,再然后安装车轮,最后调试)来建造车,最终返回给用户一个产品(自行车)。
Re:设计模式(15)-Facade Pattern Dufresne 2012-02-02 20:33
形似……到神似。。。
Re:Windows Mobile 数独游戏及全部源码 mopengpeng 2012-02-02 16:59
谁有吕老师的联系方式?我有急事请教他。如果知道麻烦告诉我一下,感激不尽。我的联系QQ45525444
Re:设计模式随笔-蜡笔与毛笔的故事 wenwei 2012-01-09 15:36
这个例子很好
Re:C#设计模式(1) kxhappy 2012-01-09 11:39
吕老师,没想到做课设的时候找到了您的博客,期待下学期的课~O(∩_∩)O
突然间发现大部分设计模式就是用对象之间的关系代替框架级的if else...
Re:痛苦的选择:不再只专注于技术 CV_2010 2012-01-05 18:59
难得遇到讨论这么多的帖子,顶一个吧!
Re:笔迹鉴别(2) —— 纹理制作 CV_2010 2012-01-05 18:44
看着文字切割的效果,真舒服啊。。。。
BinarySerialize和BinaryDeserialize<T> :
[code=csharp]
public static void BinarySerialize(object obj, Stream stream)
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
}
public static T BinaryDeserialize<T>(Stream stream) where T : class
{
IFormatter formatter = new BinaryFormatter();
object obj = formatter.Deserialize(stream);
if (obj is T)
{
return obj as T;
}
else
{
Type type = typeof(T);
throw new Exception(string.Format ("反序列化后不能得到类型{1}",type.Name));
}
}
[/code]
一直在学习,从未应用过!
也许自己写过的代码和某个设计模式相似,然而自己全然不知,哈哈!!
记得《.net组件程序设计》中讲序列化一章提到可用序列化Clone对象,应该如下,贴出来大家看看:
[code=csharp]
/// <summary>
/// 利用序列化克隆对象
/// </summary>
/// <typeparam name="T">对象的类型</typeparam>
/// <param name="source">原对象</param>
/// <returns></returns>
public static T Clone<T>(T source) where T : class
{
if (typeof(T).IsSerializable)
{
using (Stream stream = new MemoryStream())
{
BinarySerialize(source, stream);
T clone = BinaryDeserialize<T>(stream);
return clone;
}
}
else
{
throw new Exception(string.Format ("不能用序列化的方式克隆类型为{0}的对象",typeof(T).Name));
}
}
[/code]
Re:你真的了解Ioc与AOP吗?(1) 头文字C 2012-01-04 12:33
楼主画图用的什么工具啊?
Re:痛苦的选择:不再只专注于技术 unsigned 2011-12-27 17:08
博主不是真的喜欢技术,只是喜欢技术或者任何能带来“成功”的东西而已。既然如此,就去追逐“成功”吧,何苦庸人自扰,和技术纠缠在一起。你要的是成功,是金钱和地位以及成就感,如此而已,没什么不好的。
Re:C#设计模式(1) Spring枫 2011-12-22 21:12
学习ing
Re:你真的了解Ioc与AOP吗?(1) TSAPI 2011-11-11 13:06
我在想,其实IOC,和AOP应该就是设计模式的一种融合,它归属于设计模式。
刚看了下IOC,AOP,有装饰模式,工厂模式。
老师写的文章比书本的容易懂多了。谢谢,我会继续关注。
Re:小议数据库主键选取策略(原创) 海南.胡勇 2011-11-04 10:48
这是一个长期值得争论的问题,对于大数据量的确是必须考虑的问题。
我在实际工作中,上面的几种方式都使用过,不同的系统要求不一样,不同的表要求也不一样,不一定必须按某个方式来!
但总的来说,在存储过程中实现事务自增的方式效率还是高一些,但对Db复制,DTS等则带来很大的不便。
GUID也是我们常用的方式,对于效率问题到是有一定影响,因此最后我们采用了用建表缓存ID,给ORACLE一样的干法。
分析到位,这是一个需一生去不断探索的过程。没有定论!
Re:笔迹鉴别(1) —— 实现步骤概述 hailong 2011-10-16 06:15
很好!
Re:C#设计模式(1) 柚子5 2011-10-07 21:54
@caca
这个要看i的初始值
Re:窗体间传递复杂数据 莫为然 2011-09-15 12:00
非常不错!
学习了。
Re:C#设计模式(3) tie_v 2011-07-25 16:52
人过留声
Re:再次提升“华容道自动求解”程序效率 linxz123abc 2011-07-25 02:26
仔细看了你的4Byte表示法,思路我和的编码方式基本相同,这个值正如"sumtec"所说的可以用来做Hash值,再加用红黑树存储这个Hash值用于判重.红黑树虽然不是平衡树,但总体的效率要比AVLTree高.它的插入时间复杂度比AVLTree好.
Re:再次提升“华容道自动求解”程序效率 linxz123abc 2011-07-25 01:03
经典布局:横刀立马(81步)我用的时间是0.125秒,据说有人用C++用的时间更少,不知道是真是假,也不知道我的程序换成C++是不是和他一样快.
Re:再次提升“华容道自动求解”程序效率 linxz123abc 2011-07-25 00:58
你的这个布局,我用的时间是0.218秒
语言: java
数据结构: 红黑树
布局的编码: 自定义的编码(只涉及移位,位或运算和赋值运算),每个布局对应唯一的一个32bits的整数,不用Hash值.
电脑主频(双核):2.21G
欢迎交流, Email: lin123@tom.com
Re:设计模式(16)-Bridge Pattern theoffspring 2011-07-14 15:47
最后一个例子举得不好吧,怎么能说切换了DataObject后,客户端代码不用改呢,啥都不改,怎么可能实现切换.比如DO从数据库改成文件系统的存储,应该再实现一个业务对象和一个文件DO,这时候客户端就要实例化这个文件业务对象,如:FileBO,如果你用spring,当然可以把实例化放在配置文件里去弄,就是控制反转/依赖注入.都得改,只不过是换个地方而已.
这个分词结果为什么和ictclals的分词结果不一样呢?
人名识别效果也不好,是哪里的问题呢?
博主能不能给点指点呦?
Re:你真的了解Ioc与AOP吗?(4) whwqs 2011-07-01 23:12
都这么多年了!
Re:你真的了解Ioc与AOP吗?(4) whwqs 2011-07-01 23:12
吴老师现在在干啥呢?