韩敬海 设计模式(Java版)
(一)定义
定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法涉及的角色有:
1 .抽象工厂角色:工厂方法模式的核心,与应用系统无关,任何创建对象的工厂类必须实现这个接口。
2. 具体工厂角色:实现了抽象工厂接口,被应用程序调用以创建产品对象。
3. 抽象产品角色:定义产品的共性,实现对产品抽象的定义。
4. 具体产品角色:实现抽象产品角色所声明的接口。
(二)类图
(二)代码实现
1. 抽象工厂角色
package com.xiaobai.design_pattern.factorymethod.createrole;
import com.xiaobai.design_pattern.factorymethod.productrole.Cake;
/**
* @author wangtw
* @ClassName Creator
* @description: 抽象工厂角色
* @date 2023/8/622:10
*/
public interface Creator {
Cake factory();
}
2. 抽象产品角色
package com.xiaobai.design_pattern.factorymethod.productrole;
/**
* @author wangtw
* @ClassName Product
* @description: 抽象产品角色
* @date 2023/8/622:16
*/
public interface Cake {
/**
* 获取蛋糕类型
*/
void make();
}
3. 具体工厂角色
(1)苹果蛋糕生成工厂
package com.xiaobai.design_pattern.factorymethod.createrole;
import com.xiaobai.design_pattern.factorymethod.productrole.AppleCake;
import com.xiaobai.design_pattern.factorymethod.productrole.Cake;
/**
* @author wangtw
* @ClassName AppleCakeCrator
* @description: 苹果蛋糕生成工厂(具体工厂角色)
* @date 2023/8/708:23
*/
public class AppleCakeCreator implements Creator{
@Override
public Cake factory() {
return new AppleCake();
}
}
(2)草莓蛋糕生成工厂
package com.xiaobai.design_pattern.factorymethod.createrole;
import com.xiaobai.design_pattern.factorymethod.productrole.Cake;
import com.xiaobai.design_pattern.factorymethod.productrole.StrawberryCake;
/**
* @author wangtw
* @ClassName StrawberryCakeCrator
* @description: 草莓蛋糕生成工厂(具体工厂角色)
* @date 2023/8/708:24
*/
public class StrawberryCakeCreator implements Creator{
@Override
public Cake factory() {
return new StrawberryCake();
}
}
4. 具体产品角色
(1)苹果蛋糕
package com.xiaobai.design_pattern.factorymethod.productrole;
import lombok.extern.slf4j.Slf4j;
/**
* @author wangtw
* @ClassName AppleCake
* @description: 苹果蛋糕(具体产品角色)
* @date 2023/8/707:56
*/
@Slf4j
public class AppleCake implements Cake{
@Override
public void make() {
log.info("正在制作苹果蛋糕");
}
}
(2)草莓蛋糕
package com.xiaobai.design_pattern.factorymethod.productrole;
import lombok.extern.slf4j.Slf4j;
/**
* @author wangtw
* @ClassName StrawberryCakeProduct
* @description: 草莓蛋糕(具体产品角色)
* @date 2023/8/622:34
*/
@Slf4j
public class StrawberryCake implements Cake {
@Override
public void make() {
log.info("正在制作草莓蛋糕");
}
}
5. 测试
package com.xiaobai.design_pattern.factorymethod;
import com.xiaobai.design_pattern.factorymethod.createrole.AppleCakeCreator;
import com.xiaobai.design_pattern.factorymethod.createrole.Creator;
import com.xiaobai.design_pattern.factorymethod.createrole.StrawberryCakeCreator;
import com.xiaobai.design_pattern.factorymethod.productrole.AppleCake;
import com.xiaobai.design_pattern.factorymethod.productrole.Cake;
import org.junit.jupiter.api.Test;
/**
* @author wangtw
* @ClassName FactoryMethodTest
* @description: 工厂方法模式测试类
* @date 2023/8/622:36
*/
public class FactoryMethodTest {
@Test
public void test() {
// 草莓蛋糕生成
Creator creator1 = new StrawberryCakeCreator();
Cake strawberryCake = creator1.factory();
strawberryCake.make();
// 苹果蛋糕生成
Creator creator2 = new AppleCakeCreator();
Cake appleCake = creator2.factory();
appleCake.make();
}
}
输出:
22:58:45.924 [main] INFO com.xiaobai.design_pattern.factorymethod.productrole.StrawberryCake - 正在制作草莓蛋糕
22:58:45.929 [main] INFO com.xiaobai.design_pattern.factorymethod.productrole.AppleCake - 正在制作苹果蛋糕
(三)总结
1. 工厂方法模式优点
(1)提高扩展性:在增加产品类的情况下,只要适当调整具体的工厂类或扩展一个工厂类,就可以适应变化。
(2)调用者不需要关心产品的具体实现,只需要关注产品的接口是否发生变化,因为产品的实例化是由工厂负责的。
(3)解耦:高层模块只需要知道产品的抽象类,不需要关注产品的实现类,符合迪米特法则、依赖倒置原则、里氏替换原则。