public class BindingConstraint
{
public bool Constraint(ServiceEndpoint endpoint)
bool flag = false;
switch (endpoint.Binding.Name)
case "BasicHttpBinding":
//check the BasicHttpBinding;
flag = true;
break;
case "NetTcpBinding":
//check the NetTcpBinding;
case "NetPeerTcpBinding":
//check the NetPeerTcpBinding;
//...Other bindings' constraint;
}
return flag;
private static BindingConstraint m_bindingConstraint = BindingConstraintFactory.CreateConstraint();
public void AddServiceEndpoint(ServiceEndpoint endpoint)
if (m_bindingConstraint.Constraint(endpoint))
m_endpointsList.Add(endpoint);
posted on 2008-02-17 16:48 张逸 阅读(3070) 评论(17) 编辑 收藏 网摘 所属分类: Design & Pattern
职责链设计模式和管道架构模式是不是有些联系呢,帖子内容我还没看,先问个问题。 回复 引用 查看
不喜职责链, 用最简单的Strategy加工厂不是照样实现吗? 开销还低. 只要一出现可以乱序switch的地方, 其实就可以说职责链不是最适合的方式了. 因为其模型实际上是:信息1 -> 过程或对象一信息2 -> 过程或对象二....这样的形式. 看你如下代码:对象一:if (变量 == "信息一")对象二:if (变量 == "信息二")......这是什么? 这就是重复. 所以虽然得到了可以扩展的好处, 但还可以说是为了模式而模式.有话直说, LZ无怪 :). 回复 引用 查看
支持怪怪观点。感觉有点“小题大做”了 回复 引用 查看
@怪怪在本文的场景中,其实并不适用于策略模式,因为他缺少自我判断自我寻找合适对象的功能,通过职责链模式可以比较好地解决这一问题。你可以试试。至于你说的重复,我也不赞成你的意见。实际上,如果仔细分析,你会发现虽然每个对象中都包含了if语句,并对变量进行了判断,但判断的值是不一样的,即使提取为参数,要进行方法重构也很困难。设计时,不可能说要将所有类似的代码都定义为重复。至少,在这样的场景下,我不认为是为模式而模式。 回复 引用 查看
有争议就好,大家可以发表意见,但前提是应基于本文所提到的场景。 回复 引用 查看
@张逸 每个Constraint都有几乎完全相同的if逻辑,其实再Template Method一下会好一些。 回复 引用 查看
还是没看懂。 回复 引用 查看
@Jeffrey Zhao 恩,我也觉得此处还可以用Template Method 回复 引用 查看
怪怪,我看了原文,我觉得你前面那两个对代码的优化做的很不错,我暂时没想到这样改了以后会有哪些不足之处,你想了多久想到的?:)另外,我对原文的出揣测,似乎还包含了这样一层意思,我直接用Switch来表达switch (endpoint.Binding.Name){case "BasicHttpBinding": Constraint1(); Constraint2(); Constraint3(); case "NetTcpBinding": Constraint1(); Constraint3();break;case "NetPeerTcpBinding": Constraint1(); Constraint2();break;//...Other bindings' constraint;}如果 原文 “当分支条件存在扩展的可能时”,指的是这类情况时,那么存在一种链表或集合来存储这些不同的约束集合应该也无可厚非了。不过除非 每个分支基本上要对所有约束都走一遍,否则以我个人的习惯,我不会只建一条链表,因为速度在当前硬件下可能不会有太大的感觉,但是空耗太多终究不太美观。我可能更倾向于选择表驱动+链表结合/或是 在binging对象中储存相应的链表对象,不过表驱动+链表可能对象重用性更好一些,不知道是否有更好一些的方法?另外,其实Flyweight人似乎有一点点表驱动的感觉吧:) 回复 引用
好吧,按照怪怪所说,我们采用策略模式和工厂来实现。假定我们为每个绑定建立一个策略对象,抽象类型为BindingConstraintStrategy。至于工厂,为了简化起见,我们直接用简单工厂实现即可,工厂方法的参数仍然考虑使用ServiceEndpoint。我想经过这样的实现后,那么在客户端代码中,应该是这样来调用://注意,此处不能通过工厂来创建m_constraint的具体对象,因为一旦创建完毕,就限制了m_constraint只能为其中某个绑定的约束检查对象。private static BindingConstraintStrategy m_constraint;public void AddServiceEndpoint(ServiceEndpoint endpoint){ //只能在这里面创建具体对象 m_constraint = Factory.Create(endpoint); if (m_Constraint.Constraint(endpoint)) { m_endpointsList.Add(endpoint); }}注意这段代码与我的文章中客户端代码的区别。在AddServiceEndpoint()方法中出现了对象的创建,这种设计是否合理呢?如果不仅仅是该方法需要检查绑定的约束,那么就会在多个地方出现调用工厂的逻辑。这种实现方式与职责链的区别,是因为它无法智能的识别和判断,以找到准确的对象。实际上,这两种实现方式并无太多的所谓轻量级与重量级的区别,不过坦白说,在性能上,职责链的消耗还是要稍微大一些了。如Jeffery Zhao所说,如果约束对象确实存在一些公有的逻辑,那么引入Template Method,确实不错。 回复 引用 查看
@张逸 楼主。。怪怪说的很有道理。。你客户端只需要用到BindingConstraint里的Constraint方法的话又何须用工厂来创建对象呢。。用一个Executor使用字典来选择具体调用方法不是更好吗。。这样就可以智能识别和判断了撒。。^^ 回复 引用
@m j部分同意你的意见。这里实际上是一个选择的问题。如你所说,采用字典来选择就可以实现智能识别和判断,那么实际上这一过程仍然需要封装成一个单独的类来实现,也就近似于工厂了。关键不在于这点,而是因为采用这种方法的话,那么在客户端调用时,并不能事先创建BindingConstraint对象,而是在需要约束对象时,根据参数的值从字典中去寻找。虽然寻找的过程在职责链中也存在,但职责链将这一寻找过程自身抽象到了BiindingConstraint对象中,因而代码上会简略一些。我们只需要在一处创建整条职责链即可。如果采用策略模式,就需要每次去调用对应的工厂,来智能生成或寻找准确的对象。这两者之间的区别,从我前面的评论中列出的代码可以得到比较。采用策略模式,是不可能将在字典中查找的实现逻辑抽象到策略基对象中。不过除了获得这一个优点,策略模式结合工厂的方式是要比职责链模式来得直观与简洁一些,我必须得承认这一点。 回复 引用 查看
@张逸 客户端的代码还是一样简洁的撒。。因为字典又并不是由客户端来实现对吧。。 我觉得从解决具体问题来看你的方法完全可以接受没有任何问题。。要在这里讨论性能和可读性带来的影响几乎就是扯淡。。可怪怪说的关键的一点是你用的这种方法或许可以叫做什么什么链。。但确实不能简单的叫做“责任链模式”。。这个概念用在这里不够准确就会误导初学者哈。。 你是让我认识设计模式的启蒙老师之一。。当初舍书本而学习你们的博客就是因为我买的那本模式的书完全没解释清楚各种模式之间的区别和关键点。。让我越看越混淆。。而你现在也是能影响不少人的大师了。。不知道知识掌握得越多是否越觉得自己不足。。总之不妨就技术的问题多多讨论。。理是越辩越清。。期待你更多的好文章。。 回复 引用
@m j很喜欢我们这种讨论,不过别给我戴高帽子哦,这样我可受不起,因为这样我的责任可就大了。首先我要申明一点,本文的实现绝对是职责链模式的实现,这是毋庸置疑的,而且我也不怕误导初学者,因为我的这个实现是正确的。所谓“职责”,其实就是为每个绑定进行约束性检查的职责而已。实际上我和怪怪有分歧的是,在本文描述的场景下,是使用职责链模式好,还是使用其他方式,例如策略模式。另,看来你没有仔细看清楚我在评论中所说,我并不否认关于字典的操作一定不会由客户端来完成,我也表达了这个意见,而是认为为了便于客户端调用,如果采用策略模式,那么关于字典的操作应该封装在专门的工厂类中,但绝对不应该放到策略对象本身中,作为它的一个职责。我只觉得如果采用这种方式,客户端的代码虽然不复杂,但如果多处涉及到对绑定约束的检查,就可能出现调用工厂方法创建策略对象的重复代码。因为,采用策略模式,即使使用字典来查找相应的策略对象,该策略对象的创建仍然是要根据客户端调用时的ServiceEndpoint来决定的。如果使用职责链模式,这一判断自身就放在职责链对象中了,因而客户端可以免去这一个操作。 回复 引用 查看
@张逸 Sorry。。楼主是不是还没看过怪怪的这篇文章(http://www.cnblogs.com/guaiguai/archive/2008/02/18/1071753.html)。。看你写的“好吧,按照怪怪所说”以为是看到这篇文章后写的。。 回复 引用
@m j呵呵,幸得你的提醒,我才知道怪怪另外写了一篇文章。我在那篇文章之后留了言。谢谢! 回复 引用 查看
初学者 路过 `学习上有问题我会提出来喜欢各位前辈门多多指点. 回复 引用
昵称: [登录] [注册]
主页:
邮箱:(仅博主可见)
验证码: 看不清,换一个
评论内容:
登录 注册
[使用Ctrl+Enter键快速提交评论]
《软件设计精要与模式》
《WCF服务编程》