原创文章,如有转载,请注明出处:http://blog.csdn.net/myth13141314/article/details/78351034
在日常开发过程中时常需要用到设计模式,但是设计模式有23种,如何将这些设计模式了然于胸并且能在实际开发过程中应用得得心应手呢?和我一起跟着《Android源码设计模式解析与实战》一书边学边应用吧!
设计模式系列文章
- Android 设计模式之面向对象的六大原则
- Android 设计模式之Builder模式
- Android 设计模式之观察者模式
- Android 设计模式之单例模式
- Android 设计模式之代理模式
- Android设计模式之装饰模式
- Android 设计模式之外观模式
- Android 设计模式之原型模式
- Android 设计模式之策略模式
- Android 设计模式之适配器模式
- Android 设计模式之桥接模式
- Android 设计模式之状态模式
今天我们要讲的是工厂方法模式
定义
定义一个用于创建对象的接口,让子类决定实例化哪个类
使用场景
- 在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式
使用例子
- Activity中的各个生命周期方法就可以看作是工厂方法
实现
一般分4大模块
- 抽象产品
- 具体产品
- 抽象工厂
- 具体的工厂
实现的要点
- 工厂方法模式实现比较简单,方式也比较灵活,并不一定局限于上述的四个模块,可以根据需要来修改。比如只有一个工厂时可以省略抽象工厂
实现方式
工厂方法模式的实现主要是根据具体的实际情况来将多个产品的共性抽象出来,并定制具体的产品类,然后用工厂类来根据需要生产具体的产品类。下面通过一个简单的例子来看看工厂方法的实现
- 抽象产品类
public abstract class Product {
/**
* 产品类的抽象方法,由具体的产品类去实现
*/
public abstract void method();
}
- 具体产品类
//产品A
public class ProductA extends Product {
@Override
public void method() {
System.out.println("产品A");
}
}
//产品B
public class ProductB extends Product {
@Override
public void method() {
System.out.println("产品B");
}
}
- 抽象工厂
public abstract class Factory {
/**
* @param clz 产品对象类型
* @return 具体的产品类型
*/
public abstract <T extends Product> T createProduct(Class<T> clz);
}
- 具体工厂
public class ConcreteFactory extends Factory {
@Override
public <T extends Product> T createProduct(Class<T> clz) {
Product p = null;
try {
p = (Product) Class.forName(clz.getName()).newInstance();
}catch (Exception e) {
e.printStackTrace();
}
return (T) p;
}
}
- 调用
Factory factory = new ConcreteFactory();
Product productA = factory.createProduct(ProductA.class);
Product productB = factory.createProduct(ProductB.class);
productA.method();
productB.method();
- 上面的例子中,我们的工厂方法采用了反射的方式来实现生产具体的产品对象,这样更加简洁,不用为每一个产品都创建一个具体的工厂。
上面的例子比较简单,下面我们看看书中作者的举例,利用工厂方法模式封装数据持久化过程
- Android 中数据持久化为我们提供了SharePreference和SQLite,还有普通的文件存储等方式。但是对数据的操作都是增删改查,可以把这些共同的操作抽象出来作为抽象产品类,然后每一种持久化方法作为具体产品。
- 抽象产品中定义操作的方法,即增删改查
public abstract class AbstractIoHandler {
/**
* 添加个人信息
*
* @param id 身份证号码
* @param name 姓名
*/
public abstract void add(String id, String name);
/**
* 根据ID删除一条信息
*
* @param id 身份证
*/
public abstract void remove(String id);
/**
* 更新个人信息
*
* @param id 身份证
* @param name 姓名
*/
public abstract void update(String id, String name);
/**
* 查询ID对应的信息
*
* @param id 身份证
* @return 人名
*/
public abstract String query(String id);
}
- 具体的产品,持久化的类型,比如利用文件来持久化
public class FileHandler extends AbstractIoHandler {
@Override
public void add(String id, String name){
//业务处理
}
@Override
public void remove(String id) {
//业务处理
}
@Override
public void update(String id, String name) {
//业务处理
}
@Override
public String query(String id) {
return "";
}
}
- 然后是我们的工厂方法,这里仍然采用反射的方式
public class IoFactory {
/**
* 获取IoHandler
*
* @param clz AbstractIoHandler类型的类
* @return AbstractIoHandler对象
*/
public static <T extends AbstractIoHandler> T getIoHandler(Class<T> clz) {
AbstractIoHandler handler = null;
try {
handler = (AbstractIoHandler) Class.forName(clz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) handler;
}
}
- 在需要进行数据持久化的地方调用工厂方法
AbstractIoHandler ioHandler = IoFactory.getIoHandler(FileHandler.class);
System.out.println(ioHandler.query("123456"));
- 这里的例子简化了很多,还有数据库SQLite以及SharePreference的持久化的类就没有写了。
总结
- 工厂方法模式通过依赖抽象来达到解耦的效果,并且将实例化的任务交给子类去完成,有非常好的扩展性
- 工厂方法模式用于生成比较复杂的对象。像我们上面的例子中一样,当我们有多个产品需要,我们可以把产品共性的地方抽象出来,然后利用工厂方法生产具体需要的产品
- 工厂方法模式的应用非常广泛,然而缺点也很明显,就是每次我们为工厂方法添加新的产品时,都需要编写一个新的产品类,所以要根据实际情况来权衡是否要用工厂方法模式
欢迎关注我的公众号,和我一起每天进步一点点!