设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。设计模式的某一个模式,是用来解决某一种特定场景。当我们要创建某个类的对象,如果面临着多样化的创建类的需求,那么我们可能会发现仅仅使用new来创建,不如使用工厂模式来的畅快。
工厂模式中的简单工厂模式是对创建类这个动作的封装。正如我之前学习java的时候,数据封装类似。
数据封装是java一个比较简单的知识点,手法是将变量设为private,然后用set和get方法来改变和设置这个变量。对于这个变量而言,如果在多个其他类中都用到了,那么使用
set和get方法比直接调用数据,直接修改数据要好很多。
但是,如果仅仅本类中使用或者使用地方就一两处,那么set和get方法和直接调用相比就没有明显的优势了。
工厂模式的本质是封装类的创建,用一个create方法来创建新的类。和数据封装类似,如果仅仅一两处在创建明确的对象,那么工厂模式没有明显的优势。
那么,在哪些场景下需要使用工厂模式呢?
我们标准定义的工厂模式包括简单工厂模式、工厂方法模式、抽象工厂模式。这样看工厂模式是指通过方法可以选择性创建希望创建的对象,且该方法可以创建的对象不止一个。
但是如果把工厂模式作为像数据封装那样的一种封装创建对象的基础编程手段,那么单例模式也可以归于工厂模式。
所以本次将讨论单例模式、简单工厂模式、工厂方法模式、抽象工厂模式的意义。
单例模式,一个类只创建一个对象,其他所有类中都在调用这个对象,下面提供两种最常用的单例模式,同样单例模式基本也就这两种用法。
这个类有一个静态的getInstance() 方法,在其他地方使用Singleton .getInstance()就可以创建这个类的对象,此外在单例模式中,其他类只能通过getInstance()方法创建对象,而getInstance()不会多次创建对象,也就是整个程序没有办法在创建了一次对象之后,再次创建一次对象。所以,整个程序中只有一个对象,也就是单例模式了。
public class Singleton {
private Singleton() {}
private static Singleton single=null;
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = new Singleton1();
public static Singleton1 getInstance() {
return single;
}
}
个人觉得单例模式是一个工厂模式,但实际上,至少各位大神的统一观念的,单例模式使用了工厂模式,而不是工厂模式。
本文不关注这个概念上的分类,重要还是体会这种模式的使用场景,提高编程水平。
正如开篇所说,在其他类中,直接new Singleton 的对象是无法满足,单例的要求。于是通过一个静态方法类创建该对象。在这个静态方法中,我们有了很多的操作空间来满足创建对象的复杂性。
通过一个类的静态方法来创建对象,就叫做静态工厂模式,又叫做简单工厂模式。我们为了满足相对复杂的对象创建,专门创建一个类,这个类里面的有一个静态方法,专门用来创建对象,我们通过这个类直接调用静态方法来完成复杂类的创建,那么这个类就叫做工厂类。
一种复杂的对象创建是很多子类的创建。提到这里,我就想到了策略模式。策略模式是一个典型容易出现多个平行子类的场景。
当我们使用策略模式对算法进行封装后,很容易产生很多种不同算法(例如排序方式)。在使用算法的时候,就需要创建对象。不同情况下,创建不同的算法对象。这个时候,可以使用一个参数int作为选择的参数,然后通过工厂类传入int参数后,有工厂类中的静态创建算法的方法来创建对应的类。
那么,现在考虑另外一种情况:创建对象本身的复杂性。
创建某个对象有许多连带的行为,包括创建类构造器本身参数比较复杂,需要从其他多个类获取较多信息来组成这个构造器的参数。
创建完对象需要在对象上做一系列基本设置。
比如:android的组件作为对象创建是否touthable?是否focusable?是否要设置背景等等。
在前面说过,工厂模式的意义是建立在整个程序有多处在创建这个对象。往往也是针对比较大型的程序。
面对单次创建对象流程比较复杂,同时,这种创建对象的次数还较多。那么,肯定不建议在每个需要创建对象的地方都将这个流程走一遍。
可以想象,如果采用每个需要创建复杂对象的地方,都设置一边相关参数,那么一旦在创建流程中有一点修改,比如桌面程序,需要创建桌面的图标,这个创建图标的地方很多,如果我要把图标缩小一点点。那么,要修改多少个地方。
如果在设计初期采用工厂方法,将整个对象的创建流程封装到一个方法中(很多时候为了有这么一个方法,我们会创建一个专门的类来放这个方法,这个类即工厂类)那么在开发调试,以及后期维护,难度就大幅度下降了。
可以说,单例模式是最为常用的工厂模式之一。
在大多数情况下,像单例模式这样,将创建对象用一个静态方法封装起来,就叫做工厂模式。
只要场景不是特别复杂,比如上万行的代码,上百个类和对象这样,简单工厂模式完全够用。
关于更复杂的工厂方法模式和抽象工厂模式,在下一章,我将继续学习和思考。