在财产中强制执行适当价值的可接受方式是什么,这取决于同一类别的其他财产?

Yon*_*ahW 3 .net c# oop properties

假设我有一个具有以下三个属性的类.

public class Travel
{
  public int MinAirportArrival { get; set; }
  public int MinFlightTime { get; set; }
  public int TotalTravelTime { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

TotalTravelTime必须至少是MinAirportArrival和MinFlightTime的总和,但如果有中途停留或类似的事情,也可能更多.

我很清楚,我可以将逻辑放在TotalTravelTime的setter中.

我的问题是关于更改MinFlightTime和MinAirportArrival.是否期望TotalTravelTime首先增加,如果没有,当其中一个人将总和大于TotalTravelTime时抛出异常?

我以合理的方式控制这个的其他选择是什么?

我应该将此保留给负责保存状态的对象以检查类上的有效属性吗?我也可能有其他逻辑.

编辑
我没有存储额外时间的任何数量,如果有的话,这不仅仅是添加一些属性的问题.仅仅澄清这个课程只是我面临的问题的一个人为的例子,但我认为它很好地匹配问题.

dtb*_*dtb 7

框架设计指南建议属性不应相互依赖. 始终可以按任意顺序设置多个属性的值.

以下是可以看到的选项:

  1. 在这个特定情况下:

    public class Travel
    {
      public int MinAirportArrival { get; set; }
      public int MinFlightTime { get; set; }
      public int AdditionalTravelTime { get; set; }
      public int TotalTravelTime
      {
        get { return MinAirportArrival + MinFlightTime + AdditionalTravelTime; }
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这利用了可以从其他三个值重建 TotalTravelTime的效果,这三个值可以在没有依赖性的情况下进行单独设置.

  2. 一般情况的解决方案是接受任何值并在例如将实例发送到存储时验证值.

    public class Travel
    {
      public int MinAirportArrival { get; set; }
      public int MinFlightTime { get; set; }
      public int TravelTime { get; set; }
      public void Save()
      {
        // validate TravelTime > MinAirportArrival + MinFlightTime 
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 另一个选项是使属性为只读,并提供批量更新属性值的方法.

    public class Travel
    {
      public int MinAirportArrival { get; private set; }
      public int MinFlightTime { get; private set; }
      public int TravelTime { get; private set; }
      public void UpdateTimes(
        int minAirportArrival, int minFlightTime, int travelTime)
      {
        // validate travelTime > minAirportArrival + minFlightTime 
        MinAirportArrival = minAirportArrival;
        MinFlightTime = minFlightTime;
        TravelTime = travelTime;
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 或者,您可以使Travel对象不可变,并使用构造函数,工厂方法或可变构建器对象来创建实例.

    构造函数:

    public class Travel
    {
      public Travel(int minAirportArrival, int minFlightTime, int travelTime)
      {
        // validate travelTime > minAirportArrival + minFlightTime 
      }
      public int MinAirportArrival { get; }
      public int MinFlightTime { get; }
      public int TravelTime { get; }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    工厂方法:

    public class Travel
    {
      public static Travel CreateTravel(
        int minAirportArrival, int minFlightTime, int travelTime)
      {
        // validate travelTime > minAirportArrival + minFlightTime 
        return new Travel(minAirportArrival, minFlightTime, travelTime);
      }
      private Travel(int minAirportArrival, int minFlightTime, int travelTime);
      public int MinAirportArrival { get; }
      public int MinFlightTime { get; }
      public int TravelTime { get; }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    Builder类:

    public class TravelBuilder
    {
      public int MinAirportArrival { get; set; }
      public int MinFlightTime { get; set; }
      public int TravelTime { get; set; }
      public Travel BuildTravel()
      {
        // validate TravelTime > MinAirportArrival + MinFlightTime 
        return new Travel(MinAirportArrival, MinFlightTime, TravelTime);
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    可以在.NET框架中找到所有三个选项的示例.