第五章 应用最广泛的模式——工厂模式
工厂方法模式是创建型设计模式之一,是一种结构简单的模式,在平时开发中应用很广泛。
1.定义
定义一个用于创建对象的接口,让子类决定实例化哪个类。
2.使用场景
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。
3.简单实现
工厂模式主要有四大角色,一是抽象工厂,它是工厂方法模式的核心;二是具体工厂,它实现了具体的业务逻辑;三是抽象产品,它是工厂方法模式所创建的产品的父类;四是具体产品,它是实现抽象产品的某个具体产品的对象。
/**
* Description:抽象工厂类
* Created by 禽兽先生
* Created on 2017/5/8
*/
public abstract class Factory {
public abstract Product crecteProduct();
}
/**
* Description:具体工厂类,多工厂方法模式
* Created by 禽兽先生
* Created on 2017/5/8
*/
public class ConcreteFactoryA extends Factory {
@Override
public Product crecteProduct() {
return new ConcreteProductA();
}
}
/**
* Description:工厂设计模式产品抽象类
* Created by 禽兽先生
* Created on 2017/5/8
*/
public abstract class Product {
public abstract void design();
public abstract void assemble();
public abstract void produce();
}
/**
* Description:工厂设计模式产品具体类A
* Created by 禽兽先生
* Created on 2017/5/8
*/
public class ConcreteProductA extends Product {
@Override
public void design() {
System.out.println("design ConcreteProductA");
}
@Override
public void assemble() {
System.out.println("assemble ConcreteProductA");
}
@Override
public void produce() {
System.out.println("produce ConcreteProductA");
}
}
/**
* Description:工厂设计模式产品具体类A
* Created by 禽兽先生
* Created on 2017/5/8
*/
public class ConcreteProductB extends Product {
@Override
public void design() {
System.out.println("design ConcreteProductB");
}
@Override
public void assemble() {
System.out.println("assemble ConcreteProductB");
}
@Override
public void produce() {
System.out.println("produce ConcreteProductB");
}
}
如何使用:
在客户端构造一个工厂对象,并通过其工厂方法生产具体的产品对象://多工厂方法模式,根据不同工厂类创建不同产品对象
ConcreteFactoryA concreteFactoryA = new ConcreteFactoryA();
Product concreteProductA = concreteFactoryA.crecteProduct();
concreteProductA.design();
concreteProductA.assemble();
concreteProductA.produce();
如果想生成别的产品对象,则需要修改工厂方法:
@Override
public Product crecteProduct() {
// return new ConcreteProductA();
return new ConcreteProductB();
}
这种方式比较常见,需要某个产品对象就生产哪一个。
有时候可以利用反射来简化生产,而不用去修改代码,这时就需要在工厂方法中传入一个参数Class类来决定具体生产哪一个产品类。
抽象工厂改为:
public abstract class Factory {
public abstract <T extends Product> T crecteProduct(Class<T> tClass);
}
具体工厂类改为:
/**
* Description:具体工厂类,动态传入需要生产的产品类
* Created by 禽兽先生
* Created on 2017/5/8
*/
public class ConcreteFactory extends Factory {
@Override
public <T extends Product> T crecteProduct(Class<T> tClass) {
Product product = null;
try {
product = (Product) Class.forName(tClass.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) product;
}
}
//动态传入需要生产的产品类的类别方式
ConcreteFactory concreteFactory = new ConcreteFactory();
Product concreteProduct = concreteFactory.crecteProduct(ConcreteProductA.class);
concreteProduct.design();
concreteProduct.assemble();
concreteProduct.produce();
需要哪一个类的对象就传入哪一个类的类型,这样的方式比较动态,如果不喜欢这种方式,也可以构建多个工厂,各司其职:
public class ConcreteFactoryA extends Factory {
@Override
public Product crecteProduct() {
return new ConcreteProductA();
// return new ConcreteProductB();
}
}
public class ConcreteFactoryB extends Factory {
@Override
public Product crecteProduct() {
return new ConcreteProductB();
}
}
拥有多个工厂的方式称为多工厂方法模式。当工厂只有一个的时候,我们可以简化掉工厂的抽象类,并将工厂方法改为静态方法,这样的方式称为简单工厂模式或静态工厂模式,它是工厂方法模式的一个弱化版本。
4.总结
工厂方法模式是一个很好的设计模式,优点不必多说,它完全符合设计原则,既降低了对象之间的耦合,又将实例化的任务交给子类去做,有很好的扩展性。缺点也在所难免,每次添加新产品时就需要写一个新产品类,还需要引入抽象层,必然会导致类结构的复杂化,所以,在某些情况比较简单时是否需要使用工厂方法模式,就需要设计者自己权衡。Demo下载