概念:本文中的“分解依赖” 是指对部分不满足我们要求的类和方法进行依赖分解,通过装饰器来达到我们须要的功能。

 

正文:正如以下代码所看到的。假设你要在你的代码中增加单元測试但有一部分代码是你不想測试的,那么你应用使用这个的重构。以下的样例中我们应用静态类来完毕某些工作。但问题是在单元測试时我们无法mock静态类,所以我们仅仅能引入静态类的装饰接口来分解对静态类的依赖。从而我们使我们的调用类仅仅须要依赖于装饰接口就能完毕这个操作。

namespace LosTechies.DaysOfRefactoring.BreakDependencies.Before
{
    public class AnimalFeedingService
    {
        private bool FoodBowlEmpty { get; set; }

        public void Feed()
        {
            if (FoodBowlEmpty)
                Feeder.ReplenishFood();

            // more code to feed the animal
        }
    }

    public static class Feeder
    {
        public static void ReplenishFood()
        {
            // fill up bowl
        }
    }
}

重构后代码例如以下,我们加入一个接口和一个实现类,在实现类中调用静态类的方法,所以说详细做什么事情没有改变,改变的仅仅是形式,但这样做的一个优点是添加了了代码的可測试性。在应用了分解依赖模式后,我们就能够在单元測试的时候mock一个IFeederService对象并通过AnimalFeedingService的构造函数传递给它。

这样就能够完毕我们须要的功能。

namespace LosTechies.DaysOfRefactoring.BreakDependencies.After
{
    public class AnimalFeedingService
    {
        public IFeederService FeederService { get; set; }

        public AnimalFeedingService(IFeederService feederService)
        {
            FeederService = feederService;
        }

        private bool FoodBowlEmpty { get; set; }

        public void Feed()
        {
            if (FoodBowlEmpty)
                FeederService.ReplenishFood();

            // more code to feed the animal
        }
    }

    public interface IFeederService
    {
        void ReplenishFood();
    }

    public class FeederService : IFeederService
    {
        public void ReplenishFood()
        {
            Feeder.ReplenishFood();
        }
    }

    public static class Feeder
    {
        public static void ReplenishFood()
        {
            // fill up bowl
        }
    }
}

总结:这个重构在非常多时候和设计模式中的一些思想类似,使用中间的装饰接口来分解两个类之间的依赖,对类进行装饰。然后使它满足我们所须要的功能。