论坛首页 Java企业应用论坛

OO design trap

浏览 55137 次
锁定老帖子 主题: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的一个注释。
0 请登录后投票
   发表时间:2006-07-09  
我认为实际到目前为止,大家讨论的是两个问题:
1. 如何对分级别的用户信息进行建模。
2. 如何实现复杂的促销折扣策略。

对第一个问题,一般来说,金卡用户,银卡用户属于基本的,长期的用户分类。它们所对应的折扣率一般也属于长期有效的。其它折扣策略往往带有时效性,也就是说在一段时间内(促销活动期间)有效。因此,前者是可以建模在领域模型中的。但是,楼主给出的三种方法都不好,即当增加用户类别或改变类别折扣率时都要改程序。我的设计是这样的:
class Member {
    private MemberType type;
}

class MemberType {
    private String code;
    private BigDecimal discountRate;
}

MemberType的信息,也就是金卡和银卡用户的折扣率是应该配置在master table里的。所以不需要继承,更不需要switch。

至于复杂促销折扣策略的实现,不要管什么模式,AOP了,规则引擎才是王道。
0 请登录后投票
   发表时间:2007-01-05  
看到最近,BirdGu说的很在理。
用户本身没有差别,差别在他们持有的卡,所以,卡是变化点。
那么就去在卡上做文章。折扣或是其它的促销活动,谁的变化由谁去负责,问题就简单一些。
0 请登录后投票
   发表时间:2007-01-14  
考虑了用户升级吗? 用state pattern可以解决对分级别的用户信息进行建模, 也就是实现用户和卡的分离。
0 请登录后投票
   发表时间:2007-01-15  
最后一种也很一般。策略模式远好得多。优先考虑组合而非继承。
0 请登录后投票
   发表时间: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)
   {
       .........
   }
}
0 请登录后投票
   发表时间: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);

}
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics