1.前言
简单工厂模式、工厂模式、抽象工厂模式......这三个模式有没有把你搞晕?我反正是晕了。不过,再晕也要弄清楚啊!
话不多说回到正题,学习工厂方法模式。
工厂方法模式,是创建型设计模式之一。是一种结构简单的模式,实际开发中我们其实经常使用该模式,比如Android中的Activity里的生命周期方法。
2.定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
3.UML类图
Product:抽象产品类
Factory:抽象工厂类
ConcreteProduct:具体产品类
ConcreteFactory:具体工厂类
4.简单实现
下面是一个工厂方法模式的通用模式代码
//抽象产品类
public abstract class Product {
/**
* 产品类的抽象方法
* 由具体的产品类去实现
*
*/
public abstract void method();
}
/**
* Created by zsf.
* 具体产品类A
*/
public class ConcreteProductA extends Product {
@Override
public void method() {
Log.d("zsf","我是具体的产品A");
}
}
/**
* Created by zsf .
* 具体产品类B
*/
public class ConcreteProductB extends Product {
@Override
public void method() {
Log.d("zsf","我是具体的产品B");
}
}
/**
* Created by zsf.
* 抽象工厂类
*/
public abstract class Factory {
/**
* 抽象工厂方法
* 具体生产什么由子类去实现
*
* @return 具体的产品对象
*/
public abstract Product createProduct();
}
/**
* Created by zsf.
* 具体工厂类
*/
public class ConcreteFactory extends Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
//客户端类
public class FactoryPatternTestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Factory factory = new ConcreteFactory();
Product p = factory.createProduct();
p.method();
}
}
打印出Log
03-31 22:08:04.694 6187-6187/? D/zsf: 我是具体的产品A
以上就是一个通用模式的组成。
- 抽象工厂,工厂方法模式的核心
- 具体工厂,实现具体业务逻辑
- 抽象产品,工厂方法模式所创建的产品的父类
- 具体产品,实现抽象产品的某个具体产品的对象
上面的代码还可以优化,我们在客户端想要得到具体产品B的实例,就需要在具体工厂类中修改返回的return,将其改为
return new ConcreteProductB();
这里就像我是一个机械厂的老板,我手下机械厂只有一条生产线,往常都是在生产A类产品,突然我接了个B类的大订单。我就通知下去,这条线改为生产B类产品。总结起来就是:我需要哪种产品就生产哪种产品。
代码修改的地方虽然不多,但是作为追求高水准的工程师,我们还可以试用更好的方式来决定生产哪种产品——反射。
我们在抽象工厂类中,修改工厂方法createProduct()
public abstract class Factory {
/**
* 抽象工厂方法
* 具体生产什么由子类去实现
*
* @return 具体的产品对象
*/
public abstract<T extends Product> T createProduct(Class<T> tClass);
}
修改具体的工厂类,通过反射获取类的实例:
/**
* Created by zsf.
* 具体工厂类
*/
public class ConcreteFactory extends Factory {
@Override
public <T extends Product> T createProduct(Class<T> tClass) {
Product p = null;
try {
p = (Product) Class.forName(tClass.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) p;
}
}
最后,客户端代码:
public class FactoryPatternTestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Factory factory = new ConcreteFactory();
Product p = factory.createProduct(ConcreteProductB.class);
p.method();
}
}
这样的话,直接在客户端修改就好了。
也有直接为每一个产品去定义一个具体的工厂类的,ConcreteProductA、ConcteteProductB,然后分别在客户端是实现。这样的方法称为多工厂方法模式。当你确定你的工厂只会有一个的时候就可以继续简化你的代码,不再使用抽象工厂,而是将对应的工厂方法改为静态即可。
public class Factory {
public static Product createProduct(){
return new ConcreteProductA();
}
}
上面的这种工厂模式其实就是简单工厂模式。
完整简单例子代码如下,生产三种材质齿轮的工厂方法模式实现。
/**
* Created by zsf.
* 抽象机械工厂类
*/
public abstract class MechanicalFactory {
//某齿轮的工厂方法
public abstract <T extends Gear> T createGear(Class<T> tClass);
}
/**
* Created by zsf.
* 生产三种不同材质的齿轮,大小相同,(假设)直接使用一条生产线
*/
public class GearFactory extends MechanicalFactory {
@Override
public <T extends Gear> T createGear(Class<T> tClass) {
Gear gear = null;
try {
gear = (Gear) Class.forName(tClass.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) gear;
}
}
/**
* Created by zsf
* 抽象产品类——齿轮
*/
public abstract class Gear {
//不同材质的齿轮
public abstract void material();
//齿数
public abstract void numberOfTeeth();
}
/**
* Created by zsf.
* 铸钢齿轮
*/
public class CastSteelGear extends Gear {
@Override
public void material() {
Log.d("zsf","我是铸钢材质齿轮");
}
@Override
public void numberOfTeeth() {
Log.d("zsf","我的齿数为20");
}
}
/**
* Created by zsf.
* 铸铁材质齿轮
*/
public class CastIronGear extends Gear {
@Override
public void material() {
Log.d("zsf","我是铸铁材质齿轮");
}
@Override
public void numberOfTeeth() {
Log.d("zsf","我的齿数为22");
}
}
/**
* Created by zsf.
*/
public class ForgedSteelGear extends Gear {
@Override
public void material() {
Log.d("zsf","我是锻钢材质齿轮");
}
@Override
public void numberOfTeeth() {
Log.d("zsf","我的齿数为25");
}
}
客户端代码:
/**
* Created by zsf
*/
public class ProductGearTestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//1.构造一个生产齿轮的工厂对象
MechanicalFactory factory = new GearFactory();
//2.1生产锻钢齿轮
ForgedSteelGear forgedSteelGear = factory.createGear(ForgedSteelGear.class);
forgedSteelGear.material();
forgedSteelGear.numberOfTeeth();
//2.2生产铸钢齿轮
CastSteelGear castSteelGear = factory.createGear(CastSteelGear.class);
castSteelGear.material();
castSteelGear.numberOfTeeth();
//2.3生产铸铁齿轮
CastIronGear castIronGear = factory.createGear(CastIronGear.class);
castIronGear.material();
castIronGear.numberOfTeeth();
}
}
打印Log
03-31 23:29:55.212 18942-18942/? D/zsf: 我是锻钢材质齿轮
03-31 23:29:55.212 18942-18942/? D/zsf: 我的齿数为25
03-31 23:29:55.212 18942-18942/? D/zsf: 我是铸钢材质齿轮
03-31 23:29:55.212 18942-18942/? D/zsf: 我的齿数为20
03-31 23:29:55.212 18942-18942/? D/zsf: 我是铸铁材质齿轮
03-31 23:29:55.212 18942-18942/? D/zsf: 我的齿数为22