工厂方法模式-设计模式

导读:本篇文章讲解 工厂方法模式-设计模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

动机(Motivation)

  1. 在软件系统中,经常面临着创建对象的工作:由于需求的变化,需要创建的对象的具体类型经常变化。
  2. 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?
  3. 可以控制对象的生产过程,对对象做一些额外操作,权限、修饰、日志等等。

模式定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:接口)。

为什么要定义创建对象的接口,而不是用户直接调用具体的对象

  1. 因为创建对象通常不仅仅是一个new 操作,可能是一系列赋值操作,因此需要一个抽象创建对象接口提供一个创建方法。

类图

在这里插入图片描述

实例

未使用工厂方法之前

  1. 场景
    不同种类的分割器,分割器的使用者需要分割不同类型的东西,比如分割文件、视频等。
  2. 抽象一个分割器接口,抽象出一个稳定接口, 这样分割器就可以自由的扩展了。
public interface ISplitter {
  void split();
}
  1. 文件分割器、视频分割器分别实现抽象的分割器接口
public class FileSplitter implements ISplitter {
    @Override
    public void split() {
        System.out.println("File split");
    }
}
public class VideoSplitter implements ISplitter {
    @Override
    public void split() {
        System.out.println("Video split");
    }
}
  1. 创建分割器工具,用于作为用户调用分割器的框架
public class SplitterTool {
    public void split() {
        // 依赖了具体的类,违反依赖倒置原则
        ISplitter splitter = new FileSplitter();
        splitter.split();
    }
}
  1. 物体分割器用户使用分割器分割不同类型的物体
public class SplitterUser {
    public static void main(String[] args) {
        SplitterTool tool = new SplitterTool();
        tool.split();
    }
}
// 执行结果
// File split
  1. 可以看出,用户不能方便的分割不同类型的问题,因为分割器工具与具体的文件分割器绑定了,违反了依赖倒置原则。代码出现了紧耦合。

使用工厂方法模式,构造稳定的分割器工具,使代码松耦合。

  1. 定义一个创建对象的接口
public interface SplitterFactory {
    ISplitter createSplitter();
}
  1. 实例化创建对象的接口,把具体的类型创建延迟到子类
public class VideoSpliiterFactory implements SplitterFactory {
    @Override
    public ISplitter createSplitter() {
        return new VideoSplitter();
    }
}
public class FileSpliiterFactory implements SplitterFactory {
    @Override
    public ISplitter createSplitter() {
        return new FileSplitter();
    }
}
  1. 改造分割器工具,使它成为稳定不变的框架工用户调用
public class SplitterTool {

    private SplitterFactory splitterFactory;

    public void setSplitterFactory(SplitterFactory factory) {
        this.splitterFactory = factory;
    }

    public SplitterTool(SplitterFactory splitterFactory) {
        this.splitterFactory = splitterFactory;
    }

    // 稳定不变,具体的工厂类有构造或者set方法传入
    public void split() {
        ISplitter splitter = splitterFactory.createSplitter();
        splitter.split();
    }
}
  1. 用户可以很方便的增加不同的分割器,需要可以方便的扩展,产品也可以方便的扩展,唯一的缺点就是类会成倍的扩展
public class SplitterUser {
    public static void main(String[] args) {
        SplitterTool tool = new SplitterTool(new FileSpliiterFactory());
        tool.split();
        tool.setSplitterFactory(new VideoSpliiterFactory());
        tool.split();
    }
}
  1. 可以看到变化点只在用户调用(用户肯定要知道需要什么,所以肯定是变化的,也是造成变化的源头),具体的工厂、具体的产品类是变化点,方便扩展,满足开闭原则;framwork和抽象的工厂、抽象的产品是不变的,framwork依赖抽象,framwork和抽象是所有设计模式的重点。

静态工厂方法

使用类的静态方法封装对象的生成,通常用来代替类的构造器,让代码更易读、易维护。
提高了类的提供者对自己提供的类的掌控力。

作为一个开发者,当我们作为调用方,使用别人提供的类时,如果使用new关键字来创建一个类实例时,如果对类不是特别熟悉,那么要一定特别慎重一一 new实在是太好用了,以致于它经常被滥用,随意的new是有很大风险的,除了可能导致性能、内存方面的问题外,也经常会使得代码结构变得混乱,难以维护。
当我们作为类的提供方时,无法控制调用者的具体行为,但是我们可以尝试使用一些方法来增大自己对类的控制力,减少调用方犯错的机会,这也是对代码更负责任的具体体现。

参考

关于 Java 的静态工厂方法,看这一篇就够了!

要点总结

  1. Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。
  2. Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好的解决了这种紧耦合关系。
  3. Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/100415.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!