设计模式-工厂方法模式
设计模式—工厂方法模式
定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类
优点:
- 良好的封装性,代码结构清晰
- 良好的扩展性
- 典型的解耦架构
代码
首先定义一个产品的接口
1
2
3public interface Product {
void say();
}然后定义产品A,产品B 实现产品接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class ProductA implements Product {
public void say() {
System.out.println("this is product A");
}
}
public class ProductB implements Product {
public void say() {
System.out.println("this is product B");
}
}现在定义一个抽象的工厂类 以及一个产品的工厂类,使用泛型,包含创建产品的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public abstract class AbstractProductFactory {
public abstract <T extends Product> T createProduct(Class<T> cls);
}
public class ProductFactory extends AbstractProductFactory {
public <T extends Product> T createProduct(Class<T> cls) {
Product product = null;
try {
product = (Product) Class.forName(cls.getName()).newInstance();
// product = cls.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) product;
}
}现在就可以测试工厂类去创建产品对象了
1
2
3
4
5
6
7
8
9
10
11
12
13public class ProductFactoryTest {
public void testFactory(){
AbstractProductFactory factory = new ProductFactory();
Product a = factory.createProduct(ProductA.class);
a.say();
ProductB b = factory.createProduct(ProductB.class);
b.say();
}
}从上面创建对象的方式可以看出没有使用new 关键字,也就实现了解耦
扩展
简单工厂模式
当一些模块只需要一个工厂类的时候,没有必要将工厂类实例化出来,这是就可以使用简单工厂模式来实现,去掉抽象工厂类并将工厂类的方法设为static
1
2
3
4
5
6
7
8
9
10
11
12public class SimpleProductFactory {
public static <T extends Product> T createProduct(Class<T> cls){
Product product = null;
try {
product = (Product) Class.forName(cls.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) product;
}
}多工厂模式
当项目比较复杂且产品的实现类比较多时,可以考虑为每个产品创建一个工厂类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public abstract class MultiAbstractFactory {
public abstract Product createProduct();
}
public class ProductAFactory extends MultiAbstractFactory {
public Product createProduct() {
return new ProductA();
}
}
public class ProductBFactory extends MultiAbstractFactory {
public Product createProduct() {
return new ProductB();
}
}替代单例模式
利用反射代替单例模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public class Singleton {
//私有构造
private Singleton(){}
}
public class SingletonFactory {
private static Singleton singleton;
static {
try {
Class cls = Class.forName(Singleton.class.getName());
Constructor constructor = cls.getDeclaredConstructor();
constructor.setAccessible(true);
singleton = (Singleton) constructor.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
public static Singleton getSingleton(){
return singleton;
}
}