Search code examples
c#oopdesign-patternssolid-principles

Factory class is not supporting SOLID principle


I have code as shown below

 public interface ICar
{
    void Created();
}

public class BigCar : ICar
{
    public void Created()
    {

    }
}

public class SmallCar : ICar
{
    public void Created()
    {

    }
}


public class LuxaryCar : ICar
{
    public void Created()
    {

    }
}

public class CarFactory
{
    public ICar CreateCar(int carType)
    {
        switch (carType)
        {
            case 0:
                return new BigCar();
            case 1:
                return new SmallCar();
            case 2:
                return new LuxaryCar();
            default:
                break;
        }
        return null;
    }
}

In this code I have a factory which is returning the concrete instances. But every time I need to have a new implementation of the ICar interface, I have to change the CreateCar() method of the CarFactory. It seems like I am not supporting the Open Closed Principle of the SOLID principles. Please suggest is there a better way to handle this scenario.


Solution

  • You probably want to make it configurable, like this:

    void Main()
    {
        // configurable array
        var factories = new ICarFactory[] { new BigCarFactory() };
    
        // create factory
        var realfactory = new CarFactory(factories);
    
        // create car
        var car = realfactory.CreateCar(0);
    }
    
    public class CarFactory : ICarFactory
    {
        private ICarFactory[] _factories;
    
        public CarFactory (ICarFactory[] factories)
        {
            _factories = factories;
    
        }   
        public ICar CreateCar(int carType)
        {
            return _factories.Where(x=>x.SupportCar(carType)).First().CreateCar(carType);
        }
    
        public bool SupportCar(int type) => _factories.Any(x=>x.SupportCar(type));
    }
    
    public interface ICarFactory
    {
        ICar CreateCar(int type);
        bool SupportCar(int type);
    }
    
    public class BigCarFactory : ICarFactory
    {
        public ICar CreateCar(int carType)
        {
            if(carType != 0) throw new NotSupportedException();
            return new BigCar();
        }
    
        public bool SupportCar(int type) => type == 0;
    }
    
    
    public interface ICar
    {
        void Created();
    }
    
    public class BigCar : ICar
    {
        public void Created()
        {
    
        }
    }
    
    public class SmallCar : ICar
    {
        public void Created()
        {
    
        }
    }
    
    
    public class LuxaryCar : ICar
    {
        public void Created()
        {
    
        }
    }