0. 序言
工厂方法模式的定义:定义一个用于创建对象的接口,让子类决定实例化哪个类。
1. 场景
任何需要生成复杂对象或多个对象的地方,都可以使用工厂方法模式。
2. 变化
- 当拥有多个工厂的时候,工厂方法模式就变化为了多工厂方法模式。
- 当拥有一个工厂的时候,简化掉抽象类,将对应的工厂方法改为静态方法,工厂方法模式就变化为了简单工厂模式,或被称为静态工厂模式,它是工厂方法模式的弱化版本。
3. UML类图
工厂方法模式类图.png角色介绍:
① 抽象工厂Factory:工厂方法模式的核心。
② 具体工厂ConcreteFactory:实现了具体的业务逻辑。
③ 抽象产品Product:工厂方法模式所创建的产品的父类。
④ 具体产品ConcreteProduct:为实现抽象产品的某个具体产品的对象。
4. 通用代码
- 定义抽象产品类Product:
public abstract class Product {
public abstract void method();
}
- 定义具体产品类A
public class ConcreteProductA extends Product {
@Override
public void method() {
System.out.println("具体的产品A");
}
}
- 定义具体产品类B
public class ConcreteProductB extends Product {
@Override
public void method() {
System.out.println("具体的产品B");
}
}
- 定义抽象工厂类
public abstract class Factory {
public abstract Product createProduct();
}
- 定义具体工厂类
public class ConcreteFactory extends Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
- 测试代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Factory factory = new ConcreteFactory();
Product product = factory.createProduct();
product.method();
}
}
12-06 14:15:30.911 14725-14725/com.smartisan.factory I/System.out: 具体的产品A
说明:ConcreteFactory用来具体生产对象:这里我们生产的是产品A的对象,如果想得到产品B的对象,我们修改下代码即可:
public class ConcreteFactory extends Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
12-06 14:18:31.260 15059-15059/com.smartisan.factory I/System.out: 具体的产品B
5. 反射的应用
如果按照以上方式,需要哪个对象就生产哪个对象,当然也可以利用反射更简洁地生产具体产品对象,在工厂方法的参数列表中传入一个Class类来决定是哪一个产品类:
public abstract class Factory {
public abstract <T extends Product> T createProduct(Class<T> tClass);
}
public class ConcreteFactory extends Factory {
@Override
public <T extends Product> T createProduct(Class<T> tClass) {
Product product = null;
try {
product = (Product) Class.forName(tClass.getName()).newInstance();
} catch (IllegalAccessException | InstantiationException | ClassNotFoundException e) {
e.printStackTrace();
}
return (T) product;
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Factory factory = new ConcreteFactory();
Product product = factory.createProduct(ConcreteProductB.class);
product.method();
}
}
12-06 14:28:50.155 15412-15412/com.smartisan.factory I/System.out: 具体的产品B
说明:通过反射,你需要哪一个类的对象就传入哪一个类的类型即可,方法简洁、动态。
6. 多工厂方法模式
我们也可以为每个产品定义一个工厂类,逻辑更清楚,不过类就增多了。
public abstract class Factory {
public abstract Product createProduct();
}
public class ConcreteFactoryA extends Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
public class ConcreteFactoryB extends Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.method();
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.method();
}
}
7. 简单工厂模式
当我们只有一个工厂的时候,我们可以简化掉抽象工厂类,只需要将对应的工厂方法改为静态方法:
public class Factory {
public static Product createProduct(){
return new ConcreteProductB();
// return new ConcreteProductA();
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Product productA = Factory.createProduct();
productA.method();
}
}
说明:简单工程模式是工厂方法模式的弱化版本。
8. 延迟初始化
延迟初始化的意思就是一个对象被消费完毕后,并不立刻释放,工厂类保持其初始状态,等待再次被使用,其实就是把对象缓存,这样不用每次调用就new 对象了。
public class ProductFactory {
public static final int TYPE_PRODUCT_A = 1;
public static final int TYPE_PRODUCT_B = 2;
private static final Map<String, Product> map = new HashMap<>();
public static synchronized Product createProduct(String type) throws Exception {
Product product = null;
if (map.containsKey(type)) {
product = map.get(type);
} else {
if (type.equals(TYPE_PRODUCT_A)) {
product = new ConcreteProductA();
} else {
product = new ConcreteProductB();
}
map.put(type, product);
}
return product;
}
}
说明:Map容器中如果有缓存的对象,就取出来用,如果没有,就生成一个对象并缓存这个对象到Map集合中。
9. 替代单例模式
开发中会有很多类是单例模式的,为了简化代码,我们可以用一个工厂单例类,对这些类进行统一操作,简化需要设置为单例的类,示例如下:
- 定义一个Singleton类:
public class Singleton {
private Singleton() {
}
public void doSomething(){
// 业务处理
System.out.println("哈哈,我是单例模式了");
}
}
说明:这里我们私有了构造方法。
- 定义生成单例的工厂类SingletonFactory:
public class SingletonFactory {
private static final Map<String, Object> map = new HashMap<>();
public static synchronized Object createSingleton(Class clazz) throws Exception {
Object sObject;
if (map.containsKey(clazz.getName())) {
sObject = map.get(clazz.getName());
} else {
Class aClass = Class.forName(clazz.getName());
// 获得无参构造
Constructor constructor = aClass.getDeclaredConstructor();
// 设置无参构造是可访问的
constructor.setAccessible(true);
// 产生一个实例对象
sObject = constructor.newInstance();
// 缓存对象
map.put(clazz.getName(), sObject);
}
return sObject;
}
}
- 测试代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Singleton singleton_01;
Singleton singleton_02;
try {
singleton_01 = (Singleton) SingletonFactory.createSingleton(Singleton.class);
Log.i("fukq", "singleton_01的内存地址:" + singleton_01);
singleton_02 = (Singleton) SingletonFactory.createSingleton(Singleton.class);
Log.i("fukq", "singleton_02的内存地址:" + singleton_02);
} catch (Exception e) {
e.printStackTrace();
}
}
}
12-06 16:04:39.928 17196-17196/? I/fukq: singleton_01的内存地址:com.smartisan.factory.Singleton@879a4a1
singleton_02的内存地址:com.smartisan.factory.Singleton@879a4a1
说明:打印出来的内存地址一样,证明实现了类的单例模式。唯一需要类所做得就是私有自己的构造方法即可。我们想要哪个类实现单例,我们只需要传入它的class名字即可。
10. 源码实现:
以List和Set为例,它俩都继承了Collection接口,而Collection接口继承于Iterable接口。
- Iterable:
public interface Iterable<T> {
Iterator<T> iterator();
...
}
- ArrayList:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
...
public Iterator<E> iterator() {
return new Itr();
}
...
}
private class Itr implements Iterator<E> {
...
}
说明:会看到ArrayList中的iterator方法返回一个ltr迭代器对象。
- HashSet:
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
public Iterator<E> iterator() {
return map.keySet().iterator();
}
...
}
其中map代码:
private transient HashMap<E,Object> map;
其中keySet代码:
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new KeySet();
keySet = ks;
}
return ks;
}
其中KeySet代码:
final class KeySet extends AbstractSet<K> {
public final Iterator<K> iterator() { return new KeyIterator(); }
...
}
说明:会看到HaskSet最终返回的是KeySet中的一个迭代器对象。ArrayList和HashSet中的iterator方法其实就相当于一个工厂方法,转为new对象而生,这里Iterator方法是构造并返回一个具体的迭代器。
11. 后续
如果大家喜欢这篇文章,欢迎点赞!
如果想看更多 设计模式 方面的技术,欢迎关注!
网友评论