工厂方法模式
Posted gxl1995
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工厂方法模式相关的知识,希望对你有一定的参考价值。
定义
定义一个用于创建对象的接口,让子类决定实例化哪个类。
使用场景
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。
uml图
角色介绍:
- 抽象工厂:其为工厂方法模式的核心,它定义了一个工厂类所具备的基本行为;
- 具体工厂:其实现了具体的业务逻辑;
- 抽象产品:它定义了所有产品的公共行为;
- 具体产品:实现抽象产品的某个具体产品的对象。
通用代码
产品
抽象产品
/**
* 抽象产品类
*/
public abstract class Product {
/**
* 产品类的抽象方法,
* 由具体的产品类去实现
*/
public abstract void method();
}
具体产品A
/**
* 具体的产品类A
*/
public class ConcreteProductA extends Product {
@Override
public void method() {
System.out.println("我是具体的产品 A");
}
}
具体产品B
/**
* 具体的产品类B
*/
public class ConcreteProductB extends Product {
@Override
public void method() {
System.out.println("我是具体的产品 B");
}
}
工厂
关于工厂有多种写法,下面就说一下常用的四种写法,用哪一种都行。
第一种
抽象工厂类
public abstract class Factory {
/**
* 抽象工厂方法,
* 又具体的抽象工厂类实现
*/
public abstract Product createFactory();
}
具体工厂类
public class ConcreteFactory extends Factory {
@Override
public Product createFactory() {
// return new ConcreteProductB();
return new ConcreteProductA();
}
}
这种方式比较常见,需要哪个产品,就生产哪个。
第二种
抽象工厂
public abstract class Factory {
/**
* 创建产品
* 具体生产什么由子类去实现
*/
public abstract <T extends Product> T createProduct(Class<T> clazz);
}
具体工厂
public class ConcreteFactory extends Factory {
@Override
public <T extends Product> T createProduct(Class<T> clazz) {
Product product = null;
try {
product = (Product) Class.forName(clazz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) product;
}
}
这种方式时通过反射,需要哪个产品直接传入相应的class就行,非常方便。
第三种
抽象工厂
public abstract class Factory {
/**
* 抽象工厂方法,
* 又具体的抽象工厂类实现
*/
public abstract Product createFactory();
}
具体工厂A
public class ConcreteFactoryA extends Factory {
@Override
public Product createFactory() {
return new ConcreteProductA();
}
}
具体工厂B
public class ConcreteFactoryB extends Factory {
@Override
public Product createFactory() {
return new ConcreteProductB();
}
}
这种创建工厂方式和uml比较契合,每有一个产品创建对应的工厂来生产产品,像这样拥有多个工厂的方法我们称之为多工厂方法模式。
第四种
没有抽象工厂,直接创建工厂如下:
public class Factory {
public static Product createProduct() {
// return new ConcreteProductB();
return new ConcreteProductA();
}
}
这种方式简化掉了抽象类,将对应的方法改成了静态方法,这种方式称为简单工厂模式或者静态工模式。
实践
我们在项目中经常有保存数据的操作,但是保存的方式有很多种,如Preference,File,数据库等,这些保存方式各有各的优点和缺点,在实际运用中,可能在不同的地方要用不同的方式来存储,但是这些存储都有一个共同的特点就是增,删,改,查。有这四个特性,我们可以考虑运用工厂方法模式来处理这个问题。
先做出对应的uml图来理清结构
下面就根据这个原理来写代码
IOHandler
public interface IOHandler {
/**
* 存储String类型的值
*/
void putString(String key, String value);
/**
* 获取String类型值
*/
String getString(String key);
}
PreferencesHandler
public class PreferencesHandler implements IOHandler {
private static volatile PreferencesHandler mInstance;
private SharedPreferences mSP;
private PreferencesHandler(Context context) {
mSP = context.getApplicationContext().getSharedPreferences("cache", Context.MODE_PRIVATE);
}
public static PreferencesHandler getInstance(Context context) {
if (mInstance == null) {
synchronized (PreferencesHandler.class) {
if (mInstance == null) {
mInstance = new PreferencesHandler(context);
}
}
}
return mInstance;
}
@Override
public void putString(String key, String value) {
mSP.edit().putString(key, value).commit();
}
@Override
public String getString(String key) {
String string = mSP.getString(key, null);
return string;
}
}
MemoryHandler
public class MemoryHandler implements IOHandler {
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
int cacheSize = maxMemory / 8;
private static volatile MemoryHandler mInstance;
private LruCache<String, Object> mLruCache;
private MemoryHandler() {
mLruCache = new LruCache<>(cacheSize);
}
public static MemoryHandler getInstance() {
if (mInstance == null) {
synchronized (MemoryHandler.class) {
if (mInstance == null) {
mInstance = new MemoryHandler();
}
}
}
return mInstance;
}
@Override
public void putString(String key, String value) {
mLruCache.put(key, value);
}
@Override
public String getString(String key) {
return (String) mLruCache.get(key);
}
}
IOFactory
public class IOFactory {
/**
* 获取相应的存储方法
* @param clazz 具体的IOHandler子类
*/
public static <T extends IOHandler> T getIOHandler(Class<T> clazz) {
IOHandler handler = null;
try {
handler = (IOHandler) Class.forName(clazz.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return (T) handler;
}
}
上面就是大致的思路,可更加这个思路扩展。
以上是关于工厂方法模式的主要内容,如果未能解决你的问题,请参考以下文章