简体   繁体   中英

Decorator pattern in C#

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)'

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM