[设计模式]工厂模式(Java实现)

Jan 10, 2015


工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。工厂模式分为以下三种:

1.简单工厂模式

2.工厂方法模式

3.抽象工厂模式

下面进行分条说明:

①简单工厂模式

定义:简单工厂模式特别简单,简单工厂模式用于:定义一个用于创建对象的接口。

简单工厂模式中包含的角色及其相应的职责如下:

1.工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。

2.抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。

3.具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。

简单工厂模式举例: 1.新建立一个食物的接口:


/** 
 * 产品的抽象接口 
 **/  
public interface Food {  
    /** 
     * 获得相应的食物 
     **/  
    public void getFood();  
}  

2.建立具体的产品:


public class apple implements Food{  
    public void getFood(){  
        System.out.println("苹果");  
    }  
}  
  
public class orange implements Food{  
    public void getFood(){  
        System.out.println("橘子");  
    }  
}  

3.建立食物工厂:


public class FoodFactory{  
    public static Fruit factory(String which)throws Exception{  
        if(which.equalsIgnoreCase("apple")){  
            return new apple();  
        }else if(which.equalsIgnoreCase("orange")){  
            return new orange();  
        }else{  
            throw new Exception("找不到相应的实例化类!");  
        }  
    }  
}  

4.简单测试:


public class SimpleFactoryTest {  
    public static void main(String[] args) throws Exception{  
        Food apple = FoodFactory.getFood("apple");  
        Food orange = FoodFactory.getFood("orange");  
        Food eggs = FoodFactory.getFood("eggs");  
        if(apple!=null){  
            apple.get();  
        }  
        if(orange!=null){  
            orange.get();  
        }  
        if(eggs!=null){  
            eggs.get();  
        }  
    }  
}  

5.简单工厂模式的优缺点分析:

优点:工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。

缺点:由于工厂类集中了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会受到牵连;而且由于简单工厂模式的产品室基于一个共同的抽象类或者接口,这样一来,但产品的种类增加的时候,即有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建何种种类的产品,这就和创建何种种类产品的产品相互混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。而且更重要的是,简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,因为当我新增加一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。

总结一下:简单工厂模式分离产品的创建者和消费者,有利于软件系统结构的优化;但是由于一切逻辑都集中在一个工厂类中,导致了没有很高的内聚性,同时也违背了“开放封闭原则”。另外,简单工厂模式的方法一般都是静态的,而静态工厂方法是无法让子类继承的,因此,简单工厂模式无法形成基于基类的继承树结构。

②工厂方法模式

工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。

1.抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

2.具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。

3.抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

4.具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

适用性:

1.当一个类不知道它所必须创建的对象的类的时候。

2.当一个类希望由它的子类来指定它所创建的对象的时候。

3.当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。


/** 
 *定义工作接口 
 **/  
public interface Work {  
    void doWork();  
}  
/** 
 *定义学生的工作 
 **/  
public class StudentWork implements Work {  
    public void doWork() {  
        System.out.println("学生做作业!");  
    }  
}  
/** 
 *定义老师的工作 
 **/  
public class TeacherWork implements Work {  
    public void doWork() {  
        System.out.println("老师审批作业!");  
    }  
}  
/** 
 *定义工厂接口 
 **/  
public interface IWorkFactory {  
    Work getWork();  
}  
/** 
 *定义学生工作类 
 **/  
public class StudentWorkFactory implements IWorkFactory {  
    public Work getWork() {  
        return new StudentWork();  
    }  
}  
/** 
 *定义学生工作类 
 **/  
public class TeacherWorkFactory implements IWorkFactory {  
    public Work getWork() {  
        return new TeacherWork();  
    }  
}  
/** 
 *测试类 
 **/  
public class Test {  
    public static void main(String[] args) {  
        IWorkFactory studentWorkFactory = new StudentWorkFactory();  
        studentWorkFactory.getWork().doWork();  
        IWorkFactory teacherWorkFactory = new TeacherWorkFactory();  
        teacherWorkFactory.getWork().doWork();  
    }  
}  

可以看出工厂方法的加入,使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。因为如果不能避免这种情 况,可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。

③抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

适用性:

1.一个系统要独立于它的产品的创建、组合和表示时。

2.一个系统要由多个产品系列中的一个来配置时。

3.当你要强调一系列相关的产品对象的设计以便进行联合使用时。

4.当你提供一个产品类库,而只想显示它们的接口而不是实现时。

实例:

1.AbstractFactory 声明一个创建抽象产品对象的操作接口。

2.ConcreteFactory 实现创建具体产品对象的操作。

3.AbstractProduct 为一类产品对象声明一个接口。

4.ConcreteProduct 定义一个将被相应的具体工厂创建的产品对象。 实现AbstractProduct接口。

5.Client 仅使用由AbstractFactory和AbstractProduct类声明的接口


public interface IAnimalFactory {  
    ICat createCat();     
    IDog createDog();  
}  
  
public class BlackAnimalFactory implements IAnimalFactory {  
    public ICat createCat() {  
        return new BlackCat();  
    }  
    public IDog createDog() {  
        return new BlackDog();  
    }  
}  
  
public class WhiteAnimalFactory implements IAnimalFactory {  
    public ICat createCat() {  
        return new WhiteCat();  
    }  
    public IDog createDog() {  
        return new WhiteDog();  
    }  
}  
  
public interface ICat {  
    void eat();  
}  
public interface IDog {  
    void eat();  
}  
  
public class BlackCat implements ICat {  
    public void eat() {  
        System.out.println("The black cat is eating!");  
    }  
}  
public class WhiteCat implements ICat {  
    public void eat() {  
        System.out.println("The white cat is eating!");  
    }  
}  
public class BlackDog implements IDog {  
    public void eat() {  
        System.out.println("The black dog is eating");  
    }  
}  
public class WhiteDog implements IDog {  
    public void eat() {  
        System.out.println("The white dog is eating!");  
    }  
}  
  
public static void main(String[] args) {  
    IAnimalFactory blackAnimalFactory = new BlackAnimalFactory();  
    ICat blackCat = blackAnimalFactory.createCat();  
    blackCat.eat();  
    IDog blackDog = blackAnimalFactory.createDog();  
    blackDog.eat();  
      
    IAnimalFactory whiteAnimalFactory = new WhiteAnimalFactory();  
    ICat whiteCat = whiteAnimalFactory.createCat();  
    whiteCat.eat();  
    IDog whiteDog = whiteAnimalFactory.createDog();  
    whiteDog.eat();  
}  

总结

简单工厂模式是由一个具体的类去创建其他类的实例,父类是相同的,父类是具体的。工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成。抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。