用于反向访问逻辑更改的模式

本文关键字:模式 访问 用于 | 更新日期: 2023-09-27 18:03:08

我试图找到一个设计模式或最佳实践,或一些其他解决方案的问题,保持在我的应用程序中的业务逻辑的版本。具体来说,我正在寻找一种方法来确定使用了哪种逻辑来签发保险单。

我现在的代码看起来像这样:

public double FixedDeductibleSurchageAmount()
{
    double percent = FixedDeductibleSurchargePercent();
    double base_premium = CollisionPremium() + TheftPremium();
    return (base_premium * percent);
}

我需要更改业务逻辑,使此功能看起来更像:

public double FixedDeductibleSurchageAmount()
{
    double percent = FixedDeductibleSurchargePercent();
    double base_premium = CollisionPremium() + TheftPremium() + MedicalPremium();
    return (base_premium * percent);
}

我遇到的问题是,现有的政策应该与先前的逻辑进行评级。这有什么设计模式吗?如果没有,有什么好的方法来实现它吗?

用于反向访问逻辑更改的模式

策略模式听起来最适用。您可能需要一个工厂方法或其他类似的方法来接收日期以返回适当的策略。

你将不得不使用某种形式的额外数据来跟踪精确的算法是用来获得你的数据;您可能需要更改持久性表示,以维护用于派生结果的算法的版本控制信息。

顺便说一句,您可以考虑将MedicalPremium或TheftPremium之类的东西设置为仅可获取的属性,而不是无参数函数。他们非常符合这种模式。

有很多方法可以解决这个问题。一些例子:

1)切换到新代码并向用户数据添加一个标志,以便MedicalPremium对老用户自动返回0。如果您将数据存储在XML中,这将特别容易;旧的数据不会有这个标志,而且它不会影响数据的反序列化,因为XML是灵活的。

2)将包含MedicalPremium函数的类设置为基类,并将MedicalPremium设置为虚类。在派生类(即新版本)中重写它。较新的用户是派生类。旧用户被创建为基类。对于老用户,它总是返回0。属性也可以像函数一样是虚的。

如果您有机会看一下Martin Fowler的《企业架构模式》,他谈到了个体实例方法,这与您所拥有的并不完全相同,但非常相似。无论如何,这是一本伟大的书。

同时,我认为你可能不得不开始考虑你的函数也是数据,并在你的数据库中存储哪个函数被使用。您不需要(但可能想要)存储函数文本,但是您确实需要足够的信息来在运行时确定要调用哪个方法。你问的是模式,显然你在这里有一个策略模式,你可以参考,但我不知道它是否特别有用。

是的,有:Decorator Pattern。您可以使用它来使用其他包装器类来扩展类的行为。在下面的示例中,我将其与模板方法模式结合起来,以实现我相信您正在寻找的内容。

public class BaseSurchargePolicy {
    protected abstract double BasePremium { get; }
    protected abstract double FixedDeductibleSurchargePercent { get; }
    public double FixedDeductibleSurchageAmount{
      get
      {
        return (BasePremium * FixedDeductibleSurchargePercent);
      }
    }
    protected ICollection<string> _ProcessorsUsed;
    public IEnumerable<string> ProcessorsUsed 
    { 
      get { return ProcessorsUsed; }
    }
}
public class OldSurchargePolicy : BaseSurchargePolicy 
{
    protected double BasePremium 
    { 
        _ProcessorsUsed.Add(GetType().Name);
        return CollisionPremium + TheftPremium; 
    }
    protected double FixedDeductibleSurchargePercent { get; set; }
    public double CollisionPremium { get; set; }
    public double TheftPremium { get; set; }
}
public class MedicalSurchargeDecorator: BaseSurchargePolicy
{
    private BaseSurchargePolicy _wrapped;
    private double _medicalPremium;
    public MedicalSurchargeDecorator(BaseSurchargePolicy wrapped, double medicalPremium) 
    {
        _wrapped = wrapped;
        _medicalPremium = medicalPremium;
    }
    protected double BasePremium 
    { 
      get 
      {
        _ProcessorsUsed.Add(GetType().Name);
        return _wrapped.BasePremium + _medicalPremium; 
      }
    }
    protected double FixedDeductibleSurchargePercent { 
      get { return _wrapped.FixedDeductibleSurchargePercent }
    }
}