Problem
[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?
Solution
“… instead of inheritance..” I expected the JobFilterRequest
class to encapsulate the TimeFrame
object by wrapping the contained TimeFrame
object’s methods in its own. Thus the client code is not aware of a distinct inner object – the Law of Demeter a.k.a. the least knowledge principle.
That encapsulation implies there is no public getter; and I would prefer a constructor parameter over the public setter.
If we inherit from TimeFrame
there is no contained object, so good encapsulation makes composition “feel” the same for the client code. Class types are different of course, but we’re still calling the same methods and getting the same behavior.