首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用策略模式重构代码

使用策略模式重构代码
EN

Stack Overflow用户
提问于 2012-07-11 14:48:54
回答 4查看 1.1K关注 0票数 0

我有一个GiftCouponPayment课程。它有一个可以频繁更改的业务策略逻辑- GetCouponValue()。目前的逻辑是“当优惠券数小于2000时,优惠券价值应视为零”。在未来的商业策略中,它可能会改变为“当优惠券发行日期小于1/1/2000时,优惠券价值应被视为零”。它可以根据公司的管理部门转变成任何这样的战略。

如何使用策略模式重构GiftCouponPayment类,以便在GetCouponValue方法的策略时不需要更改该类?

UPDATE:在分析职责之后,我觉得"GiftCoupon“将是"GiftCouponPayment”类的一个更好的名称。

C#代码

代码语言:javascript
复制
    public int GetCouponValue()
    {
        int effectiveValue = -1;
        if (CouponNumber < 2000)
        {
            effectiveValue = 0;
        }
        else
        {
            effectiveValue = CouponValue;
        }

        return effectiveValue;
    }

阅读

  1. Strategy Pattern - multiple return types/values
EN

回答 4

Stack Overflow用户

发布于 2012-07-11 15:02:37

GiftCouponPayment类应该将GiftCoupon传递给不同的策略类。因此,您的策略接口(CouponValueStrategy)应该包含一个方法:

int getCouponValue(GiftCoupon giftCoupon)

由于实现CouponValueStrategy的每个具体策略都可以访问GiftCoupon,所以每个策略都可以实现基于优惠券号或优惠券日期等的算法。

票数 3
EN

Stack Overflow用户

发布于 2012-07-11 15:07:58

您可以将“优惠券值策略”注入优惠券对象本身,并调用它计算优惠券值。在这种情况下,将this传递到策略中是可以接受的,以便策略可以要求优惠券获得其所需的属性(例如优惠券号):

代码语言:javascript
复制
public interface ICouponValuePolicy
{
  int ComputeCouponValue(GiftCouponPayment couponPayment);
}

public class GiftCouponPayment
{
  public ICouponValuePolicy CouponValuePolicy {
    get;
    set;
  }

  public int GetCouponValue()
  {
    return CouponValuePolicy.ComputeCouponValue(this);
  }
}

而且,你的GiftCouponPayment似乎真的要负责两件事(付款和礼券)。提取包含CouponNumberCouponValueGetCouponValue()CouponNumber类并从GiftCouponPayment中引用它可能是有意义的。

票数 3
EN

Stack Overflow用户

发布于 2012-07-11 15:07:28

当您的业务逻辑发生变化时,您的代码也会发生更改,这是非常自然的。

您也许可以选择将过期检测逻辑移到规范类中:

代码语言:javascript
复制
    public class CouponIsExpiredBasedOnNumber : ICouponIsExpiredSpecification
    {

        public bool IsExpired( Coupon c )
        {
             if( c.CouponNumber < 2000 )
                 return true;
             else
                  return false;
        }
    }

    public class CouponIsExpiredBasedOnDate : ICouponIsExpiredSpecification
    {
       public readonly DateTime expirationDate = new DateTime (2000, 1, 1);

       public bool IsExpired( Coupon c )
        {
             if( c.Date < expirationDate )
                 return true;
             else
                  return false;
        }
    }

public class Coupon
{
     public int GetCouponValue()
     {
        ICouponIsExpiredSpecification expirationRule = GetExpirationRule();

        if( expirationRule.IsExpired(this) ) 
           return 0;
        else
           return this.Value;

     }
}

你应该问自己的一个问题:现在有必要让它变得如此复杂吗?你不能让它尽可能的简单,以满足当前的需求,并在过期规则确实改变之后重构它吗?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11435320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档