如何正确使用构图?

How to use composition correctly?

[DataContract(Name = "jobDateTimeFilterRequest", Namespace = Constants.ManagementNamespace)]
public class JobDateTimeFilterRequest : TimeFrame
{
    [DataMember(Name = "jobType")]
    public BackgroundJobType JobType { get; set; }
}

[DataContract(Name = "timeFrame", Namespace = Constants.ManagementNamespace)]
public class TimeFrame
{
    [DataMember(Name = "from")]
    public DateTime From { get; set; }

    [DataMember(Name = "to")]
    public DateTime To { get; set; }
}

我想使用组合而不是继承。 为此,我需要创建:

[DataContract(Name = "jobFilterRequest", Namespace = Constants.ManagementNamespace)]
public class JobFilterRequest
{
    [DataMember(Name = "jobType")]
    public BackgroundJobType JobType { get; set; }
}

JobDateTimeFilterRequest会是这样的:

[DataContract(Name = "jobDateTimeFilterRequest", Namespace = Constants.ManagementNamespace)]
public class JobDateTimeFilterRequest
{
    [DataMember(Name = "jobType")]
    public JobFilterRequest JobFilter { get; set; }

    [DataMember(Name = "timeFrame")]
    public TimeFrame TimeFrame{ get; set; }
}

我说的对吗?还是对构图的理解不正确?

总的来说你是对的。您已将基础 class 的实例置于派生 class 的状态。但是你不应该忘记封装,在当前的实现中,可能会得到 JobDateTimeFilterRequest 对象的不一致状态,例如通过设置 TimeFrame null。考虑一下它依赖于业务逻辑的对象的一致状态。我不知道你的业务逻辑,但你的案例可以通过使用 TimeFrame 属性 的私有 setter 的构造函数参数来完成。请注意,我们正在谈论一般情况,但有 WCF 逻辑可能会被 private 修饰符

破坏

大概是这样的(我忽略WCF属性和逻辑):

public class JobDateTimeFilterRequest
{
    public JobFilterRequest JobFilter { get; set; }

    public TimeFrame TimeFrame{ get; private set; }

    public JobDateTimeFilterRequest(TimeFrame timeFrame)
    {
        this.TimeFrame = timeFrame;
    }
}

"composition over inheritance"原则通常适用于具有行为的对象,而不是简单的数据结构。原因是,使用新 功能 可以更轻松地扩展系统。相反,仅仅引入新数据并不会改变系统本身。

在你的情况下,只要你不覆盖属性并且它们仍然是 public 自动属性,从 TimeFrame 继承可能和拥有 [=10] 一样好=].