Replace conditional with polymorphism refactoring or similar?

前端 未结 5 986
感动是毒
感动是毒 2021-02-06 00:45

I have tried to ask a variant of this question before. I got some helpful answers, but still nothing that felt quite right to me. It seems to me this shouldn\'t really be that h

5条回答
  •  青春惊慌失措
    2021-02-06 01:25

    this is a common problem, there are a few options that i can think of. There are two design pattern that come to mind, firstly the Strategy Pattern and secondly the Factory Pattern. With the strategy pattern it is possible to encapsulate the calculation into an object, for example you could encapsulate your GetHours method into individual classes, each one would represent a calculation based on size. Once we have defined the different calculation strategies we wrap then in a factory. The factory would be responsible for selecting the strategy to perform the calculation just like your if statement in the GetHours method. Any way have a look at the code below and see what you think

    At any point you could create a new strategy to perform a different calculation. The strategy can be shared between different objects allowing the same calculation to be used in multiple places. Also the factory could dynamically work out which strategy to use based on configuration, for example

    class Program
    {
        static void Main(string[] args)
        {
            var factory = new HourCalculationStrategyFactory();
            var strategy = factory.CreateStrategy(1, "writing");
    
            Console.WriteLine(strategy.Calculate());
        }
    }
    
    public class HourCalculationStrategy
    {
        public const int Small = 2;
        public const int Medium = 8;
    
        private readonly string _serviceType;
        private readonly int _numberOfManuals;
    
        public HourCalculationStrategy(int numberOfManuals, string serviceType)
        {
            _serviceType = serviceType;
            _numberOfManuals = numberOfManuals;
        }
    
        public int Calculate()
        {
            return this.CalculateImplementation(_numberOfManuals, _serviceType);
        }
    
        protected virtual int CalculateImplementation(int numberOfManuals, string serviceType)
        {
            if (serviceType == "writing")
                return (Small * 30) + (20 * (Medium - Small)) + (10 * numberOfManuals - Medium);
            if (serviceType == "analysis")
                return 30;
    
            return 0;
        }
    }
    
    public class SmallHourCalculationStrategy : HourCalculationStrategy
    {
        public SmallHourCalculationStrategy(int numberOfManuals, string serviceType) : base(numberOfManuals, serviceType)
        {
        }
    
        protected override int CalculateImplementation(int numberOfManuals, string serviceType)
        {
            if (serviceType == "writing")
                return 30 * numberOfManuals;
            if (serviceType == "analysis")
                return 10;
    
            return 0;
        }
    }
    
    public class MediumHourCalculationStrategy : HourCalculationStrategy
    {
        public MediumHourCalculationStrategy(int numberOfManuals, string serviceType) : base(numberOfManuals, serviceType)
        {
        }
    
        protected override int CalculateImplementation(int numberOfManuals, string serviceType)
        {
            if (serviceType == "writing")
                return (Small * 30) + (20 * numberOfManuals - Small);
            if (serviceType == "analysis")
                return 20;
    
            return 0;
        }
    }
    
    public class HourCalculationStrategyFactory
    {
        public HourCalculationStrategy CreateStrategy(int numberOfManuals, string serviceType)
        {
            if (numberOfManuals <= HourCalculationStrategy.Small)
            {
                return new SmallHourCalculationStrategy(numberOfManuals, serviceType);
            }
    
            if (numberOfManuals <= HourCalculationStrategy.Medium)
            {
                return new MediumHourCalculationStrategy(numberOfManuals, serviceType);
            }
    
            return new HourCalculationStrategy(numberOfManuals, serviceType);
        }
    }
    

提交回复
热议问题