Anatoly
Anatoly

Reputation: 1916

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; }
}

I would like to use composition instead of inheritance. To do this I will need to create:

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

And JobDateTimeFilterRequest will be like this:

[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; }
}

I'm I right? Or it's incorrect understanding of composition?

Upvotes: 1

Views: 118

Answers (2)

Ilia Maskov
Ilia Maskov

Reputation: 1898

Generally you are right. You've placed instance of base class in state of derived class. But you should not forget about incapsulation, in current realisation it is possible to get inconsistent state of JobDateTimeFilterRequest object, for example by setting TimeFrame null. Think about consistent state of objects it dends on business logic in lagerly. I don't know your business logic but your case could be done for example by taking constructor parameter with private setter of the TimeFrame property for example. Note that we are talking about general case but there is WCF logic which perhaps can be potentially broken byprivate modifier

Probably it would be like this (i'm ignoring WCF attributes and logic):

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

    public TimeFrame TimeFrame{ get; private set; }

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

Upvotes: 1

guillaume31
guillaume31

Reputation: 14064

The "composition over inheritance" tenet usually applies to objects with behavior, not simple data structures. The reason is, it makes it easier to extend the system with new functionality. In contrast, just introducing new data isn't changing the system per se.

In your case, as long as you don't override the properties and they remain public auto-properties, inheriting from TimeFrame will probably be just as good as having a TimeFrame.

Upvotes: 2

Related Questions