锁定老帖子 主题:OO design trap
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-12-27
buaawhl 在前面说过:OO 多态的作用就是用来消除 hard coded logic branch (if, else, switch)。
但是重新审视OO设计2、3,虽然使用了多态,switch却并没有完全消失,hard coded logic branch只是被归并、转移。 再考察Quake Wang的Script,hard coded logic branch被转移到script上面: "if(member.point > 5) return 0.05; else return 0.02;" 而T1的CO呢,情况也大致相同;if(m.get_type().trim().equals("金卡")) return m.set_discount(discount+10); ajoo的map和bind机制倒真是让hard coded logic branch从代码里面消失了。 好东西不怕抄,为OO设计3增加map机制,将switch彻底清除。 // member class Member { string type; string gender; public Member GetMember(string id);; public string[] GetPropertyList(); { string[] list = new string[2]; list[0] = "type"; list[1] = "gender"; return list; } public string GetValueByName(string property_name); { switch(property_name); { case "type": return type; case "gender": return gender; } } } // stragetys class member_strategys { Hashtable m_strategys = null; static protected Initialize(); { if(m_strategys == null); { m_strategys = new Hashtable();; InitStrategys();; } } static protected InitStrategys(); { m_strategys.Add("type.金卡", new golden_strategy);; m_strategys.Add("type.银卡", new silver_strategy);; m_strategys.Add("gender.女", new female_strategy);; } static public ArrayList GetStrategys(Member member); { Initialize();; ArrayList strategy_list = new ArrayList();; string[] name_list = member.GetPropertyList();; foreach(string name in name_list); { string data = member.GetValueByName(name);; string map = name + "." + data; if(m_strategys.Contains(map); strategy_list.Add(m_strategys[map]);; } } } map机制的使用相当于为系统增加自动匹配策略的功能,意味着对象系统开始从静态设计向动态设计靠拢,那么我们是不是可以认为,号称"everything is component"的CO,从另一个角度来看实际上是MO,"mechanism Oriented",单独的component是没有意义的,由components所构成的mechanism才是价值所在。 |
|
返回顶楼 | |
发表时间:2005-12-27
T1 写道 此map非彼map HashMap vs FP Map 操作? T1 写道 ajoo 那个map是一个操作阿 和hashmap有啥关系 就是给你一个操作,然后一个表。map(op,list) it will go through the list with applying the op on each element of list ,then return the list consisted by the result. |
|
返回顶楼 | |
发表时间:2005-12-27
计算器可以描述成
计算动作 => 计算动作 where 条件 在给出的计算数据中,系统可能同时有多个计算动作符合条件,这个时候该怎么选择,人工或是计算器本身定义优先级? |
|
返回顶楼 | |
发表时间:2005-12-27
附件是我的方案。
我认为系统中应该建立的对象模型应该是折扣的对象模型,因为它导致了所有的变化,因此应该对折扣进行OO化处理,这样就得到了几种正交的折扣计算方式(也就是“元折扣”的概念): 卡折扣 性别折扣 日期折扣 生日折扣 年龄折扣 剩下的都是他们的组合。 |
|
返回顶楼 | |
发表时间:2005-12-28
什么需求对应什么设计。在目前这个简单需求下面强求给出弹性的设计不太实际也并不经济。
|
|
返回顶楼 | |
发表时间:2005-12-28
ajoo 写道 什么需求对应什么设计。在目前这个简单需求下面强求给出弹性的设计不太实际也并不经济。
不要光说不练呀,更复杂的需求无非发展成这样:标准等级discount + conditional discount + 自选优惠套餐组合,并且这些策略有可能是排它性的,比如说有这样一个conditional discount:如果会员本月累计购买额超过10万,那么本月后续消费一律给予20%的折扣,更复杂的情形是,如果排它性折扣实际上比其他组合获得的折扣更低,那么应该取消排它性折扣而选取其他组合。 如果觉得还不够复杂,大可以自己补充吧,把你的弹性设计拉出来溜溜,是骡是马还说不准呢。 |
|
返回顶楼 | |
发表时间:2005-12-28
buaawhl 写道 T1 写道 此map非彼map HashMap vs FP Map 操作? T1 写道 ajoo 那个map是一个操作阿 和hashmap有啥关系 就是给你一个操作,然后一个表。map(op,list) it will go through the list with applying the op on each element of list ,then return the list consisted by the result. FP Map?map(op, list)好象跟需求完全相反了吧,这些折扣op基本上都是独立的,不需要对任何list元素进行操作。 |
|
返回顶楼 | |
发表时间:2005-12-28
明确下一阶段需求:
折扣方案主要分为三大类: 1. 会员等级折扣,会员等级是最重要的分类,大部分方案都会在等级上面作文章,所以单独归为一类 2. 条件型折扣,只有在符合特定条件下才会发生的折扣,比如前面针对女性会员节日的折扣 3. 货物优惠折扣,这些方案根据货物制定,举个例子:客户单独买电视或音响不会有任何折扣,一起买则会得到5%的折扣,电视+音响+DVD组合更会得到7%的折扣。 在一般情况下,这些折扣方案所产生的折扣是累加的(1+2+3),但是不排除其他可能性,例如2中可能出现的排它性条件折扣,也就是说这些折扣方案有可能会出现相对复杂的组合关系。 |
|
返回顶楼 | |
发表时间:2005-12-28
age0 写道 明确下一阶段需求:
折扣方案主要分为三大类: 1. 会员等级折扣,会员等级是最重要的分类,大部分方案都会在等级上面作文章,所以单独归为一类 2. 条件型折扣,只有在符合特定条件下才会发生的折扣,比如前面针对女性会员节日的折扣 3. 货物优惠折扣,这些方案根据货物制定,举个例子:客户单独买电视或音响不会有任何折扣,一起买则会得到5%的折扣,电视+音响+DVD组合更会得到7%的折扣。 在一般情况下,这些折扣方案所产生的折扣是累加的(1+2+3),但是不排除其他可能性,例如2中可能出现的排它性条件折扣,也就是说这些折扣方案有可能会出现相对复杂的组合关系。 Decorator public interface Payment { double pay();; } class AllPayment implements Payment { private double original; AllPayment(double original); { this.original = original; } public double pay(); { return original; } } class GoldPayment implements Payment { private Payment base; GoldPayment(Payment base); { this.base = base; } public double pay(); { double result = 0; // 根据base.pay();计算result return result; } } // 银... // 铜... class SpecialPayment implements Payment { private Payment base; SpecialPayment(Payment base); { this.base = base; } public double pay(); { double result = 0; // 根据base.pay();计算result return result; } } class CompositePayment implements Payment { private Payment base; CompositePayment(Payment base); { this.base = base; } public double pay(); { double result = 0; // 根据base.pay();计算result return result; } } // client public static void main(String[] args); { double original = 100; // 金 + 货物组合 + 特殊 Payment myPayment = new SpecialPayment( new CompositePayment(new GoldPayment( new AllPayment(original););););; myPayment.pay();; } |
|
返回顶楼 | |
发表时间:2005-12-28
age0 写道 明确下一阶段需求:
折扣方案主要分为三大类: 1. 会员等级折扣,会员等级是最重要的分类,大部分方案都会在等级上面作文章,所以单独归为一类 2. 条件型折扣,只有在符合特定条件下才会发生的折扣,比如前面针对女性会员节日的折扣 3. 货物优惠折扣,这些方案根据货物制定,举个例子:客户单独买电视或音响不会有任何折扣,一起买则会得到5%的折扣,电视+音响+DVD组合更会得到7%的折扣。 在一般情况下,这些折扣方案所产生的折扣是累加的(1+2+3),但是不排除其他可能性,例如2中可能出现的排它性条件折扣,也就是说这些折扣方案有可能会出现相对复杂的组合关系。 Composite public interface Payment { double pay(double original);; } class DiscountCalculator implements Payment { private List discounts = new LinkedList();; public double pay(double original); { double result = original; for (Iterator i = discounts.iterator();; i.hasNext();;); { Payment discount = (Payment); i.next();; result = discount.pay(result);; } return result; } public void add(Payment discount); { discounts.add(discount);; } } class GoldDiscount implements Payment { public double pay(double original); { double result = 0; // 根据original计算result return result; } } // 银... // 铜... class SpecialDiscount implements Payment { public double pay(double original); { double result = 0; // 根据original计算result return result; } } class CompositeDiscount implements Payment { public double pay(double original); { double result = 0; // 根据original计算result return result; } } // client public static void main(String[] args); { double original = 100; // 金 + 货物组合 + 特殊 DiscountCalculator calculator = new DiscountCalculator();; calculator.add(new GoldDiscount(););; calculator.add(new CompositeDiscount(););; calculator.add(new SpecialDiscount(););; calculator.pay(original);; } |
|
返回顶楼 | |