Java 是一门面向对象的语言,一般情况下,我们要获取一个对象的实例,需要用 new 关键字来创建,而在多数情况下,创建一个实例还需要一些初始设置等其他操作,就是一个过程而不是一个简单的操作。比如有一个客户想要一个小动物,传统的做法就是:
1 | Animal cat = new Cat(); |
简单工厂主要包含3个角色:
- 抽象动物(Animal),一般为具体产品继承的父类或者实现的接口
- 具体动物(CatDog),工厂类所创造的对象
- 工厂类(AnimalFactory),模式的核心,负责创建具体产品的实例,有一定的处理逻辑
这种模式虽然解决了客户和动物的耦合问题,但是每增加一个动物,我们不得不在工厂类中新增一个 case ,需要修改以前的代码,这显然不能达到我们的要求,于是我们对这种模式进行扩展,有了工厂方法模式。
2 工厂方法
这种模式为每个动物创建一个工厂,当有新动物增加时,我们只需要为新动物增加一个工厂类即可,不需要修改以前代码,主要包含 4 个角色:
- 抽象动物(Animal),一般为具体产品继承的父类或者实现的接口
- 具体动物(CatDog),工厂类所创造的对象
- 抽象工厂(AnimalFactory),一般为具体工厂的父类或者接口
- 具体工厂(CatFactory和DogFactory),具体的工厂,负责具体动物的创建
public interface AnimalFactory {
Animal createAnimal();
}
public class CatFactory implements AnimalFactory {
@Override
public Animal createAnimal() {
return new Cat();
}
}
public class DogFactory implements AnimalFactory {
@Override
public Animal createAnimal() {
return new Dog();
}
}
AnimalFactory cf = new CatFactory();
Animal cat = cf.createAnimal();
AnimalFactory df = new DogFactory();
Animal dog = df.createAnimal();
3 抽象工厂
抽象工厂是将一组具有相同主题的封装起来,使用的时候,客户端程序需要创建抽象工厂的具体实现,然后使用抽象工厂作为接口来创建这一主题的具体对象。客户端程序不需要知道(或关心)它从这些内部的工厂方法中获得对象的具体类型,因为客户端程序仅使用这些对象的通用接口。抽象工厂模式将一组对象的实现细节与他们的一般使用分离开来。
如图所示,我们假定猫和狗都有男女之分,(CatFactory可以创建男猫和女猫,DogFactory可以创建男狗和女狗,客户端通过具体工厂实现来创建相应实例。
public class CatFactory implements AnimalFactory {
@Override
public Animal createMale() {
return new Cat("male");
}
@Override
public Animal createFemale() {
return new Cat("female");
}
}
public class DogFactory implements AnimalFactory {
@Override
public Animal createMale() {
return new Dog("male");
}
@Override
public Animal createFemale() {
return new Dog("female");
}
}
AnimalFactory cf = new CatFactory();
Animal maleCat = cf.createMale();
Animal femaleCat = cf.createFemale();
AnimalFactory df = new DogFactory();
Animal maleDog = df.createMale();
Animal femaleDog = df.createFemale();