工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。
工厂模式主要用一下几种形态:
1:简单工厂(Simple Factory)
2:工厂方法(Factory Method)
3:抽象工厂(Abstract Factory)
简单工厂(Simple Factory)
又叫静态工厂,是工厂模式三中状态中结构最为简单的。主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。来看一个具体的例子:假设一家工厂,既生产衣服,又生产帽子、鞋子等等。
先为所有产品定义一个共同的产品接口
public interface Product{}
接着让这个工厂的所有产品都必须实现此接口
public class Clothes implements Product{
public Clothes(){
System.out.println("衣服被制造了");
}
}
public class Hat implements Product{
public Hat(){
System.out.println("帽子被制造了");
}
}
public class Shoe implements Product{
public Shoe(){
System.out.println("鞋子被制造了");
}
}
然后写一个工厂类,有它来负责生产以上的产品
public class SimpleFactory {
public static Product factory(String productName) throws Exception{
if(productName.equals("Clothes")){
return new Clothes();
}else if(productName.equals("Hat")){
return new Hat();
}else if(productName.equals("Shoe")){
return new Shoe();
}else{
throw new Exception("没有该产品");
}
}
}
好了,有了这个工厂类,就可以开始下定单了,SimpleFactory将根据不同的定单类决定生产什么产品。
public static void main(String[] args) {
try {
SimpleFactory.factory("Clothes");
SimpleFactory.factory("Hat");
SimpleFactory.factory("Shoe");
} catch (Exception e) {
e.printStackTrace();
}
}
由上面的代码可以看出,简单工厂的核心就是一个SimpleFactory类,它拥有必要的逻辑判断能力和所有产品的创建权利,只需要向把定单给它,就能得到想要的产品,这使用起来似乎非常方便。
但实际上,这个SimpleFactory有很多的局限。首先,每次想要增加一种新产品的时候,都必须修改SimpleFactory的原代码。其次,当拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增,这对以后的维护简直就是恐怖两个字…
还有就是,整个系统都严重依赖SimpleFactory类,只要SimpleFactory类一出问题,系统就进入不能工作的状态,这也是最为致命的一点….
以上的不足将在工厂模式的另外两种状态中得到解决。
工厂方法(Factory Method)
工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。
工厂方法为工厂类定义了接口,用多态来削弱了工厂类的职能,以下是工厂接口的定义:
public interface Factory{
public Product create();
}
再来定义一个产品接口
public interface Product{}
以下是实现了产品接口的产品类
public class Clothes implements Product{
public Clothes(){
System.out.println("衣服被制造了");
}
}
public class Hat implements Product{
public Hat(){
System.out.println("帽子被制造了");
}
}
public class Shoe implements Product{
public Shoe(){
System.out.println("鞋子被制造了");
}
}
接下来,就是工厂方法的核心部分,也就是具体创建产品对象的具体工厂类,
//创建衣服的工厂
public class ClothesFactory implements Factory{
public Product create(){
return new Clothes();
}
}
//创建帽子的工厂
public class HatFactory implements Factory{
public Product create(){
return new Hat();
}
}
//创建鞋子的工厂
public class ShoeFactory implements Factory{
public Product create(){
return new Shoe();
}
}
从上面创建产品对象的代码可以看出,工厂方法和简单工厂的主要区别是,简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。但工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产家电外产品,还生产手机产品,这样一来家电是手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了传说的类爆炸,对于以后的维护来说,简直就是一场灾难…..
抽象工厂(Factory Method)
抽象工厂:目的在于创建一系列互相关联或互相依赖的对象。
抽象工厂就是在工厂方法的基础上引进了分类管理的概念….
工厂方法用来创建一个产品,它没有分类的概念,而抽象工厂则用于创建一系列产品,所以产品分类成了抽象工厂的重点,
继续用上面的例子来说明:
工厂生产的所有产品都用都用大写字母来标明它们的型号,比如衣服,就有“衣服-A”,“衣服-B”,同样,其他的产品也都是遵守这个编号规则,于是就有了一下产品家族树
衣服:
1.衣服-A
2.衣服-B
鞋子:
1.鞋子-A
2.鞋子-B
可以为衣服和鞋子分别定义两个产品接口,以对它们进行分类
//衣服接口
public interface Clothes{
}
//鞋子接口
public interface Shoe{
}
接着分别创建这两个接口的具体产品
//衣服-A
public class ClothesA implements Clothes{
public ClothesA(){
System.out.println("衣服-A被制造了");
}
}
//衣服-B
public class ClothesB implements Clothes{
public ClothesB(){
System.out.println("衣服-B被制造了");
}
}
//鞋子-A
public class ShoeA implements Shoe{
public ShoeA(){
System.out.println("鞋子-A被制造了");
}
}
//鞋子-B
public class ShoeB implements Shoe{
public ShoeB(){
System.out.println("鞋子-B被制造了");
}
}
到此,产品的部分准备好了,接下来处理工厂部分,先来定义工厂行为接口
public interface Factory{
public Clothes createClothes();
public Shoe createShoe();
}
接下来创造具体的工厂类,根据上面产品的接口,把型号A的产品分为一类,由一个工厂来管理,把型号为B的产品有另一个工厂管理,根据这个分类,可以实现如下的两个具体工厂类
//创建型号为A的产品工厂
public class FactoryA implements Factory{
//创建衣服-A
public Clothes createClothes(){
return new ClothesA();
}
//创建鞋子-A
public Shoe createShoe(){
return new ShoeA();
}
}
//创建型号为B的产品工厂
public class FactoryB implements Factory{
//创建衣服-B
public Clothes createClothes(){
return new ClothesB();
}
//创建鞋子-B
public Shoe createShoe(){
return new ShoeB();
}
}
这样,抽象工厂就完成了。由上面可以看出,在应用抽象工厂之前,要先对创建的对象进行系统的分类,这点很重要,好的产品分类规则能为具体工厂类的选择调用和以后的扩展提供清晰的思路.
总结
1、简单工厂模式是由一个具体的类去创建其他类的实例,父类是相同的,父类是具体的。
2、工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成。
3、抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。