对象创建模式之工厂方法模式(Factory Method)_~青萍之末~的博客-程序员宅基地

技术标签: 工厂方法模式  设计模式  

一、概念

  定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。 —《设计模式》Gof

二、动机

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

  如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合

三、源代码讲解

class FileSplitter
{
    
public:
    void split(){
    
        //...
    }
};

class MainForm : public Form
{
    
    TextBox* txtFilePath;    //文件路径
    TextBox* txtFileNumber;    //希望分割的个数
    ProgressBar* progressBar;

public:
    void Button1_Click(){
    
        //收集到用户输入的参数信息
        string filePath = txtFilePath->getText();    
        int number = atoi(txtFileNumber->getText().c_str());
        //传递给FileSplitter,让该类去分割文件
        FileSplitter splitter(filePath, number, progressBar);
        //进行分割
        splitter.split();
    }
};

  动态看待问题,上面使用了具体细节类,是静态特质,定死了,我们应该去判断业务有没有需求的变化,是不是只需要文件分割。比如我们这里有变化,支持二进制,图片,视频,文本分割…,此时我们应该将他声明为抽象基类来使用。

四、使用工厂方法模式进行改进

class MainForm : public Form {
    
    SplitterFactory *factory; // 工厂
public:
    MainForm(SplitterFactory *factory) {
    
        this->factory = factory;
    }
    
    void Button1_Click() {
    
    	// 通过虚函数来实现多态new,避免直接使用new创建对象
        ISplitter *splitter = factory->CreateSplitter(); 
        splitter->split();
    }
};

// 抽象类
class ISplitter {
    
public:
    virtual void split() = 0;
    virtual ~ISplitter() {
     }
};

// 具体类
class BinarySplitter : public ISplitter {
    

};

class TxtSplitter: public ISplitter {
    
    
};

class PictureSplitter: public ISplitter {
    

};

class VideoSplitter: public ISplitter {
    
    
};

// 工厂基类
class SplitterFactory {
    
public:
    virtual ISplitter *CreateSplitter() = 0;
    virtual ~SplitterFactory() {
     }
};

// 具体工厂
class BinarySplitterFactory: public SplitterFactory {
    
public:
    virtual ISplitter* CreateSplitter() {
    
        return new BinarySplitter();
    }
};

class TxtSplitterFactory: public SplitterFactory {
    
public:
    virtual ISplitter* CreateSplitter() {
    
        return new TxtSplitter();
    }
};

class PictureSplitterFactory: public SplitterFactory {
    
public:
    virtual ISplitter* CreateSplitter() {
    
        return new PictureSplitter();
    }
};

class VideoSplitterFactory: public SplitterFactory {
    
public:
    virtual ISplitter* CreateSplitter(){
    
        return new VideoSplitter();
    }
};

五、类图结构

在这里插入图片描述

六、要点总结

  • Factory Method 模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。

  • Factory Method模式通过面向对象的手法(多态),将所要创建的对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。

  • Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/daaikuaichuan/article/details/103685432

智能推荐

【源码篇】Flutter GetX深度剖析 | 我们终将走出自己的路(万字图文)_小呆呆666的博客-程序员宅基地_flutter getx原理

前言人心中的成见是一座大山,任你怎么努力都休想搬动。这是电影《哪吒》里申公豹说的一句话,也是贯彻整部电影的一个主题;或许这句话引起了太多人的共鸣:35岁职场危机,大厂卡本科学历,无房无车结婚难等等,所以,这句话也经常被人提起。同时,因为GetX作者的一些言论,也让一些成见一直伴随着GetX这个框架。我写这篇文章,并不是为GetX正名我自问自己并不是任何一个状态框架的死忠者,Provider和Bloc,我写了相关使用、原理剖析文章和相关代码生成插件在我心中,这类框架并没有多么神秘因为对其.

UNP Chapter 23 - 线程_weixin_30735745的博客-程序员宅基地

23.1. 概述在传统的UNIX模型中,当一个进程需要由另一个实体执行某件事时,该进程派生(fork)一个子进程,让子进程去进行处理。UNIX下的大多数网络服务器程序都是这么编写的,这在我们的并发服务程序例子中可以看出:父进程接收连接,派生子进程,子进程处理与客户的交互。虽然这种模式很多年来使用的很好,但是fork有一些问题:1. fork是昂贵的。内存映像要从父进程拷贝到子进程,所有...

oracle 任意结果集交集,oracle两个结果集取交集 sql语句取交集_愚夫股份的博客-程序员宅基地

Oracle求两个结果集的交集?从表1a,表2B中选择a.id,a.name其中substr(a.name,1,1)=b.value使用union all可以实现Oracle中union和union all之间的差异。如果需要整体显示两个select语句的结果,则需要使用关键字Union或Union all。Union(或Union)的功能是同时显示多个结果。union和union all的区别在...

公众号内容拓展学习笔记(2021.3.21)_CV_七少的博客-程序员宅基地

公众号内容拓展学习笔记(2021.3.21)???? 今日要点2021年!955互联网公司白名单来了 ️软件开发工程师平均薪资,找工作的时候可以参考深入探讨:为什么要做特征归一化/标准化? ️有关特征归一化比较详尽的解释说明如何使ResNet优于EfficentNet?改进训练方法和扩展策略 ️️️论文:Revisiting ResNets: Improved Training and Scaling Strategies

Android图片二进制与Bitmap、Drawable之间的转换_quentain的博客-程序员宅基地

Android图片二进制与Bitmap、Drawable之间的转换Java代码 public byte[] getBitmapByte(Bitmap bitmap){ ByteArrayOutputStream out = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG,

随便推点

android.support.v4.app.Fragment_yixueshi9268的博客-程序员宅基地_android.support.v4.app.fragment

package com.example.duoduo.festival_sms;import android.os.Bundle;import android.support.design.widget.TabLayout;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentPager

note_nchen123的博客-程序员宅基地

http://divineka.googlepages.com/godisagirl.wmahttp://tophoo.googlepages.com/http://google.tohot.com/gmail/http://www.google.com/support/analytics/bin/answer.py?answer=26908&topic=7174http://www.pa

jsp九大内置对象以及对应的api_yzx_lemon的博客-程序员宅基地_jsp的api

1.JSP 中的九大内置对象   out          JspWriter             向jsp对应位置输出内容  request      HttpServletRequest    封装Http请求信息的对象   response     HttpServletResponse   封装Http响应信息的对象   session      HttpSession    ...

ARM9流水线(转)_harrymore2011的博客-程序员宅基地

ARM7采用三级流水线的冯·诺伊曼结构,ARM9采用五级流水线的哈佛结构。ARM7流水线包括取指(fetch)、译码(decode)、执行(excute)。ARM7流水线在译码阶段不读取操作数寄存器,因此执行阶段的PC值和取指阶段的PC值关系为:PC(excute)=PC(f

Trusty API Reference_Vincent8080的博客-程序员宅基地

Trusty API ReferenceThe Trusty API generally describes the Trusty inter-process communication (IPC) system, including communications with the non-secure world. This page defines the relevant terms a...

【工具/HTTP】HTTP抓包工具推荐_我是Superman丶的博客-程序员宅基地

一、Charleshttps://www.charlesproxy.com/个HTTP代理服务器 可以抓包!二、待补充

推荐文章

热门文章

相关标签