工厂模式可以分为:简单工厂模式,工厂方法模式,抽象工厂模式。
简单工厂模式就没什么好说的了,无非是所有的东西都写在一个类里面,要什么就调用什么,如果要添加新的方法也是到这类里面添加,代码很多,看起来也是很乱,就像一个大工厂,什么都在里面。扩展性很低。
而工厂方法模式,把说明的理论和生产的东西就分开一点。抽象工厂模式是工厂方法模式的升级。
工厂方法模式(Factory Method Pattern),又叫虚拟构造函数模式或者多态行工厂模式。
工厂方法模式定义一个创建产品对象的工厂接口,将实际创建性工作推迟到子类中。
工厂方法模式和抽象工厂模式都是将实际创建的工作推迟到子类。
这里不要被这两种模式的名字所蛊惑!什么工厂方法!什么抽象工厂!其实就是java三大特征之继承性的一个抽象表现形式。不要以为工厂模式就不抽象,这是非常错误的想法!
抽象工厂是工厂模式的进一步升级。
怎么理解这里的进一步升级呢?
其实吧,工厂方法模式的使用中一个工厂(抽象工厂类)是对应一个实际产品的,而抽象工厂的一个工厂是对应几个相关的产品的。
也就是说最大区别就在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂则需要面对多个产品等级结构。
上面的观点论述是我看过多次工厂方法模式总结出来的,还是比较贴实。如果还不是不太会区分这两种模式的区别,最好的方法就是好好看看这两种模式的类图和代码区别,你就会有深刻的认识了!我也是懵了好久才弄懂的。
理解类图对理解设计模式是非常有帮助的,避免你不必要的顾虑。
从上面看工厂模式原来也不难嘛。其实就是不能难,只要你慢慢去理解,想得不要太复杂。
类实现接口用虚线加空心三角箭头
类/接口相关有虚线加箭头(不是三件)
类继承类用实线加空心三角箭头。
。。。
还有一些其他的说明以后再详细说。
上面几个有点你在看完这篇文章,熟知工厂方法模式后,再回来细细品味就会更有味道。
工厂方法模式还可以与其他模式混合使用(单例模式、原型模式)
应用场景没有必要纠结那么多,等你熟知很多设计模式后,你的代码设计思维自然会严谨、扩展性好一些。
问题是要熟知,不然知一半用一半,后期维护是更加麻烦的事情,还不如不用。
这里以生产力两个不同的奔驰车的型号的车辆为实例,进行模式的详细演示
这里假设设计出车子的颜色,速度,价格就生产出一辆车子了,不要跟我说实际生产车的几十个步骤,这里不想搞那么复杂。
可以对比看到,工厂方法模式实例类图中的框架和工厂方法模式的类图框架是保持一致的。
工厂方法设计模式就是这么简单。你可以看一下代码,理解一下。
package p2_factoryMethod;
/**
* 奔驰产品的抽象接口
*/
public interface Benz {
void carColor();//设置颜色
void carSpeed();//设置速度
void carPrice();//设置价格
}
package p2_factoryMethod;
/**
* 奔驰工厂的抽象接口
*/
public interface BanzFactory {
/**
* 创建奔驰的方法
*/
Benz createCar();
}
package p2_factoryMethod;
/**
* 生产某一个型号奔驰车辆的实际工厂
*/
public class C180Factory implements BanzFactory {
@Override
public Benz createCar() {
return new BenzC180();
}
}
package p2_factoryMethod;
/**
* 生产某一个型号奔驰车E260辆的实际工厂
*/
public class E260Factory implements BanzFactory {
@Override
public Benz createCar() {
return new BenzE260();
}
}
package p2_factoryMethod;
/**
* 奔驰C180的生产的具体类
*/
public class BenzC180 implements Benz {
/**
* 构造方法,创建的时候就设置基本属性
*/
public BenzC180() {
carColor();
carPrice();
carSpeed();
}
@Override
public void carColor() {
System.out.println("奔驰C180的颜色是银白色");
}
@Override
public void carSpeed() {
System.out.println("奔驰C180的速度是200公里每小时");
}
@Override
public void carPrice() {
System.out.println("奔驰C180的价格是100万");
}
}
package p2_factoryMethod;
/**
* 奔驰E260的生产的具体类
*/
public class BenzE260 implements Benz {
/**
* 构造方法,创建的时候就设置基本属性
*/
public BenzE260() {
carColor();
carPrice();
carSpeed();
}
@Override
public void carColor() {
System.out.println("奔驰E260的颜色是银白色");
}
@Override
public void carSpeed() {
System.out.println("奔驰E260的速度是200公里每小时");
}
@Override
public void carPrice() {
System.out.println("奔驰E260的价格是100万");
}
}
这里嘛,只要new出具体生产奔驰车辆的类,就相当于生产了一辆车,因为在构造方法里面已经开始执行生产的步骤了。当然你也是可以不在构造方法执行的,你可以使用车辆对象来调用那几个步骤。
这个类可以不算设计模式中的框架内容,但是也可以算是框架的一部分!
package p2_factoryMethod;
/**
* 生产两个奔驰车C180和E260的演示
* 这里使用多态的方法类创建各个类别的车型产品
*/
public class FactoryMethodDemo {
public static void main(String[] a) {
System.out.println("生产奔驰车C180");
//父类但对象子类的实例
BanzFactory banzFactory = new C180Factory();//创建一个C180工厂
//调用父类的方法,这就是java多态的一种体现
banzFactory.createCar();//C180工厂生产车辆C180
System.out.println("=========================================");
System.out.println("生产奔驰车Z260");
BanzFactory banzFactory2 = new E260Factory();
banzFactory2.createCar();//E260工厂生产车辆E260
}
}
程序运行的结果:
从这个生产奔驰车辆的实例中,有人可能会决定这样写是有点麻烦了,几句话就搞定的东西,非要弄这么多类和方法出来。。。
但是这只是一个简单的实例演示而已,实际工程中一个类可能有几百几千行代码。。。
一个类的生产工程可能包含几十个步骤,如果我们不把这些分开一下,是很容易弄乱的。。。
其实最最重要的一点就是扩展性很好。
比如说,你还要生产一个奔驰车子CC888,那么你只需要创建一个生产CC888的实际生产类和一个CC888的实际工厂类,它们的生产规则和基本步骤都已经完善了,你只要设置你想要的参数就可以得到你想要的产品了。。。同样你想要几十个几百个这样的产品,你也是可以这样简单做到,但是你把所有产品写在一个类里面,我们就会发现代码的臃肿性,所以工厂方模式的好处就是扩展性好,但是你也是要分清场合,并不是所有的东西需要扩展和能扩展的!
定义接口对很多初学者来说是一件麻烦并且感觉没有必要的事情。
但是随着我们接触项目越来越多,看到的代码越来越多,就会发现一个问题,这个类那么多方法,那么多代码,一段时间后在想在某一个类中找到某一个方法是有点困难的,特别是对那个方法不是很记得的情况下,你要慢慢看整个类才能找到。
上面的情况下,如果你定义了一个接口,接口有什么?不就是只有方法吗?一个方法就一行代码,哪怕是几十个方法,也就几十行代码,跟一个具体实现类的几百几千行代码,那是没得比的,几十行代码一眼就看完了!
这里具体实现类是继承了接口的,所有你调用接口的方法和调用实现类的方法效果就是一样的啊。
所有像一些重要的、方法多的类,一定要写一个接口,并且在接口方法中简单说明一下这个方法的作用。
比如我在登录界面会写一个接口ILongin,接口中定义一些必须要实现的方法:判断网络、获取用户名、获取密码、登录。。。
这样我就不会忘记一些东西或步骤,同样我也可以在我其他的项目中把这个接口用进去。
其实嘛,接口的作用就相当于我们生活中点菜的菜单,我们去餐厅点菜,我们只能看到菜单,看不到里面的实际操作步骤和详细过程(厨师知道就可以了),也不需要关心,对着菜单就能吃到我们想要吃的菜了。
后面马上就是介绍抽象工厂模式。
之前也详细介绍过了单例模式:http://blog.csdn.net/wenzhi20102321/article/details/77882203
java 23种设计模式介绍:http://blog.csdn.net/wenzhi20102321/article/details/54601909