面向接口编程:简单工厂模式

主讲教师:王少华   QQ群号:483773664

学习目标

  1. 理解面向接口编程的优势

  2. 掌握简单工厂模式

一、面向对象编程提倡面向接口编程

在面向对象编程中提倡面向接口编程,而不是面向实现编程。

(一)为什么

假设某电脑公司,生产的电脑它需要一个打印功能,它有二种选择,一种是与某个打印机生产公司结成战略合作伙伴关系,我公司生产的电脑,只能用你的打印机,另外一种是方式,我定义一个规范,只要生产打印机公司按照我这种规范生产的打印机,我的电脑都能识别。

我们将这二种方式用代码的形式来实现一下

1
2
3
4
5
public class Printer {
    public void print(){
        System.out.println("我是战略合作伙伴");
    }
}
1
2
3
public interface Output {
    public void out(String str);
}
1
2
3
4
public class Computer {
    private Printer printer;//这种方式缺点很明显,耦合度太高
    private Output output;
}

(二)面向接口编程的优势

接口体现了约定和实现相分离的原则,通过面向接口编程,可以降低代码间的耦合性,提高代码的可扩展性和可维护性。

二、简单工厂模式

(一)应用场景:

以上面的例子为场景,假设一个公司,占门代工生产各种型号的打印机,而且这些打印机都符合生产电脑的公司的规范,那么这个电脑公司就不需要去找各个打印机公司要打印机了,只需要去这个打机印代工工厂要打印机就可以了。这就是简单工厂模式在实际生活的应用。

(二)代码实现

1、PrinterA:一种打印机产品

1
2
3
4
5
public class PrinterA implements Output{

    public void out(String str) {

        System.out.println(str);

        System.out.println("PrinterA");
    }
}

2、OutputFactory:打印机生产的代工厂

1
2
3
4
5
6
7
8
9
public class OutputFactory {
    /**
     * 专门用于生产打印机
     * @return
     */
    public Output getOutput(){
        return new PrinterA();
    }
}

3、Computer

1
2
3
4
5
6
public class PrinterA implements Output{
    public void out(String str) {
        System.out.println(str);
        System.out.println("PrinterA");
    }
}

4、Test

1
2
3
4
5
6
7
public class Test {
    public static void main(String[] args) {
        OutputFactory outputFactory = new OutputFactory();
        Computer computer = new Computer(outputFactory.getOutput());
        computer.print("我要打印");
    }
}

(三)优化

现在我们使用的简单工厂模式,还存在一个弱点,就是我们要在工厂中手动指定一个产品,我们希望这个工厂是这样的:客户需给一个打印机的名称,它就能生产出这种打印机。

这里要用到Java的反射机制。具体实现如下

OutputFactory

1
2
3
4
5
6
7
8
9
10
public Output creatOutput(String printName)throws  InstantiationException, IllegalAccessException, ClassNotFoundException{
        if(printName.equalsIgnoreCase("PrinterA")){
            return PrinterA.class.newInstance();
        }else if(printName.equalsIgnoreCase("PrinterB")){
            return PrinterB.class.newInstance();
        }else {
            System.out.println("抱歉,这种打印机,我生产不了!!!");
            return null;
        }
    }