从依赖倒置看工厂方法模式

啥是依赖倒置?

想了解啥是依赖倒置先得说清楚啥是依赖。就是讲你这个类用了其他哪些对象,这就叫依赖,在面向对象开发中,依赖都是自上向下的,看代码:

class TestIPhone{
    public void testIphone(String type){
        Iphone iphone = null;
        if(type.equals("Iphone6")){
            iphone = new Iphone6();
        }else if (type.equals("Iphone7")){
            iphone = new Iphone7();
        }
        ...
        iphone.powerOn();
        iphone.takePic();
        ...
    }
}

TestPhone依赖Iphone6,Iphone7,Iphone8......如图:

从依赖倒置看工厂方法模式_第1张图片
依赖

在上一篇文章[从简单工厂到Spring配置文件][1]我们讲到,要面向接口编程而不是面向实现编程,把实例化对象的过程与使用对象的过程分开,即简单工厂。那样的话IphoneTest就只是依赖简单工厂创建对象了。

public Class TestIphone {
...
Iphone testIphone(String type){
      Iphone = SimpleIphoneFactory.createIphone(type);
      iphone.powerOn();
      iphone.takePic();
      ...
  }
}

现在我们考虑这样一组场景,由于我们手机测试公司发展迅速,走向国际化,公司发展到日本,欧洲,美国。而那边的Iphone或多或少有一些地域差异。(比如日本的Iphone无法通过静音关闭拍照声音)。
首先我们会想到,这样简单啊,我们只需要在当地建一个SimpleLocalFactory和IphoneLocalTest就可以了啊。这样确实可以,不过我们发现也许在当地,他们的IphoneLocalTest在执行测试的时候并不符合我们公司的规范。这时候,我们又想,那我们可以让当地公司继承最原始的IphoneTest。再让SimpleLocalFactory继承最原始的Factory。这个方法也可以,但是我们还是觉得有点麻烦,需要继承两次,能不能在简化一下呢?
我们想到了设计原则:找出公共的部分,把它们封装起来。我们发现IphoneTest总是要调用SimpleFactory,我们把调用这部分合在一起,来看看代码:

public abstract class TestIPhone{
    //测试的部分方法可以写成final禁止子类改变
    public void testIphone(String type){
        Iphone iphone = null;
        iphone = createIphone(type);
        iphone.powerOn();
        iphone.takePic();
        ...
    }
    //生产Iphone的方法设计成abstract去让子类实现
    abstract Iphone createIphone(String type){
    } 
}

public class JpanTestIphone extends TestIPhone{
    Iphone createIphone(String type){
        if (type.equals("JpIphone6")){
            return new JpIphone6();
        } else if (type.equals("JpIphone7")){
            return new JpIphone7();
        } else if type.equals("JpIphone9"){
            return new JpIphone9();
        }
    }
}

public class UkTestIphone extends TestIPhone{
    Iphone createIphone(String type){
        if (type.equals("UkIphone6")){
            return new UkIphone6();
        } else if (type.equals("UkIphone7")){
            return new UkIphone7();
        } else if type.equals("UkIphone9"){
            return new UkIphone9();
        }
    }  
}

我们将具体实例化的代码交给了子类去完成,TestIphone只依赖Iphone,而JpTestphone和UkTestphone则依赖具体的Iphone类,可以说我们通过一个“接口”Iphone将TestIphone和具体的LocalTestIphone连接在了一起。

从依赖倒置看工厂方法模式_第2张图片
依赖倒置

其实工厂方法所做的就是使得父类IphoneTest根本不用在乎是哪个Iphone,实例化的Iphone对于IphoneTest是看不到的。
我们通过一个“接口”IphoneTest和一个“接口”Iphone将具体的实例化推迟到子类进行,但是不变的部分封装在父类,这就是工厂方法。
最后,其实当我们学完设计模式后,在写代码读代码的过程中,都会运用到设计模式的设计理念,在经典的源码中,都有着大量的设计模式,学习设计模式也可以使我们在阅读他人代码的过程中更轻松,最后你会发现到处都是设计模式。
从依赖倒置看工厂方法模式_第3张图片
微信公众号-码农放个假

[1]: http://www.jianshu.com/p/af77f5cdb41f "从简单工厂到Spring配置文件"

你可能感兴趣的:(从依赖倒置看工厂方法模式)