首页 > 其他分享 >设计模式 -- FactoryMethod(工厂方法)

设计模式 -- FactoryMethod(工厂方法)

时间:2022-09-25 15:23:55浏览次数:46  
标签:-- void FactoryMethod public ISplitter Override 设计模式 class split

工厂方法(Factory Method)

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

在软件系统中,经常会面临着创建对象的工作,由于需求变化,需要创建的对象的具体类型也会经常的变化

假设还是拿之前的文件分割器作为例子,如果不使用具体的设计模式,那么在具体创建对象的时候,需要在初始化对象的时候指定出具体的实现细节,虽然ISplitter * splitter = new BinarySplitter(); 是面向接口的编程,将变量生命为了抽象的基类,但在实际new时,依赖了一个具体的实现类。实际上这里违反了依赖导致原则。如果这时候具体的Splitter还未完成实现,那么编译时会报错,如果需求发生变更那么此时,也需要重新修改和编译源代码。

原先

// 文件分割器接口
interface ISplitter {
    void split();
};

class BinarySplitter implements ISplitter {
    @Override
    public void split() {

    }
};

// 文件分割器具体实现类
class TxtSplitter implements ISplitter {
    @Override
    public void split() {

    }
};

// 文件分割器具体实现类
class PictureSplitter implements ISplitter {
    @Override
    public void split() {

    }
};

// 文件分割器具体实现类
class VideoSplitter implements ISplitter {
    @Override
    public void split() {

    }

};

public class FactoryMethod {
    @Test
    public void T1() {
        // 对象创建依赖了具体的类
        ISplitter splitter = new BinarySplitter();
        splitter.split();
    }
}

对于之前的代码,在应对变化时,ISplitter splitter = new BinarySplitter();这里是核心的问题。那么如何才能绕开new一个具体的细节呢?

那么我们可以使用一个函数,来讲所需要的对象返回给我们的方式来获取这个对象,为了代码的进一步隔离,我们把他直接抽象到一个新的类中,并用写成一个虚函数,由工厂的子类来自己实现创建自己的方法。也就形成了一个模式,每个实现方法有一个类,配套的每个类都有一个工厂,而这些工厂都继承自一个抽象的工厂。那么就得到了下面的代码。

重构

// 文件分割器接口
interface ISplitter {
    void split();
};

class BinarySplitter implements ISplitter {
    @Override
    public void split() {

    }
};

// 文件分割器具体实现类
class TxtSplitter implements ISplitter {
    @Override
    public void split() {

    }
};

// 文件分割器具体实现类
class PictureSplitter implements ISplitter {
    @Override
    public void split() {

    }
};

// 文件分割器具体实现类
class VideoSplitter implements ISplitter {
    @Override
    public void split() {

    }

};

// 文件分割器工厂接口
interface ISplitterFactory {
    ISplitter CreateSplitter();
}

// 具体工厂
class BinarySplitterFactory implements ISplitterFactory {
    @Override
    public ISplitter CreateSplitter() {
        return null;
    }
}

// 具体工厂
class TxtSplitterFactory implements ISplitterFactory {
    @Override
    public ISplitter CreateSplitter() {
        return null;
    }
}

// 具体工厂
class PictureSplitterFactory implements ISplitterFactory {
    @Override
    public ISplitter CreateSplitter() {
        return null;
    }
}

// 具体工厂
class VideoSplitterFactory implements ISplitterFactory {
    @Override
    public ISplitter CreateSplitter() {
        return null;
    }
}

public class FactoryMethod {
    ISplitterFactory factory;

    FactoryMethod(ISplitterFactory factory) {
        this.factory = factory;
    }

    @Test
    public void T1() {
        // 多态创建对象
        ISplitter splitter = factory.CreateSplitter();
        splitter.split();
    }
}

现在的工厂通过构造函数传入其中,依赖其实依旧存在,但是并没有具体类型的依赖,而依赖的都是接口类。其实对于设计模式来说,并没有办法消除依赖,而是将依赖控制在了最可控的地方。

总结

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

标签:--,void,FactoryMethod,public,ISplitter,Override,设计模式,class,split
From: https://www.cnblogs.com/tie-dao/p/16727921.html

相关文章

  • docker实战教程(九):本地镜像发布到阿里云
    流程构建镜像的两种方式:commit、dockerfilebuild推送到远程的两种方式:阿里云、私有库步骤选择控制台,进入容器镜像服务,创建个人版实例创建命名空间创建......
  • 五、pycharm的安装与基本使用
    目录一、pycharm的安装1、软件介绍2、正版安装1.下载软件2.安装软件3、其他方法安装(需要先下载相关资源)①无限试用法②傻瓜式激活法③淘宝购买二、pycharm软件的使用1.创建......
  • git rebase 使用
    1.GITREBASE使用说明gitrebase作用将提交进行合并有些时候,我们在开发的时候,可能在本地做了几次提交,但是这个提交是解决一个问题的,这个时候如果我们向远程推送的时......
  • py调jenkins接口发布-优化篇
    py调jenkins接口发布-优化篇之前写的文章,python调jenkins接口【https://www.cnblogs.com/windysai/p/16709313.html】,用于晚上10点后自动构建jenkins任务并发通知,但是......
  • Spring事务
             ......
  • ★★★PAT 1003 我要通过!Python
    ★★★PAT1003我要通过!Python题号:PATbasiclevel1003引文链接PAT-1003猫猫虫(——)-思路:正则匹配+数学归纳crayonJJ-注释补充:正则匹配菜鸟教程-Python正则表......
  • navigation 对象
    navigation对象​navigator对象包含有关浏览器的信息.它有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值。下面前......
  • prompt
    prompt()方法用于弹出框alert("请猜测一个1-100之间的数")vara=Math.floor(Math.random()*100);alert(a);while(1){......
  • LeetCode 1382. Balance a Binary Search Tree
    原题链接在这里:https://leetcode.com/problems/balance-a-binary-search-tree/题目:Giventhe root ofabinarysearchtree,return a balanced binarysearchtre......
  • 二叉树遍历
    应用实例代码实现publicclassBinaryTreeDemo{ publicstaticvoidmain(String[]args){ //先需要创建一颗二叉树 BinaryTreebinaryTree=newBinary......