设计模式之工厂方法

工厂方法(模式)

前面,我们讲解了简单工厂模式,接着我们来说工厂方法模式。今天我们从一个简单的例子来说,从无模式发现代码中问题,然后使用模式解决的
方式。

需求

我们要实现一个文件分割器,把大文件按照指定的文件个数,分割成小的文件。文件的格式为二进制文件
示意代码如下:

/**
 * 接口描述: 文件分割器接口
 */
public interface ISplitter {
    void split(String filePath,int fileNumber);
}

/**
 * 类描述: 二进制文件分割
 */
public class BinarySplitter implements ISplitter{

    @Override
    public void split(String filePath, int fileNumber) {
        System.out.println("this is BinarySplitter filePath::::::"+filePath+" fileNumber::::::"+fileNumber);
    }
}

/**
 * 类描述: 文件分割器窗体
 */
public class SplitterMainForm {

    // 文件路径
    private String filePath;

    // 文件被分割的个数
    private int fileNumber;

    // 点击按钮
    public void onClick(String filePath,int fileNumber) {
        // SplitterMainForm 依赖具体的BinarySplitter分割器。
        ISplitter splitter = new BinarySplitter();
        splitter.split(filePath,fileNumber);
    }
}

上述代码中文件分割器窗体SplitterMainForm类依赖了具体BinarySplitter分割器,
我们知道这种强耦合关系导致代码很脆弱,不好。那么我们该如何解决这个问题呢?

重构v2

思考:现在问题是SplitterMainForm依赖具体的BinarySplitter分割器。我们想办法不让它依赖具体实现类问题就解决了
因此:我们创建ISplitter的工厂接口类ISplitterFactory。在这里我只展示新增的代码和修改的代码

新增ISplitterFactory接口

/**
 * 类描述: 文件分割器工厂接口
 */
public interface ISplitterFactory {

    public ISplitter createSplitter();

}

/**
 * 类描述: 二进制文件分割器工厂
 */
public class BinarySplitterFactory implements ISplitterFactory{

    @Override
    public ISplitter createSplitter() {
        return new BinarySplitter();
    }
}

/**
 * 类描述: 文件分割器窗体
 */
public class SplitterMainForm {

    // 文件路径
    private String filePath;

    // 文件被分割的个数
    private int fileNumber;

    private ISplitterFactory splitterFactory;

    public SplitterMainForm(String filePath,int fileNumber,ISplitterFactory splitterFactory) {
        this.filePath = filePath;
        this.fileNumber = fileNumber;
        this.splitterFactory = splitterFactory;
    }

    // 点击按钮
    public void onClick(String filePath,int fileNumber) {
        // SplitterMainForm 依赖抽象ISplitterFactory接口。
        ISplitter splitter = splitterFactory.createSplitter();
        splitter.split(filePath,fileNumber);
    }

}

问题SplitterMainForm依赖具体的BinarySplitter分割器解决,现在SplitterMainForm 依赖抽象ISplitterFactory接口。
疑问:虽然SplitterMainForm类现在不依赖具体工厂类,是通过参数的形式传递过来的,那么肯定在某个代码的位置,还是要创建具体的工厂,
那么问题不又回来了嘛。是的,确实是在某个地方又出现了依赖具体类。然而,我们知道软件设计模式,是封装变化,而不是消缺变化。变化我们
是消除不了的,我们只能把变化赶到一起集中管理起来。某软件知名大师曾经说过,把猫关进笼子里。例如整洁的房间,好动的猫,
如何保证房间的整洁,那就把它关在笼子里

定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法模式使得一个类的实例化延迟(目的:解耦)到子类。

通俗说

它为类提供了一种把实例化的逻辑委托给子类的方式。

维基百科

在基于类的编程中,工厂方法模式是一种创建型设计模式用来解决创建对象的问题,而不需要指定将要创建对象的确切类。
这是通过调用工厂方法创建对象来完成的,而不是通过调用构造器。该工厂方法在接口中指定并由子类实现,或者在基类实现并可以选择由子类重写。

JAVA案例

java.util.Calendar
java.util.ResourceBundle
java.text.NumberFormat
java.nio.charset.Charset
java.net.URLStreamHandlerFactory
java.util.EnumSet
javax.xml.bind.JAXBContext

总结

  1. 工厂方法模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。
  2. 工厂方法模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好的解决了这种紧耦合关系。
  3. 工厂方法模式解决"单个对象"的需求变化,缺点在于要求创建方法/参数相同。
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值