Home > Back-end >  Decorator pattern in C#
Decorator pattern in C#

Time:10-17

I try to simulate the decorator pattern in C#.

So I have these classes:

public abstract class Car
    {

       // private string description;
        public abstract string Descripton 
        {
            get; 
        
        }

        public abstract int Cost();

    }
public abstract class CarDecorator : Car
    {
        protected Car _decorated;
        //private string description;
        public CarDecorator(Car decoratied)
        {
            this._decorated = decoratied;

        }

        public override string Descripton
        {
            get
            {
                return _decorated.Descripton;
            }
        }

        public override int Cost()
        {
            return _decorated.Cost();
        }

 public class EnhancedAutoPilot : CarDecorator
    {   

        public EnhancedAutoPilot(Car car):base(car)
        {
            this._decorated = car;
        }


        public override string Descripton
        {
            get
            {
                return _decorated.Descripton   ", Enhanced autopilot";
            }
        }

        public override int Cost()
        {
            return _decorated.Cost()    5000;
        }
    }

public class ModelXS:Car
    {
        protected Car _decorated;

        public string Description = "Model XS";

        public override string Descripton
        {
            get
            {
                return _decorated.Descripton;
            }
        }

        public override int Cost()
        {
            return 5500;
        }        
        
    }

 public class ModelXXX : Car
    {
        protected Car _decorated;

        public string Description = "ModelXXX";

        public override string Descripton
        {

            get
            {
                return _decorated.Descripton;
            }

        }

        public override int Cost()
        {
            return 73000;
        }       
    }

 public class RearFacingSeats:CarDecorator
    {

        public RearFacingSeats(Car car):base(car)
        {
            this._decorated = car;

        }

        public override string Descripton
        {
            get
            {
                return _decorated.Descripton   ", Rear Facing Seats  ";
            }
        }

        public override int Cost()
        {
            return _decorated.Cost()   4000;
        }
    }
public class SmartAirSuspension: CarDecorator
    {
        public SmartAirSuspension(Car car):base(car)
        {
            this._decorated = car;
        }


        public override string Descripton
        {
            get
            {
                return _decorated.Descripton   ",  Smart Air Suspension ";
            }
        }

        public override int Cost()
        {
            return _decorated.Cost()   2500;
        }



    }
class Program
    {
        static void Main(string[] args)
        {
            Car car = new RearFacingSeats(new SmartAirSuspension(new EnhancedAutoPilot()));
        }
    }

But then I get this error:

There is no argument given that corresponds to the required formal parameter 'car' of 'EnhancedAutoPilot.EnhancedAutoPilot(Car)'

CodePudding user response:

Your Cars are wrong, they look like decorators but are not, in fact they are supposed to be just implementations of Cars. Like this one:

public class ModelXS : Car
{
    public override string Descripton
    {
        get
        {
            return "Model XS";
        }
    }

    public override int Cost()
    {
        return 5500;
    }        
}

After that you can call the constructors like in @Richard 's answer and you are golden.

and you can ditch

public EnhancedAutoPilot(Car car):base(car)
{
    this._decorated = car; // <<-- this lines
}

because you do that assignment in the base constructor of the CarDecorator class already.

CodePudding user response:

The error is telling you that you are not passing a value to the EnhancedAutoPilot() contstructor. All of your decorators require a Car instance be passed, thus you must instantiate a car first, before calling your decorators.

It looks like ModelXS and ModelXXX are types of cars, so the Program class should be:

    class Program
    {
        static void Main(string[] args)
        {
            Car decoratedCar = 
                new RearFacingSeats(
                new SmartAirSuspension(
                new EnhancedAutoPilot(
                new ModelXS())));
        }
    }

CodePudding user response:

You're using new EnhancedAutoPilot() constructor without parameters and it requires a Car parameter in your contructor signature.

public EnhancedAutoPilot(Car car):base(car)

Another issue i see is that you have _decorated in your Car class. The decorated object should only be in the Decorator classes.

So i would modify your car classes this way :

public class ModelXXX : Car
{
    public override string Descripton => "ModelXXX";

    public override int Cost()
    {
        return 73000;
    }
}

public class ModelXS : Car
{
    public override string Descripton => "Model XS";

    public override int Cost()
    {
        return 5500;
    }
}

And main would look like this :

static void Main(string[] args)
{
    Car car = new ModelXXX();

    car = new EnhancedAutoPilot(car);
    car = new SmartAirSuspension(car);
    car = new RearFacingSeats(car);

    Console.Writeline(car.Descripton);
}
  •  Tags:  
  • c#
  • Related