前言:在学习c++设计模式后对于工厂模式的理解(由于笔者现在目前在使用java语言进行学习,所以代码片段是使用java来进行编写的可能有些地方会有错误,希望大家能够指正,同时希望大家能够沉下心来看本篇文章篇幅会比较长)
首先我们先来实现一个小需求,我们要实现两种分割方式,一种是普通的分割方式,一种是vidio分割方式
我们一般来说会通过以下代码片段来实现
public class Button1 {
public static void main(String[] args) {
//紧耦合
vidioSplitter vidioSplitter = new vidioSplitter();
vidioSplitter.split();
}
}
public class FilterSplitter {
public void spilt(){
System.out.println("执行分割方法");
}
}
class vidioSplitter {
public void split(){
System.out.println("执行vidio分割方法");
}
}
我们只需要在主程序中new出我们希望执行的分割方法就可以达到实现的目的。但这种设计方式有一个问题,当我们需求变更的时候比如说我们又需要实现xxx分割方式,就会需要改全片幅的一个代码,原因就是我们代码中
//紧耦合
vidioSplitter vidioSplitter = new vidioSplitter();
vidioSplitter.split();
这个地方出现了紧耦合就是说我们对程序进行编译的时候程序需要知道我们new的这个对象是哪一个指定的对象,在这里引出一个设计原则
依赖倒置原则:
- 高层模块(稳定)不应该依赖低层模块(变化),二者都应该依赖于抽象(稳定)
- 抽象(稳定)不应该依赖于实现细(变化),实现细节应该依赖于抽象(稳定)
就用上面的例子进行解释,在上面很明显我们的主程序依赖了vidioSplitter()这个具体的类,违反了依赖倒置原则高层模块(主程序)依赖了低层模块(vidioSplitter)
接下来对于我们的程序进行修改
首先,对于类的特征进行一个提取,都是实现xxx分割,提取出一个抽象类
public interface splitMethod {
void split();
}
然后让对应的需求去实现这个接口并重写实现细节
//第一个实现类
public class FilterSplitter implements splitMethod{
public void split() {
System.out.println("Filesplit");
}
}
//第二个实现类
class vidioSplitter implements splitMethod{
public void split() {
System.out.println("vidiosplit");
}
}
实际上使用接口是为了将我们的实现类(变化)进行一个隔离,从而提升我们代码的一个复用性
主程序
public static void main(String[] args) {
splitMethod splitMethod = new FilterSplitter();
splitMethod.split();
}
可能大家都发现了,虽然说我们确实是利用多态来实现了动态的调用split()
方法,但是还是有new FilterSplitter()
这样紧耦合的代码出现,接下来就要引出我们本文的正题工厂模式的使用.
在这里我引用我在学习中学到的一句话就是说我们在学习设计模式的时候不应该去关注xxx设计模式是什么样子的,而是应该关注xxx设计模式解决了一个什么样的一个问题,应该在什么样的场景下去应用这么一个设计模式来帮助我们写出更好的代码。
很明显工厂模式主要是用来帮助我们解决上面这样一个紧耦合的一个问题,工厂模式顾名思义,就是利用一个工厂来帮我们生产出我们想要的东西,
进一步对上面的代码进行修改
工厂类
class FilterSplitterFactory implements factoryCreate{
public splitMethod Create() {
return new FilterSplitter();
}
}
class vidioSplitterFactory implements factoryCreate{
public splitMethod Create() {
return new vidioSplitter();
}
}
主程序
private factoryCreate factoryCreate;
public Button1(factoryCreate factoryCreate){
this.factoryCreate = factoryCreate;
}
public void click(){
splitMethod splitMethod = this.factoryCreate.Create(); //多态创建
splitMethod.split();
}
public static void main(String[] args) {
Button1 button1 = new Button1(new FilterSplitterFactory());
button1.click();
}
可能这里就会用读者问"这不还是依赖了FilterSplitterFactory
"这个具体类吗,其实这个东西就像一个兔子,一开始它在我们的程序中跳来跳去就会显得特别难管理,我们设计模式不是将兔子给进行消除,而是相当于将兔子关进”笼子“里面以便我们对其进行管理,程序本质上一定是会有一个地方需要依赖的。
最后提一嘴,抽象工厂模式本质上和工厂模式是一样的,只不过抽象工厂是将一系列具有联系的对象一起进行创建,比如进行数据库连接时的那些对象。