1.简介
1.1 模式定义
简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法)
1.2 解决的问题
将“类实例化的操作”与“使用对象的操作”分开,
让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。
即使用者可直接消费产品而不需要知道其生产的细节
1.3 模式组成
组成(角色) | 关系 | 作用 |
---|---|---|
抽象产品(Product) | 具体产品的父类 | 描述产品的公共接口 |
具体产品(Concrete Product) | 抽象产品的子类 | 工厂类创建的目标类 描述生产的具体产品 |
工厂(Creator) | 被外界调用 | 根据传入不同参数从而创建不同具体产品类的实例 |
1.4 使用步骤
创建抽象产品类 & 定义具体产品的公共接口;
创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
创建工厂类,通过创建静态方法根据传入不同参数从而创建不同具体产品类的实例;
外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例
2. 代码演示
2.1 工厂类
package simplefactory;
import simplefactory.impl.Product;
import simplefactory.impl.ProductA;
import simplefactory.impl.ProductB;
import simplefactory.impl.ProductC;
public class Factory {
public Product Manufacture(String ProductName){
//工厂类里用switch语句控制生产哪种商品;
//使用者只需要调用工厂类的静态方法就可以实现产品类的实例化。
if ("A".equals(ProductName)) {
return new ProductA();
} else if ("B".equals(ProductName)) {
return new ProductB();
} else if ("C".equals(ProductName)) {
return new ProductC();
}
return null;
}
}
2.2 产品抽象类(具体产品的父类)
package simplefactory.impl;
//步骤1. 创建抽象产品类,定义具体产品的公共接口
public abstract class Product{
public abstract void method1();
}
2.3 具体产品A
package simplefactory.impl;
//具体产品类A
public class ProductA extends Product {
@Override
public void method1() {
System.out.println("生产出了产品A");
}
}
2.3 具体产品B
package simplefactory.impl;
//具体产品类B
public class ProductB extends Product {
@Override
public void method1() {
System.out.println("生产出了产品C");
}
}
2.4 具体产品C
package simplefactory.impl;
//具体产品类C
public class ProductC extends Product {
@Override
public void method1() {
System.out.println("生产出了产品C");
}
}
3. 测试
package simplefactory;
import simplefactory.Factory;
//工厂产品生产流程
public class SimpleFactoryPattern {
public static void main(String[] args){
Factory mFactory = new Factory();
//客户要产品A
try {
//调用工厂类的静态方法 & 传入不同参数从而创建产品实例
mFactory.Manufacture("A").method1();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要产品B
try {
mFactory.Manufacture("B").method1();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要产品C
try {
mFactory.Manufacture("C").method1();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
//客户要产品D
try {
mFactory.Manufacture("D").method1();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
}
}
4. 小总结:
4.1 优点
将创建实例的工作与使用实例的工作分开,
使用者不必关心类对象如何创建,实现了解耦;
把初始化实例时的工作放到工厂里进行,
使代码更容易维护。更符合面向对象的原则 & 面向接口编程,而不是面向实现编程。
4.2 缺点
工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,
这样就会造成工厂逻辑过于复杂。
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,
会造成工厂角色无法形成基于继承的等级结构。
5. 玩法
定义接口
public interface TestInterFace<T> {
/**
* 处理业务
*/
void handle(T t);
TestEnum getTestEnum();
}
定义抽象类
public abstract class TestInterFaceAbstract<T> implements TestInterFace<T> {
@Override
public void handle(T t) {}
}
定义工厂类
public class TestFactory {
@Autowired
private List<TestInterFace> testInterFaceList;
public void hand(String testType) {
for (TestInterFace testInterFace : testInterFaceList) {
if (testInterFace.getTestEnum().getType().equals(testType)) {
testInterFace.handle(testType);
}
}
}
}
定义实现类
@Service
@Slf4j
public class TestInterFace extends TestInterFaceAbstract<String> {
@Override
public void handle(String s) {
//todo
}
@Override
public TestEnum getTestEnum() {
return TestEnum.INVITE_RETURN_CHECK;
}
}