锁定老帖子 主题:OO design trap
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-06-30
第一感觉:Member就不应该有GetDiscount方法。即使有,也会随着规则的变化演变成代理。也就是说,Member本身,实际上无须存在GetDiscount方法。
这个例子充分说明了贫血的合理性。贫血的目的就是降低耦合。 本问题的描述: 应用层能够获得Member的Discount和ReturnPoint。 获得Discount的ReturnPoint的规则是易变的。 会员的等级也是易变的。会员信息的结构,也有可能发生变化。 本问题的目标: 隔离上述变化,使客户(类库的使用者)无需修改代码适应这三种变化。 设计: interface IMember{ //可以加入确认不变的field } interface IDiscountStrategy{ double getDiscount(IMember member);; } interface IReturnPointStrategy{ double getReturnPoint(IMember member);; } class StrategyEntry{ IDiscountStrategy getDiscountStrategy(IMember);; IReturnPointStrategy getReturnPointStrategy(IMember);; } 客户调用代码: double discount=StrategyEntry.getDiscountStrategy(IMember);.getDiscount(IMember);; double returnPoint=StrategyEntry.getReturnPointStrategy(IMember);.getReturnPoint(IMember);; 由于discount和returnPoint的规则可能不同,所以不应该耦合。否则就可能会产生更多的组合。 规则如何产生,那是实现时期的事情。但是要保证客户端代码不变,这是最基本的设计要求。 在实现时,可以在StrategyEntry里面使用各种方法来获得具体的策略,可以很简单,也可以很复杂,可以视情况而定。但是此设计是另外一个问题,已经被本设计分割。与本问题无关。 本解答完全能实现预期目标。 解答完毕。 本设计可以作为Dip的一个注释。 |
|
返回顶楼 | |
发表时间:2006-07-09
我认为实际到目前为止,大家讨论的是两个问题:
1. 如何对分级别的用户信息进行建模。 2. 如何实现复杂的促销折扣策略。 对第一个问题,一般来说,金卡用户,银卡用户属于基本的,长期的用户分类。它们所对应的折扣率一般也属于长期有效的。其它折扣策略往往带有时效性,也就是说在一段时间内(促销活动期间)有效。因此,前者是可以建模在领域模型中的。但是,楼主给出的三种方法都不好,即当增加用户类别或改变类别折扣率时都要改程序。我的设计是这样的: class Member { private MemberType type; } class MemberType { private String code; private BigDecimal discountRate; } MemberType的信息,也就是金卡和银卡用户的折扣率是应该配置在master table里的。所以不需要继承,更不需要switch。 至于复杂促销折扣策略的实现,不要管什么模式,AOP了,规则引擎才是王道。 |
|
返回顶楼 | |
发表时间:2007-01-05
看到最近,BirdGu说的很在理。
用户本身没有差别,差别在他们持有的卡,所以,卡是变化点。 那么就去在卡上做文章。折扣或是其它的促销活动,谁的变化由谁去负责,问题就简单一些。 |
|
返回顶楼 | |
发表时间:2007-01-14
考虑了用户升级吗? 用state pattern可以解决对分级别的用户信息进行建模, 也就是实现用户和卡的分离。
|
|
返回顶楼 | |
发表时间:2007-01-15
最后一种也很一般。策略模式远好得多。优先考虑组合而非继承。
|
|
返回顶楼 | |
发表时间:2007-04-22
interface IMember
{ public String getType(); public void setType(String type); public boolean changeType(String type); } interface IGoods { public void setDiscount(double discount); public double getDiscount(); public void setReturnPoint(double returnpoint); public double getReturnPoint(); } public class Members implements IGoods { public static IMember getMember(long memberid) { ...... } public static double getDiscount(IMember member,IGoods goods) { ......... } public static double getReturnPoint(IMember member,IGoods goods) { ......... } } |
|
返回顶楼 | |
发表时间:2007-04-22
update IGoods interface
interface IGoods { public void setDiscount(double discount); public double getDiscount(); public boolean changeDiscount(double discount); public void setReturnPoint(double returnpoint); public double getReturnPoint(); public boolean changeReturnPoint(double returnpoint); } |
|
返回顶楼 | |