8. 对象创建——工厂方法

本文介绍了如何通过简单工厂模式和工厂方法模式在文件分割功能中降低对象创建的紧耦合,从直接依赖具体类到逐步解耦并引入接口和工厂,以适应需求变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

“对象创建” 模式

  • 通过 “对象创建” 模式绕开 new,来避免 new 导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
  • 典型模式:
    • 简单工厂模式
    • Factory Method
    • Abstract Factory
    • Propotype
    • Builder

一、代码示例

**背景:**我们要实现一个文件分割的功能,包括分割文本文件、二进制文件、视频文件。

实现方式1

后台程序:

interface ISplitter{
    void split();
};

class BinarySplitter implements ISplitter{
    public void split() {
        System.out.println("分割二进制文件");
    }
};

class TxtSplitter implements ISplitter{
    public void split() {
        System.out.println("分割文本文件");
    }
};

class VideoSplitter implements ISplitter{
    public void split() {
        System.out.println("分割视频文件");
    }
    
};

客户端程序

class MainForm extends public Form
{
	TextBox txtFilePath;
	TextBox txtFileNumber;
	ProgressBar progressBar;

	public void Button1_Click(){
		ISplitter splitter = new BinarySplitter();//依赖具体类
        
    splitter.split();
	}
};

**分析:**在MainForm中需要创建Splitter,这种方式导致依赖了具体的Splitter,MainForm和Splitter存在紧耦合的关系,如果想要替换Splitter就必须修改MainForm中的代码。

**解决办法1:**使用简单工厂模式解决。在MainForm中通过参数接受一个标识,该标识再传递到简单工厂中,创建Splitter对象。即像下面的代码:

class SimpleSplitterFactory {
    public ISplitter creatSplitter(String flag) {
        ISplitter splitter;

        switch(flag) {
            case "binary":
                splitter = new BinarySplitter();
                break;
            case "txt":
                splitter = new TxtSplitter();
                break;
            case "video":
                splitter = new VideoSplitter();
                break;
            default:
                splitter = null;
        }

        return splitter;
    }
}

class MainForm extends public Form
{
    TextBox txtFilePath;
    TextBox txtFileNumber;
    ProgressBar progressBar;

    String flag;

    public MainForm(String flag) {
      this.flag = flag;
    }

    public void Button1_Click(){
          SimpleSplitterFactory factory = new SimpleSplitterFactory();

          ISplitter splitter = factory.creatSplitter(flag);
          splitter.split();
    }
};

**分析:**此时,MainForm与具体Splitter分割开来,但是MainForm又与SimpleSplitterFactory绑定,SimpleSplitterFactory与具体Splitter绑定,导致MainForm与具体的Splitter存在间接绑定。

**解决办法2:**在简单工厂的实现中,我们在MainForm中接受了一个用于标识创建哪个Splitter的flag,既然我们都传flag了,那么我们为什么不可以传递一个可以直接创建对应对象的工厂呢?此时就引出了工厂方法模式。

interface SplitterFactory {
    ISplitter createSplitter();
}

class BinarySplitterFactory implements SplitterFactory {
    public ISplitter createSplitter() {
        return new BinarySplitter();
    }
}

class TxtSplitterFactory implements SplitterFactory {
    public ISplitter createSplitter() {
        return new TxtSplitter();
    }
}

class VideoSplitterFactory implements SplitterFactory {
    public ISplitter createSplitter() {
        return new VideoSplitter();
    }
}


class MainForm extends Form
{
    TextBox txtFilePath;
    TextBox txtFileNumber;
    ProgressBar progressBar;

    SplitterFactory factory;

    public MainForm(SplitterFactory factory) {
        this.factory = factory;
    }

    public void Button1_Click(){
          ISplitter splitter = factory.createSplitter();
          splitter.split();
    }
};

二、动机

​ 在软件体系中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常发生变化。为了应对这种变化,绕过常规的对象创建方法(new),需要提供一种 “封装机制” 来避免客户程序和这种 “具体对象创建工作” 的紧耦合。

三、定义

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

四、结构

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值