一、简单工厂
1、概念
将具体创建对象的细节封装到工厂方法中。需要对象时,只需要提供对象的描述信息即可,而具体怎么创建的我们不需要关心。
简单工厂的缺点:
当需要其他Pet时,就要修改PetFactory这个类,违背了OCP原则(对扩展开放,对修改关闭)。
2、示例
假设现在我们需要宠物Pet,有dog,cat还有其他的。传统实现是写一个父类Pet,让dog和cat继承Pet,然后直接new。
如何通过简单工厂模式来实现?
1)Pet
抽象类Pet,封装通用的方法
package factory.simple;
public abstract class Pet {
//该方法用于获取创建的具体对象的类型,比如dog,cat
public abstract String getType();
}
2)Dog,Cat
Dog和Cat继承Pet
package factory.simple;
public class Dog extends Pet{
@Override
public String getType() {
return "dog";
}
}
3)PetFactory
根据提供的描述创建具体的宠物
package factory.simple;
public class PetFactory {
public static Pet createPet(String type) {
Pet pet = null;
if("dog".equals(type)) {
pet = new Dog();
}else if("cat".equals(type)) {
pet = new Cat();
}
return pet;
}
}
4)测试类
package factory.simple;
public class Test {
public static void main(String[] args) {
Pet pet1 = PetFactory.createPet("dog");
System.out.println(pet1.getType());
Pet pet2 = PetFactory.createPet("cat");
System.out.println(pet2.getType());
}
}
二、工厂方法
1、概念
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
工厂方法将简单工厂进行抽象化,在不修改原有代码的基础上可以扩展新的类。
优点:
1)我们只需要知道创建类的具体工厂名称即可,不需要知道具体的创建过程。
2)扩展新的类只需要添加新的类和具体工厂类,不需要修改原有代码。
缺点
没扩展一个类,就需要添加新的类和具体工厂类,系统过于复杂。
工厂方法模式的主要角色
**抽象工厂(Abstract Factory):**提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
**具体工厂(ConcreteFactory):**主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
**抽象产品(Product):**定义了产品的规范,描述了产品的主要特性和功能。
**具体产品(ConcreteProduct):**实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
2、示例
1)修改PetFactory
将创建宠物的方法写成抽象方法,具体的实现下沉到子类。
package factory.factorymethod;
public abstract class PetFactory {
public abstract Pet createPet();
}
2)具体工厂类DogFactory,CatFactory
这两个类继承PetFactory,实现父类的抽象方法
package factory.factorymethod;
public class DogFactory extends PetFactory {
@Override
public Pet createPet() {
return new Dog();
}
}
package factory.factorymethod;
public class CatFactory extends PetFactory {
@Override
public Pet createPet() {
return new Cat();
}
}
3)扩展新的类Fish
只需要添加Fish类和FishFactory类
package factory.factorymethod;
public class Fish extends Pet {
@Override
public String getType() {
return "fish";
}
}
package factory.factorymethod;
public class FishFactory extends PetFactory {
@Override
public Pet createPet() {
return new Fish();
}
}
4)测试类
package factory.factorymethod;
public class Test {
public static void main(String[] args) {
//dog
PetFactory pf1 = new DogFactory();
Pet pet1 = pf1.createPet();
System.out.println(pet1.getType());
//cat
PetFactory pf2 = new CatFactory();
Pet pet2 = pf2.createPet();
System.out.println(pet2.getType());
//fish
PetFactory pf3 = new FishFactory();
Pet pet3 = pf3.createPet();
System.out.println(pet3.getType());
}
}
三、抽象工厂
1、概念
是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
使用抽象工厂模式一般要满足以下条件
1)系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
2)系统一次只可能消费其中某一族产品,即同族的产品一起使用。
抽象工厂模式的主要角色如下
**抽象工厂(Abstract Factory):**提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
**具体工厂(Concrete Factory):**主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
**抽象产品(Product):**定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
**具体产品(ConcreteProduct):**实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。
产品族的概念
所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。
举例
dog和cat属于同一等级,rose(玫瑰花)和lily(百合花)属于同一等级。
现在将dog和rose组合,那么称之为一个产品族,同样将cat和lily组合,也称之为一个产品组。
工厂方法模式和抽象工厂模式的区别
如果工厂的产品全部属于同一个等级结构(dog和cat),则属于工厂方法模式;
如果工厂的产品来自多个等级结构(dog和rose),则属于抽象工厂模式。
如果一个工厂提供全部四种类型的产品,因为产品分属两个等级结构,他当然也属于抽象工厂模式了。
2、示例
现在有宠物(Pet)和植物(Plant)抽象类,他们分别有子类dog和cat,rose和lily。
抽象工厂(AbsFactory),提供了createPet()和createPlant()两个抽象方法,他有两个子类FactoryA和FactoryB。FactoryA用于创建dog和rose,FactoryB用于创建cat和lily。
1)Pet,Dog,Cat
package factory.abstractfactory;
public abstract class Pet {
//该方法用于获取创建的具体对象的类型,比如dog,cat
public abstract String getType();
}
package factory.abstractfactory;
public class Dog extends Pet{
@Override
public String getType() {
return "dog";
}
}
package factory.abstractfactory;
public class Cat extends Pet {
@Override
public String getType() {
return "cat";
}
}
2)Plant,Rose,Lily
package factory.abstractfactory;
public abstract class Plant {
public abstract String getType();
}
package factory.abstractfactory;
public class Rose extends Plant{
@Override
public String getType() {
return "rose";
}
}
package factory.abstractfactory;
public class Lily extends Plant{
@Override
public String getType() {
return "lily";
}
}
3)AbsFactory,FactoryA,FactoryB
package factory.abstractfactory;
//抽象工厂类
public abstract class AbsFactory {
//创建动物
public abstract Pet createPet();
//创建植物
public abstract Plant createPlant();
}
package factory.abstractfactory;
public class FactoryA extends AbsFactory {
@Override
public Pet createPet() {
return new Cat();
}
@Override
public Plant createPlant() {
return new Lily();
}
}
package factory.abstractfactory;
public class FactoryB extends AbsFactory {
@Override
public Pet createPet() {
return new Dog();
}
@Override
public Plant createPlant() {
return new Rose();
}
}
4)测试类
package factory.abstractfactory;
public class Test {
public static void main(String[] args) {
AbsFactory af = new FactoryA();
Pet pet = af.createPet();
Plant plant = af.createPlant();
System.out.println(pet.getType() + " " + plant.getType());
AbsFactory af2 = new FactoryB();
Pet pet2 = af2.createPet();
Plant plant2 = af2.createPlant();
System.out.println(pet2.getType() + " " + plant2.getType());
}
}