设计模式 -- FactoryMethod(工厂方法)
工厂方法(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模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)