java设计模式之工厂模式

一,为什么会出现工厂模式
话说在C语言这种面向过程的语言中,如果实现一个人去开车,是需要按照过程来一步一步的完成的。例如想开奔驰了,就会说“开奔驰车”,想开宝马了,就说“开宝马车”,想开奥迪了,就说“开奥迪车”。这样有没有觉得很麻烦?想到开什么车了,就必须要把车名也都带上(或者需要自己去生成一个车的对象来开)。
那么可不可以在Java语言中,充分的体现面向对象的特征呢?当然可以了,就是增加一个辅助的人来帮你,比如是一个司机。由他来具体负责今天开什么车,处理内部的逻辑,而你呢?只需要简简单单的说一句,“Drive!”。
所以工厂模式就出现了~~~你就好比一个客户端,司机就好比一个工厂,业务逻辑有它来处理。
二:什么是工厂模式?
1,工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。 (并且遵循开闭原则,即扩展开放,修改关闭)。
2,工厂模式按照《Java与模式》中的提法分为三类:
1. 简单工厂模式(Simple Factory) (简单工厂其实有点违背了工厂模式的开闭原则)
2. 工厂方法模式(Factory Method)
3. 抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
还有一种分类法,就是将简单工厂模式看为工厂方法模式的一种特例,两个归为一类。
3,在什么样的情况下我们应该记得使用工厂模式呢?大体有两点:
1.在编码时不能预见需要创建哪种类的实例。
2.系统不应依赖于产品类实例如何被创建、组合和表达的细节
三:
1,简单工厂(Simple Factory)
又叫静态工厂,是工厂模式三中状态中结构最为简单的。主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。我们来看一个具体的例子:
2,假设一家工厂,只生产洗衣机,有生产冰箱,还有空调等等..
我们先为所有产品定义一个共同的产品接口 (抽象产品角色,只代表某种产品,具体细节由具体的产品来实现)

Java代码 :
        public interface Product{}  

3,接着我们让这个工厂的所有产品都必须实现此接口 (具体产品角色,实现了具体产品的细节)

Java代码 :
        public class Washer implements Product{  
           public Washer(){  
               System.out.println("制造洗衣机");  
           }  
        }  

public class Icebox implements Product{  
           public Icebox(){  
               System.out.println("制造冰箱");  
           }  
        }  

public class AirCondition implements Product{  
           public Icebox(){  
               System.out.println("制造空调");  
           }  
        }  

4,接下来我们来写一个工厂类,有它来负责生产以上的产品 (工厂类角色,由他来实现一些逻辑和业务)

Java代码 :
        public class SimpleFactory {  
        public static Product factory(String productName) throws Exception{  
                if(productName.equals("Washer")){  
                    return new Washer();  
                }else if(productName.equals("Icebox")){  
                    return new Icebox();  
                }else if(productName.equals("AirCondition")){  
                    return new AirCondition();  
                }else{  
                    throw new Exception("没有该产品");  
                }  
            }  
        }  

5,好了,有了这个工厂类,我们就可以开始下定单了,SimpleFactory将根据不同的定单类决定生产什么产品。

Java代码 
        public static void main(String[] args) {  
            try {  
                      SimpleFactory.factory("Washer");  
                      SimpleFactory.factory("Icebox");  
                      SimpleFactory.factory("AirCondition");  
                    } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  

6,总结:由上面的代码可以看出,简单工厂的核心就是一个SimpleFactory类,他拥有必要的逻辑判断能力和所有产品的创建权利,我们只需要向把定单给他,就能得到我们想要的产品。这使用起来似乎非常方便。
但,实际上,这个SimpleFactory有很多的局限。首先,我们每次想要增加一种新产品的时候,都必须修改SimpleFactory的原代码(违背了开闭原则)。其次,当我们拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增,这对以后的维护简直就是恐怖两个字…
还有就是,整个系统都严重依赖SimpleFactory类,只要SimpleFactory类一出问题,系统就进入不能工作的状态,这也是最为致命的一点….
%以上的不足将在工厂模式的另外两种状态中得到解决%

四:
1,工厂方法(Factory Method)
上面的代码告诉我们,简单工厂并不简单,它是整个模式的核心,一旦他出了问题,整个模式都将受影响而不能工作,为了降低风险和为日后的维护、扩展做准备,我们需要对它进行重构,引入工厂方法。
2, 工厂方法模式的组成角色,比简单工厂多了一个角色:
1、抽象工厂类角色:工厂的抽象,是一般工厂的父类或实现的接口。在Java中由一个接口或抽象类来实现。例如我们程序的产品部门主管。
2、工厂类角色 :这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。例如你生产产品的部门,由他来处理你想生产的逻辑。
3、抽象产品角色 :它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。例如产品这个模型,它是所有你想生产 产品的父类或接口。
4、具体产品角色 :工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。例如具体的某产品,冰箱?空调?洗衣机?

3,工厂方法为工厂类定义了接口,用多态来削弱了工厂类的职能,以下是工厂接口的定义:

Java代码 :
    public interface Factory{  
      public Product create();  
    }  

4,我们再来定义一个产品接口

Java代码:
public interface Product{}  

5,是实现了产品接口的产品类

Java代码:
public class Washer implements Product{  
   public Washer(){  
       System.out.println("制造洗衣机");  
   }  
}  

public class Icebox implements Product{  
   public Icebox(){  
       System.out.println("制造冰箱");  
   }  
}  

public class AirCondition implements Product{  
   public Icebox(){  
       System.out.println("制造空调");  
   }  
}  

6,接下来,就是工厂方法的核心部分,也就是具体创建产品对象的具体工厂类,

Java代码:
//创建洗衣机的工厂  
public class CreateWasher implements Factory{  
    public Product create(){  
          return new Washer();  
    }  
}  

//创建冰箱的工厂  
public class CreateIcebox implements Factory{  
    public Product create(){  
          return new Icebox();  
    }  
}  
//创建空调的工厂  
public class CreateAirCondition implements Factory{  
    public Product create(){  
          return new AirCondition();  
    }  
}  

从上面创建产品对象的代码可以看出,工厂方法和简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。但工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产家电外产品,还生产手机产品,这样一来家电是手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了传说的类爆炸,对于以后的维护来说,简直就是一场灾难…..

简单来说其实工厂原本所以的冰箱,空调什么的都在一个部门生产,现在换成了不同的部门。有生产空调部门,冰箱部门==。

五,抽象工厂:意的意图在于创建一系列互相关联或互相依赖的对象。
我自己觉得抽象工厂是在工厂方法的基础上引进了分类管理的概念
工厂方法用来创建一个产品,它没有分类的概念,而抽象工厂则用于创建一系列产品,所以产品分类成了抽象工厂的重点。
2 解释:
工厂生产的所有产品都用都用大写字母来标明它们的型号,比如冰箱,就有“冰箱-A”,“冰箱-B”,同样,其他的产品也都是遵守这个编号规则,于是就有了一下产品家族树
冰箱: 冰箱-A,冰箱-B
洗衣机: 洗衣机-A,洗衣机-B

我们可以为冰箱和洗衣机分别定义两个产品接口,以对他们进行分类,

Java代码
//洗衣机接口  
public interface Washer{  
}  

//冰箱接口  
public interface Icebox{  
}  

接着,我们分别创建这两个接口的具体产品

Java代码 
//洗衣机-A  
public class WasherA implements Washer{  
   public WasherA(){  
       System.out.println("洗衣机-A被制造了");  
   }  
}  

//洗衣机-B  
public class WasherB implements Washer{  
   public WasherB(){  
       System.out.println("洗衣机-B被制造了");  
   }  
}  

//冰箱-A  
public class IceboxA implements Icebox{  
   public IceboxA(){  
       System.out.println("冰箱-A被制造了");  
   }  
}  

//冰箱-B  
public class IceboxB implements Icebox{  
   public IceboxB(){  
       System.out.println("冰箱-B被制造了");  
   }  
}  

到此,产品部分我们准备好了,接下来我们来处理工厂部分,我们先来定义工厂行为接口

Java代码
public interface Factory{  
       public Washer createWasher();  
       public Icebox createIcebox();  
}  

接下来我创造具体的工厂类,我们根据上面产品的接口,把型号A的产品分为一类,由一个工厂来管理,把型号为B的产品有另一个工厂管理,根据这个分类,我们可以实现如下的两个具体工厂类

Java代码
//创建型号为A的产品工厂  
public class FactoryA implements Factory{  
       //创建洗衣机-A  
       public Washer createWasher(){  
            return new WasherA();  
       }  

   //创建冰箱-A  
    public Icebox createIcebox(){  
         return new IceboxA();  
    }  
}  

//创建型号为B的产品工厂  
public class FactoryB implements Factory{  
       //创建洗衣机-B  
       public Washer createWasher(){  
            return new WasherB();  
       }  

   //创建冰箱-B  
   public Icebox createIcebox(){  
        return new IceboxB();  
   }  
}  

这样,我们的抽象工厂就完成了。有上面可以看出,在运用上我觉得工厂方法和抽象工厂,都有自己的应用场景,并没有什么优劣之分,但在应用抽象工厂之前,要先对创建的对象进行系统的分类,这点很重要,好的产品分类规则能为具体工厂类的选择调用和以后的扩展提供清晰的思路.

参考文章:http://chjl2020.iteye.com/blog/265283

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值