根据案例分析传统模式可能存在的问题
需求分析: 以合同签署为例: 有两个不同的产品"AAA"与"BBB",客户进行合同签署,根据产品的不同,进行不同的业务处理,签署合同
传统模式
- 创建多个产品抽象出的公共接口
//产品抽象接口
interface ProductInterface{
//获取产品类型
String getProductType();
}
- 创建产品类ProductA,与ProductB,继承公共的抽象接口
//产品A
class ProductA implements ProductInterface{
private String productType = "AAA";
@Override
public String getProductType() {
return productType;
}
}
//产品B
class ProductB implements ProductInterface{
private String productType="BBB";
@Override
public String getProductType() {
return productType;
}
}
- 创建合同签署类
//传统模式下
class Contract{
//合同签署方法
public void sign(String productType){
if("AAA".equals(productType)){
ProductA productA = new ProductA();
System.out.println(productA.getProductType()+"产品业务代码执行");
}else if("BBB".equals(productType)){
ProductB productB = new ProductB();
System.out.println(productB.getProductType()+"产品业务代码执行");
}else{
System.out.println("没有该产品");
}
//合同签署代码
System.out.println("合同签署成功或失败");
}
}
- 测试客户签署
public class FactoryTest {
public static void main(String[] args) {
Contract contract = new Contract();
//AAA产品签署合同
contract.sign("AAA");
//BBB产品签署合同
contract.sign("BBB");
}
}
分析传统模式下可能出现的问题
- 当前有A与B两个产品,假设后续客户要增加产品C,就需要更改Contract中的代码,违反ocp原则
- 功能代码与业务代码冗余到一块,Contract中的sign()方法实际只关注合同签署是否成功,假设现在已经存在10个产品签署合同,都会调用该方法进行合同签署,假设后续增加其他产品需要更改Contract中的代码,要与以前已存在的进行兼容,比较复杂
简单工厂模式
实现步骤
- 创建产品工厂类,根据不同信息创建不同的产品,将对于产品的业务代码抽取到工厂这边,后续如果有增加新的产品,只需要更改工厂类中的代码
//创建工厂类
class ProductFactory{
//通过给定的信息,创建对应的产品,将对应产品的业务代码放入此处
public static ProductInterface createProduct(String productType){
ProductInterface product = null;
if("AAA".equals(productType)){
product = new ProductA();
System.out.println(product.getProductType()+"产品业务代码执行");
}else if("BBB".equals(productType)){
product = new ProductB();
System.out.println(product.getProductType()+"产品业务代码执行");
}else {
//没有该产品抛出异常
}
return product;
}
}
- 修改原有Contract,将业务与功能进行剥离,各司其职,使Contract只关注合同签署,签署合同时获取的是父接口类型,后续增加产品,修改产品,都不会影响到合同签署功能
class Contract{
//合同签署代码,业务代码与功能代码进行剥离,
//使其只关注功能,需要产品,声明的是父接口类型
public void sign(ProductInterface product){
System.out.println("合同签署成功或失败");
}
}
- 测试
public class FactoryTest {
public static void main(String[] args) {
//通过工厂获取对应的产品对象
ProductInterface product = ProductFactory.createProduct("AAA");
Contract contract = new Contract();
//进行合同签署
contract.sign(product);
}
}
- 根据代码分析我理解的简单工厂模式是: 提供公共的父类例如 ProductInterface, 根据不同的产品创建子类例如ProductA,ProductB,创建工厂类,在工厂类中编写逻辑代码,根据给出的不同信息创建指定的产品对象,将产品与功能进行剥离,功能在需要产品时给出父类即可
分析简单工厂模式的优缺点
- 优点: 业务与功能进行剥离,各司其职,实现责任划分,降低耦合度,有利于软件体系的后续优化等
- 缺点: 分析上面的ProductFactory工厂类,会发现如果增加或删除产品,需要修改该工厂类中的代码,影响系统扩展,并且也是违背了ocp原则的
业务与简单工厂模式的落地示例
- 图标创建:在图形界面应用程序中,常常需要创建各种类型的图标,如圆形、正方形、三角形等。这些图标具有相同的接口,但是实现方式不同。使用简单工厂模式,我们可以将这些不同类型的图标创建过程封装起来,使得客户端只需要提供相应的参数就可以获取到所需的图标对象
- 定义一个图标接口Icon,包含显示图标的方法show()
public interface Icon {
void show();
}
- 定义多个具体的图标类,如CircleIcon、SquareIcon和TriangleIcon,它们都实现了图标接口Icon,并分别实现了自己的show()方法
public class CircleIcon implements Icon {
@Override
public void show() {
System.out.println("This is a circle icon.");
}
}
public class SquareIcon implements Icon {
@Override
public void show() {
System.out.println("This is a square icon.");
}
}
public class TriangleIcon implements Icon {
@Override
public void show() {
System.out.println("This is a triangle icon.");
}
}
- 定义一个图标工厂类,根据参数类型来创建相应的图标对象
public class IconFactory {
public static Icon create(String iconType) {
if (iconType.equals("circle")) {
return new CircleIcon();
} else if (iconType.equals("square")) {
return new SquareIcon();
} else if (iconType.equals("triangle")) {
return new TriangleIcon();
} else {
return null;
}
}
}
- 对外的业务接口: 当用户输入"/circle"、“/square"或”/triangle"时,就会分别创建一个CircleIcon、SquareIcon或TriangleIcon对象,并调用show()方法显示相应的图标类型
@RestController
public class IconController {
@GetMapping("/{iconType}")
public ResponseEntity<String> getIcon(@PathVariable String iconType) {
Icon icon = IconFactory.create(iconType);
if (icon != null) {
icon.show();
return ResponseEntity.ok().body("Icon created successfully.");
} else {
return ResponseEntity.badRequest().body("Invalid icon type.");
}
}
}