欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式学习笔记(1):工厂模式

程序员文章站 2024-01-21 17:43:28
...
今天开始决定学习设计模式,教程是Pattern In Java,网上很有名的一本入门级设计模式教程。看了前面的大致介绍,语言确实很平实,丝毫不晦涩。决定每天学习一种模式,并记录下来,权当自己的加深理解的一种记录。

(注:里面有很多文字代码都是源自板桥里人的Pattern In Java,大家有兴趣可以参照原书地址:[url]http://www.jdon.com/designpatterns/index.htm[/url],我这里的所有文字仅当自己的备考,无侵权之意。特此声明。)

工厂模式(Factory)也许是最常用及常见的设计模式之一了,以前在读大学的时候经常听老师提起这个词汇,可是自己从来没有深入了解过到底它是一个什么东西?如何实现?有何优缺点?现在重新了解,希望不晚~
工厂模式其实简单来说,就是:[b][color=red]提供创建对象的接口。[/color][/b]不知你是否和我有相同的疑问,为什么我们需要一个接口来创建对象?创建对象不就是new一下就OK了吗?比如,我们有一个名为Sample的类,我们要创建它的对象:
Sample sample = new Sample();

假如我们需要在创建的时候有其他操作,比如赋值,那么可以使用构造函数:
Sample sample = new Sample(参数);

但是,假如我们在创建Sample对象的时候还有一系列的事情要做(通常情况都是这样),那么,如果把这些额外的需要做的一系列事情都放到构造函数中,则违背了OOP的思想:封装和分派。所以,我们需要把创建实例和使用实例分开来,使得语句:
Sample sample = new Sample(参数);

就是简单意义:使用这个实例,而具体内部是如何创建的,交给Factory模式去做吧。
还有一种情况是:如果Sample是父类,MySample这个类继承了Sample,按照面向接口编程。我们需要把Sample类抽象为一个接口。现在,Sample是一个接口,它有两个子类:MySample和HisSample,我们要实例化时,需要如下的操作:

Sample mySample = new MySample(参数);
Sample hisSample = new HisSample(参数);

随着项目深入,Sample可能会“生出”更多的“儿子”来,那么我们在实例化的时候需要将它们一一实例化,这些烦恼可以通过工厂模式很好的解决--如下建立一个专门“生产”Sample实例的工厂:

/*
* code1_1:工厂模式之工厂方法(Factory Method)
*/
public class Factory {
public static Sample creator() {

........

if(witch == 1) {
return new MySample();
}

if(witch == 2) {
return new HisSample();
}

}
}


那么,在程序中,要实例化MySample是,就使用:
Sample sample = Factory.creator();

这样,就不涉及到Sample的具体的子类,达到封装的效果。

在工厂模式中,分为两种:[b][color=red]工厂方法(Factory Method)[/color][/b]和[b][color=red]抽象工厂(Abstract Factory)[/color][/b]

上面提到的code1_1就是用的工厂方法,这种方法适用于:[b][color=red]创建简单的对象[/color][/b],如果创建对象的方法变得复杂了,那么我们可能会将上例中的Factory变为抽象类,将共同的部分封装在抽象类中,不同部分在子类中实现:


/*
* code1_2:抽象工厂(Abstract Factory)
*/
public abstract class Factory {
public abstract Sample1 creator();
public abstract Sample2 creator();
}

public class Simple1Factory extends Factory {
public Sample1 creator() {
//具体的实现
}

public Sample2 creator() {
//具体的实现
}
}

public class BombFactory extends Factory {
public Sample1 creator() {
//.........
}

public Sample2 creator() {
//.........
}
}