工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。
工厂模式主要有:
简单工厂模式,工厂方法,抽象工厂;
简单工厂:
又叫静态工厂,是工厂模式三中状态中结构最为简单的。主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。我们来看一个具体的例子:
如下面价单的图形
![]()
代码如下:
首先我们先创建一个抽象的产品:
1 package Factory;
2
3 public abstract class BMW {
4
5 public BMW() {
6 }
7
8 }
然后我们具体的产品类去继承我们的抽象产品:
1 public class BMW320 extends BMW{
2 public BMW320() {
3 // TODO Auto-generated constructor stub
4 System.out.println("生产BMW320");
5 }
6 }
7
8
9
10
11
12 public class BMW523 extends BMW{
13 public BMW523() {
14 // TODO Auto-generated constructor stub
15 System.out.println("生产BMW523");
16 }
17 }
下面我们创建我们的工厂:
1 package Factory;
2
3 public class Factory {
4 public BMW crateBMW(int type){
5 if(type==320){
6 return new BMW320();
7 }else if (type==523){
8 return new BMW523();
9 }else{
10 return null;
11 }
12 }
13 }
下面就是客户了,客户需要产品,我们进行生产:
1 package Factory;
2
3 public class Customer {
4 public static void main(String[] args) {
5 Factory f=new Factory();
6 BMW b320=f.crateBMW(320);
7 BMW b523=f.crateBMW(523);
8 }
9 }
运行的结果如下-----:
![]()
这个就是简单的工厂模式;
上面的代码告诉我们,简单工厂并不简单,它是整个模式的核心,一旦他出了问题,整个模式都将受影响而不能工作,为了降低风险和为日后的维护、扩展做准备,我们需要对它进行重构,引入工厂方法。
工厂方法:
工厂方法其实就是,不同额工厂对应不同的产品,就算其中某一个工厂不能正常工作了,也不会影响到其他的工厂工作;
![]()
首先我们先创建 产品接口和对应的具体产品
1 public interface Product {
2
3 }
4
5
6 public class Washer implements Product{
7
8 public Washer() {
9 System.out.println("洗衣机被制造了");
10 }
11
12 }
13
14
15
16 public class AirCondition implements Product{
17
18 public AirCondition() {
19 System.out.println("空调被制造了");
20 }
21 }
然后我们再创建 工厂接口和对应的具体生产不同商品的工厂
public interface Factory {
}
public class WasherFactory implements Factory{
public Product make(){
return new Washer();
}
}
public class AirConditionFactory implements Factory{
public Product make(){
return new AirCondition();
}
}
最后就是顾客了,
1 package Factory2;
2
3 public class Customer {
4
5 public static void main(String[] args) {
6 // TODO Auto-generated method stub
7
8 WasherFactory f=new WasherFactory();
9 Product w=f.make();
10
11 AirConditionFactory f2=new AirConditionFactory();
12 Product w2=f2.make();
13 }
14 }
运行的结果为:
![]()
可以理解为:有了很多个工厂方法,自己需要哪一个产品,就调用当前产品的工厂方法,获取相应的具体实例。
从上面创建产品对象的代码可以看出,工厂方法和简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。但工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产家电外产品,还生产手机产品,这样一来家电是手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了传说的类爆炸,对于以后的维护来说,简直就是一场灾难.....
抽象方法:
抽象工厂:意的意图在于创建一系列互相关联或互相依赖的对象。
我自己觉得抽象工厂是在工厂方法的基础上引进了分类管理的概念....
工厂方法用来创建一个产品,它没有分类的概念,而抽象工厂则用于创建一系列产品,所以产品分类成了抽象工厂的重点,
我们继续用上面的例子来说明:
工厂生产的所有产品都用都用大写字母来标明它们的型号,比如冰箱,就有“冰箱-A",“冰箱-B",同样,其他的产品也都是遵守这个编号规则,于是就有了一下产品家族树
![]()
首先:我们创造不同的 电视和鼠标的接口:
1 public interface TV {
2 }
3
4
5 public interface Mouse {
6
7 }
然后我们创造冰箱和鼠标的不同的品种:
1 public class TV_A implements TV{
2
3 public TV_A() {
4 System.out.println("A型TV");
5 }
6
7 }
8
9
10 public class TV_B implements TV{
11
12 public TV_B() {
13 System.out.println("B型TV");
14 }
15
16 }
17
18
19 public class Mouse_A implements Mouse{
20
21 public Mouse_A() {
22 System.out.println("A型鼠标");
23 }
24
25 }
26
27
28 public class Mouse_B implements Mouse{
29
30 public Mouse_B() {
31 System.out.println("B型鼠标");
32 }
33
34 }
最后就等到了不同类型的工厂,生产不同类型的产品。如A工厂只生产A类型的产品
public class Factory_A implements Factory{
@Override
public TV createTv() {
// TODO Auto-generated method stub
return new TV_A();
}
@Override
public Mouse createMouse() {
// TODO Auto-generated method stub
return new Mouse_A();
}
}
public class Factory_B implements Factory{
@Override
public TV createTv() {
// TODO Auto-generated method stub
return new TV_B();
}
@Override
public Mouse createMouse() {
// TODO Auto-generated method stub
return new Mouse_B();
}
}
最后就是测试类:
1 package Foctory3;
2
3 public class Customer {
4 public static void main(String[] args) {
5 Factory f=new Factory_A();
6 f.createTv();
7 f.createMouse();
8
9 f=new Factory_B();
10 f.createTv();
11 f.createMouse();
12 }
13 }
运行结果如图所示:
![]()
欢迎大家一起说出自己的想法。