简单工厂模式

读书学习笔记~后面是自己一些总结

简单工厂模式原理就是面向接口编程

接口体现的是一种规范和实现分离的设计哲学,充分利用接口可以极好地降低各模块之间的耦合,从而提供系统的可扩展性和可维护性

基于这种原则,很多软件架构设计理论都倡导“面向接口”编程,而不是面向实现类编程,希望通过面向接口编程来降低程序的耦合。

有一个场景,假设程序中有个Computer类需要组合一个输出设备,现在有两个选择:直接让Computer类组合(继承?)一个Print,或者让Computer类组合一个Output,那么到底采用哪种方式更好呢。

假设让Computer类组合一个Printer对象,如果有一天系统需要重构,需要使用BetterPrintrt来代替Printer,这就需要打开Computer类源代码进行修改。如果系统中只有一个Computer类组合了还好,但如果系统中有100个、1000个甚至10000个类组合了Printer,将意味着要对这么多个类进行修改。

为了避免这个问题,工厂模式建议让Computer类组合一个Output类型对象,将Computer类与Print类完全分离。Computer对象实际组合的是printer对象还是BetterPrinter对象,对Computer而言完全透明。当Printer对象切换到BetterPrinter对象时,系统完全不受影响。下面是Computer类的定义代码。

public class Computer {
    private Output out ;
    public Computer (Output out) {
        this.out = out ;
    }
    //定义一个模拟获取字符串输入的方法
    public void keyIn (String msg) {
        out.getData(msg) ;
    }
    //定义一个模拟打印的方法
    public void print() {
        out.out;
    }
}

上面的Computer类已经完全与Printer类分离,只是与Output接口耦合。Computer不再负责创建Output对象,系统提供一个Output工厂来负责生成Output对象。这个OutputFactory工厂类代码如下:
public class OutputFactory {
    public Output getOutput () {
        return new Ptinter() ;
    }
    public static void main (String [ ]args) {
        OutputFactory of = new OutputFactory () ;
        Computer c = new Computer (of.getOutput) ;
        c.keyIn("轻量级Java");
        c.keyIn("轻量级Java");
        c.print();
    }
}

在该OutputFactory类中包含了一个getOutput()方法,该方法返回一个Output实现类的实例,该方法负责创建Output实例,具体创建哪一个实现类的对象由该方法决定。如果系统需要将Print改为BetterPrinter实现类,只需让BetterPrinter实现Output接口,并改变OutputFactory类中的getOutput()方法即可。

下面是BetterPrinter实现类的部分代码,BetterPrinter只是对原有的Printer进行简单修改,以模拟系统重构后的改进。

//这个BetterPrinter需要有输入输出的行为,因此需要实现Output的这些方法
public class BetterPrinter implements Output {
    private Sting[] printData = new String[MAX];
    private int dataNum;
    
    public void out() {
        //.......具体的行为
    }
    public void getData (String mas) {
        //.....具体的行为
    }
}

下面是接口Output定义的代码

public interface Output {
    //接口定义的成员变量只能是常量
    int MAX = 50 ;
    //接口定义的普通方法只能是public 的抽象方法
    void out();
    void getData(String msg) ;
    //在接口中定义默认方法,需要使用default修饰
    default void print(String... msgs) {
        for(String msg : msgs) {
            System.out.println(msg);
        }
    }
    //在接口中定义类方法,需要使用static修饰
    static String staticTest() {
        return "接口里的类方法";
    }
}

上面的BetterPrinter类也实现了Output接口,因此也可当成Output对象使用,于是只要把OutputFactory工厂类的getOutput()方法中改成 return new BetterPrinter();

通过这种方式,即可把所以生成Output对象的逻辑集中在OutputFactory工厂类中管理,而所有需要使用Output对象的类(Computer类)只需与Output接口耦合,而不是与具体的实现类耦合。即使系统中有很多类使用了Printer对象,只要OutputFactory类的getOutput()方法生成的Output对象是BetterPrinter对象,则他们全部都会改为使用BetterPrinter对象,而所有程序无须修改,只须修改OutputFactory工厂类的getOutput()方法实现即可。

思维方式!!!!

1、Computer类需要完成输入字符串和输出字符串的动作

2、有两种选择,一种是在Computer类组合Printer(Computer和Printer没有继承关系,所以用组合)。就像这样

public class Computer {
    private Printer p;
    public void keyIn (String msg) {
        p.getData(msg) ;
    }
    public void print() {
        p.out;
    }
}

但是这样做不好,像输出设备这种经常需要跟换的东西,假如要换成BetterPrinter的话,Computer类又需要去改变它的源代码,其他组合了Printer类的类也要去修改。

因此有另一种选择,给Computer类组合Output类型的对象(它是一个接口,这个接口有所有的输出设备需要用到的动作,即输入字符串还有输出字符串)

3、所以Printer作为实现类,实现Output接口的方法。

4、然后我们需要一个产生实现类实例的类,那就是OutputFactory工厂类了。也负责打印东西


-------参考书籍《疯狂Java讲义》 李刚著


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值