Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decorator pattern in C# without Inheritance. Is this correct?

 public interface IMovable
    {
        void Move();
    }

    public interface IUnloadable
    {
        void Unload();
    }

    public class Vehicle : IMovable
    {
        public void Move()
        {
            Console.Write("moving");
        }
    }

    public class Truck : IMovable, IUnloadable
    {
        private Vehicle Veh;

        public Truck(Vehicle veh)
        {
            this.Veh = veh;
        }

        public void Move()
        {
            Veh.Move();
            Console.Write("reverse with beepy noise as well");
        }

        public void Unload()
        {
           Console.Write("Unload");
        }
    }

If this is the decorator pattern. What is the difference between the decorator pattern and composition? I have seen examples of this pattern where inheritance is used. For instance the Java example on Wikipedia.

I don't see the need to use inheritance at all, or am I missing something?

like image 410
user1809104 Avatar asked Apr 22 '15 09:04

user1809104


2 Answers

Decorator pattern by definition will implement the same interface as the component it is decorating. Idea is that the client code doesn't needs to change. It can rely on the same abstraction it was using earlier.

For example:

public interface IMovable
{
    void Move();
}

public class Truck : IMovable
{
    public void Move()
    {
        Console.Write("moving");
    }
}

public class NoisyMovable : IMovable //1.Implement same interface
{
    private IMovable movable;
    public NoisyMovable(IMovable movable)//2.Wrap same interface
    {
        this.movable = movable;
    }

    public void Move()
    {
        movable.Move();            
        Console.Write("Make noise");
    }
}

If you note the NoisyMovable class, it is a decorator because it implements the IMovable abstraction and wraps the same.

With that, you don't have to create many classes like NoisyVehicle, NoisyTruck, NoisyCar etc. Just the Car, Truck are enough; you can add the noise by using the single decorator.

IMovable movable = new NoisyMovable(new Truck ());//Noisy Truck
IMovable movable = new NoisyMovable(new Car());//Noisy car
//etc

Composition on the other hand doesn't need to wrap the same implementation of the interface it implements. It can implement one interface and wrap any other.

What you have got wrong is your Truck class takes the instance of Vehicle. It shouldn't, instead it should take any instance of IMovable. It should work with any implementation of IMovable.

like image 195
Sriram Sakthivel Avatar answered Nov 15 '22 16:11

Sriram Sakthivel


What is the difference between the decorator pattern and composition?

Conceptually, a decorator modifies the behavior of the (single) object it wraps, whereas the composite (pattern) has behavior based on the combination of the (multiple) objects it aggregates.

I dont see the need to use inheritance at all, or am I missing something?

Inheritance is useful so that you can have multiple decorators, and nest them. For example, a SelfDriver that wraps a Truck that wraps a Vehicle. Ignoring IUnloadable, the second decorator would be SelfDriver:

Class diagram in PlantUML

The code would look like this:

IMovable sd = new SelfDriver(new Truck(new Vehicle())));

The object diagram would look like this:

Object diagram in PlantUML

like image 38
Fuhrmanator Avatar answered Nov 15 '22 17:11

Fuhrmanator