【问题标题】:desigining the domain model - need help设计领域模型 - 需要帮助
【发布时间】:2010-06-28 18:40:34
【问题描述】:

我知道发生了什么以及为什么它会抛出错误(它没有找到 GetBrokenRules 方法,因为它的列表)但我在这里发布这个问题的原因是要求更好的设计,有人可以在这里指导我吗?

我正在学习设施类(列表..../Building/Floor)

错误:

错误 3“System.Collections.Generic.List”不包含“GetBrokenRules”的定义,并且找不到接受“System.Collections.Generic.List”类型的第一个参数的扩展方法“GetBrokenRules”(是您缺少 using 指令或程序集引用?)

错误 >>> else if (Campus.GetBrokenRules().Count > 0)

有没有更好的方法来设计我的 GetBrokenRules() ?

ICampus、IBuilding、IFloor 由以下组成

public interface ICampus
    {
        List<BrokenBusinessRule> GetBrokenRules(); 
        int Id { get; }
        string Name { get; }
    }

public interface IFacilities 
{
    List<BrokenBusinessRule> GetBrokenRules();
    List<ICampus> Campus { get; }
    List<IBuilding> Building { get; }
    List<IFloor> Floor { get; }  
}


public class Facilities : IFacilities 
    {
        private List<ICampus> _campus;
        private List<IBuilding> _building;
        private List<IFloor> _floor;  

        public List<ICampus> Campus
        {
            get { return _campus; }
        } 

        public List<IBuilding> Building
        {
            get { return _building; }
        }

        public List<IFloor> Floor
        {
            get { return _floor; }
        } 

        public Facilities(List<ICampus> campus, List<IBuilding> building, List<IFloor> floor)
        {
            _campus = campus;
            _building = building;
            _floor = floor; 
        } 

        public  List<BrokenBusinessRule> GetBrokenRules()
        {
            List<BrokenBusinessRule> brokenRules = new List<BrokenBusinessRule>(); 

           if (Campus == null)
                brokenRules.Add(new BrokenBusinessRule("Facility Campus", "Must have at least one Campus"));
            else if (Campus.GetBrokenRules().Count > 0)
            {
                AddToBrokenRulesList(brokenRules, Campus.GetBrokenRules());
            }

            if (Building == null)
                brokenRules.Add(new BrokenBusinessRule("Facility Building", "Must have at least one Building"));
            else if (Building.GetBrokenRules().Count > 0)
            {
                AddToBrokenRulesList(brokenRules, Building.GetBrokenRules());
            }

            if (Floor == null)
                brokenRules.Add(new BrokenBusinessRule("Facility Floor", "Must have at least one Floor"));
            else if (Floor.GetBrokenRules().Count > 0)
            {
                AddToBrokenRulesList(brokenRules, Floor.GetBrokenRules());
            }       
    }
} 

【问题讨论】:

    标签: c# model dns


    【解决方案1】:
    public  List<BrokenBusinessRule> GetBrokenRules()
    {
        var brokenRules = new List<BrokenBusinessRule>(); 
    
       // null is not possible because Campus is supplied in the constructor
       if (!Campus.Any())
            brokenRules.Add(new BrokenBusinessRule("Facility Campus", "Must have at least one Campus"));
       else
       {
           foreach(var campus in  Campus)
           {
               brokenRules.AddRange(campus.GetBrokenRules());
           }
       }
    
       if (!Building,Any())
            brokenRules.Add(new BrokenBusinessRule("Facility Building", "Must have at least one Building"));
        else
        {
            foreach(var building in Building)
            {
                brokenRules.AddRange(building.GetBrokenRules());
            }
        }
    
        if (!Floor.Any())
            brokenRules.Add(new BrokenBusinessRule("Facility Floor", "Must have at least one Floor"));
        else
        {
            foreach (var floor in Floor)
            {
                brokenRules.AddRange(floor.GetBrokenRules());
            }        
        }
        return brokenRules;     
    }
    

    就重新设计而言,我将首先摆脱 ICampus、IBuilding 和 IFloor 接口并针对这些类进行编程。我将创建一个接口来声明GetBrokenRules 行为并让业务类实现它。除此之外,在我看来,校园有建筑物,建筑物有楼层,所以我会这样设计,而不是将这些类收集到设施类中。

    【讨论】:

    • 感谢您的输入,我上课松散的原因是,我有两种不同的场景,例如 1) 由校园/建筑物/楼层组成的设施 2) 入口点使用校园/建筑物和我已经创建了两个接口 1) IFacilities 和 2) IPointOfEntry ...你还认为我应该摆脱 ICampus、IBuilding、IFloor 吗?
    • 如果你只有一个实现接口的业务(不是服务)类,那么我会去掉它,因为它没有任何价值。顺便说一句,正如 noblethrasher 指出的那样,您应该在构造函数中检查空集合。如果你不这样做,那么我在代码中的注释是错误的。
    【解决方案2】:

    您对 ICampus、IBuilding 和 IFloor 的定义在哪里?这些似乎是 IFacilities 不可或缺的一部分。此外,您是在对象列表上调用 GetBrokenRules(),而不是在对象本身上。

    我将假设 ICampus、IBuilding 和 IFloor 已正确定义,并且目前唯一的问题是您正在调用列表中的方法。您需要遍历 List 并在每个项目上调用该方法。比如:

    Campus.ForEach(c => AddToBrokenRulesList(brokenRules, c.GetBrokenRules()));
    

    (您可能需要 nVentive Umbrella extensions 来表示 .ForEach,我不记得了。但是还有其他方法可以枚举 List,所以这并不重要。)

    【讨论】:

    • @David:ICampus... 有两个属性(id、name),调用对象列表的原因是 ICampus 和 IBuilding 作为单独的对象...有意义吗?
    • @teki:所以 ICampus(我假设 IBuilding 和 IFloor)没有定义 GetBrokenRules()?那么你肯定不能在那个对象上调用那个方法。您试图摆脱这些物品的“破坏规则”,您打算如何获得它们?
    • 我该如何检查:else if (Campus.GetBrokenRules().Count > 0)?如果我使用 Campus.ForEach
    • 这应该更分层吗?也就是说,不是三个单独的对象列表,而是每个 IFacilities 对象都有一个 ICampus 对象列表,每个对象都有一个 IBuilding 对象列表,每个对象都有一个 IFloor 对象列表,这不是更有意义吗?在我看来,对于每一个存在,它的父母也必须存在,不是吗?然后,您将能够采用更加面向对象的方法来获取损坏的规则,因为每个人都可以返回从其子级获取的损坏规则列表。 (尽管您需要定义这些方法。)
    • @David,我刚刚更新了关于 ICampus、IBuilding、IFloor 的问题,其中确实包含 GetBrokenRules()。
    【解决方案3】:

    GetBrokenRules() 不接受任何参数,并且它不是扩展方法,因此它不知道它应该处理什么列表。比这更难的是,你要处理的所有列表都定义为不同接口类型的列表,所以没有共性。

    处理此问题的一种方法是定义一个新接口,该接口定义了 IBuilding、ICampus 和 IFloor 的通用处理,并让这些接口中的每一个都继承自这个新接口(称为 IFacility)。然后,您可以定义 GetBrokenRules 以获取 List 的参数,并将其传递给 List。 GetBrokenRules 将能够调用 IFacility 中定义的方法,这可能足以解决您当前的问题。

    但是,您必须将列表作为参数传递,而不是按照您现在的方式传递 (Campus.GetBrokenRules())。如果可以使扩展方法起作用,则可以使用此语法,但是在泛型集合上定义扩展方法时可能会很棘手。我现在建议不要这样做。

    【讨论】:

      【解决方案4】:

      我会在构造函数中进行空检查,并将 IEnumerables 作为参数而不是 IList。您可以在 IEnumerables 上调用 ToList(),如果它为空,它的附带好处是抛出异常。

      我将创建一个带有 GetBrokenRules 方法的 IFacility 接口,该方法返回和 IEnumerable

      public interface IFacility
      {
          IEnumerable<BrokenRules> GetBrokenRules();
      }
      
      public static class Utils
      {
          public static IEnumerable<BrokenRules> GetRules(this IEnumerable<IFacility> facilities)
          {
              return facilities.SelectMany(x => x.GetBrokenRules());
          }
      }
      

      然后让建筑物、楼层、校园等实现 IFacility 接口。

      【讨论】:

      • 谢谢,但我的问题与 GetBrokenRules() 方法更相关。
      • 啊,我误解了这个问题。我没有意识到这些是商业规则。我以为它们是诸如“20 英尺内禁止吸烟”或“晚上 10 点后不允许男孩进入女孩的建筑物”之类的规则
      猜你喜欢
      • 2012-10-10
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多