删除对继承的抽象 class 引用的依赖

Remove dependency on inherited abstract class references

我正在尝试设置一个场景,我们可以在其中为我们的工作组创建一组通用模型,然后根据需要实施或扩展它们。if/when。

我有以下设置:

namespace Workgroup.DomainClasses
{
    public abstract class WorkGroupOrder
    {
       private ICollection<WorkGroupItems> _items;

       protected WorkGroupOrder()
       {
           _items = new List<WorkGroupItems>();
       }
       protected int OrderId { get; set; }
       protected virtual ICollection<WeAccount> Items
       {
           get { return _items; }
           set { _items = value; }
       }
    }
}

我希望用户不要使用基础 WorkGroupOrder,所以我想设置它,这样他们就需要实现自己的 class 版本。如果基础 class 一切都很好,它只是一个空的 class 调用基础构造函数,否则可以添加属性和功能。这样做的想法是工作组域比单个项目可能需要的要大得多,但我们希望从这个通用模型中驱动所有工作。

using Workgroup.DomainClasses;
namespace Project.DomainClasses
{
    public class Order : WorkGroupOrder
    {
        public string OrderComment { get; set; }
    }
}

我遇到的问题是我需要引用两个域模型才能实现。下面的 Testing() 方法中有一个错误,我还必须引用 Workgroup.DomainClasses 才能实例化 class。我对 abstract classes 不是很熟悉,所以这只是抽象类型的本质吗?如果可能,我更愿意删除此依赖项。

using Project.DomainClasses;
namespace Project.DataLayer
{
    public class Testing
    {
        public void Testing()
        {
            Order o1 = new Order();
        }
    }
}

几个问题。

  1. 这个组织有意义吗?有没有更好的方法 支持我提供一个通用模型的愿望 被延长?
  2. 我将如何访问两个基础的属性 抽象的 class 和具体的 class?在我的 Testing() 方法中我无法 例如访问“o1.OrderId”。
  3. 我想从开发人员那里删除摘要的元知识 class。在不明确要求开发人员这样做的情况下如何最好地执行构造函数?

最终,我想要求开发人员创建他们自己的 class 实例,以避免直接实现基本模型。我还想建立适当的可见性,以防止它们直接进入工作组对象。

这里似乎有几个不同的问题。

首先,使用命名空间来尝试隔离基本功能不是一个可行的选择,因为默认情况下所有派生的 classes 都需要访问基本 class 的命名空间(为了继承)。任何扩展您的基础 classes 的开发人员都需要访问包含基础 classes.

的命名空间

控制对功能或数据的访问通常最好使用访问修饰符(例如,publicprotectedprivate)或 public 属性和 public get{ }protected set{ }private set{ }(即具有不同访问级别的 getter 和 setter)。如果您希望对最终用户隐藏实现细节,那么 interface 是正确的方法(例如 API)。

其次,通过标记任何 class abstract,您将自动拒绝其他开发人员直接实例化该 class 的能力。他们将被迫创建一个从 abstract class 派生的 class(也称为 "concrete" class),以便使用 abstract base class 的方法和属性。

第三,您无法在测试代码中访问 属性 o1.OrderId 的原因是因为 属性 具有 protected 的访问修饰符。这意味着只有基础 class 及其派生的 classes 可以内部 访问此 属性。要将其公开给最终用户,必须将其标记为 public.

不幸的是,我不太明白你说 "setup a scenario where we can create a common set of models for our workgroup and then implement or extend them if/when needed" 的意思。在您的上下文中什么是工作组?为什么(所有)其他 classes 应该从它派生?

无论如何,你不能使用o1.OrderID,因为这个属性是protected,这意味着它只在WorkOrderGroup和subclass的范围内可见es 派生自它。使这个 属性 public 你可以随处访问它。

此外,请不要生气,但您似乎在封装和继承的面向对象概念上有些挣扎。我建议您看看这些概念(例如,您可以开始 here)并很好地理解它们的作用以及在实现功能时如何使用它们。 根据目前的信息,我不建议您像您在问题中解释的那样构建代码。

最后,关于面向对象语言实践的一些一般提示:

  • 比继承更喜欢组合:这意味着您应该通过封装而不是继承现有的 classes 来扩展它们。在大多数情况下,这更灵活。
  • 看看 SOLID 原则:它们提供了非常好的说明,您在编写每个 class 时都应该考虑这些说明。
  • 看看设计原则,也许还有领域驱动设计:互联网上有很多指导和很多例子。通过每个示例,您可以更好地了解如何处理新问题以及如何在 OOD 中为它们建模。

希望这个回答能为您指明正确的方向。