Considering the following sample code:
// delivery strategies
public abstract class DeliveryStrategy { ... }
public class ParcelDelivery : DeliveryStrategy { ... }
public class ShippingContainer : DeliveryStrategy { ... }
and the following sample Order class:
// order (base) class
public abstract class Order
{
private DeliveryStrategy delivery;
protected Order(DeliveryStrategy delivery)
{
this.delivery = delivery;
}
public DeliveryStrategy Delivery
{
get { return delivery; }
protected set { delivery = value; }
}
}
When i derive a new type of order class, it will inherit the Delivery property of type DeliveryStrategy.
Now, when it is given that CustomerOrders must be delivered using the ParcelDelivery strategy, we could consider 'new'ing the Delivery property in the CustomerOrder class:
public class CustomerOrder : Order
{
public CustomerOrder()
: base(new ParcelDelivery())
{ }
// 'new' Delivery property
public new ParcelDelivery Delivery
{
get { return base.Delivery as ParcelDelivery; }
set { base.Delivery = value; }
}
}
(The CustomerOrder obviously needs to ensure that is compatible (polymorph) with Order)
This allows direct usage of the ParcelDelivery strategy on CustomerOrder without the need for casting.
Would you consider using this pattern? why / why not?
Update: i came up with this pattern, instead of using generics, because i want to use this for multiple properties. I don't want to use generic type arguments for all these properties
The main advantage of properties is that they allow us to encapsulate our data inside our class in such a way that we can control access to our class's data through only the properties and not by allowing outside programs to access our fields directly.
Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code. A get property accessor is used to return the property value, and a set property accessor is used to assign a new value.
Using a method causes something to happen to an object, while using a property returns information about the object or causes a quality about the object to change.
A C# property have two accessors, get property accessor and set property accessor. A get accessor returns a property value, and a set accessor assigns a new value. The value keyword represents the value of a property. Properties in C# and . NET have various access levels that is defined by an access modifier.
I'd prefer to make the type generic:
public abstract class Order<TDelivery> where TDelivery : Delivery
{
public TDelivery Delivery { ... }
...
}
public class CustomerOrder : Order<ParcelDelivery>
{
...
}
This ensures type safety at compile-time, rather than leaving it up to execution time. It also prevents the situation of:
CustomerOrder customerOrder = new CustomerOrder();
Order order = customerOrder;
order.Delivery = new NonParcelDelivery(); // Succeeds!
ParcelDelivery delivery = customerOrder.Delivery; // Returns null
Ouch.
I regard new
as usually a last resort. It introduces added complexity both in terms of implementation and use.
If you don't want to go down the generic route, I'd introduce a genuinely new property (with a different name).
I think this is a good pattern. It makes it easier to explicitly use derived types by removing the need to cast the result, and it doesn't 'break' the base class behavior. Actually, a similar pattern is used in some classes in the BCL, for instance look at the DbConnection class hierarchy :
So, if you manipulate the connection object through a DbConnection variable, CreateCommand will return a DbCommand ; if you manipulate it through a SqlConnection variable, CreateCommand will return a SqlCommand, avoiding the cast if you're assigning it to a SqlCommand variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With