入职新公司后熟悉业务过程中收到一个需求,优化一部分代码逻辑,优化时考虑业务的复杂性于是就想到使用设计模式优化这部分逻辑,将原来强耦合的逻辑拆分,便于以后的维护,分析之后确定使用工厂模式与策略模式。

先说下具体业务逻辑:首先业务逻辑中对象分为三个维度,分别为单票、大包、批次,每个维度需要执行不同的逻辑,执行逻辑就需要不同的策略来判断;这里策略有两种情况,分别为首次和重算,最后执行的逻辑则是请求其它服务的具体实现。

基于这种场景,首先考虑就是对于维度的拆分,单票、大包、批次都有不同的枚举状态来判断,这里我考虑的就是通过工厂模式判断枚举值创建对象。第二,对于首次和重算的策略,单票和大包触发策略的逻辑又不相同,这里我就考虑使用策略模式首先不同维度下的不同策略的生成。

工厂模式实现:

代码如下:

  • 创建通用维度的一个对象Dimension,该对象是一个接口呈现的
  1. public interface Dimension {
  2. public void create();
  3. }
  • 创建两个具体的对象Parcel、Container实现Dimension,重写方法

public class Parcel implements Dimension {
@Override
public void create() {
//具体逻辑
}
}

public class Container implements Dimension {
@Override
public void create() {
//具体逻辑
}
}

  • 创建一个工厂接口,定义一个创建对象的方法

public interface DimensionFactory {
public Dimension create(Class c) throws ClassNotFoundException, IllegalAccessException, InstantiationException;
}

  • 创建工厂接口的实现类,用于实现具体的维度对象

public class Factory implements DimensionFactory {
@Override
public Dimension create(Class c) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Dimension dimension = (Dimension)Class.forName(c.getName()).newInstance();
return dimension;
}
}

工厂模式主要实现为创建不同的维度对象,具体需要创建哪个对象不需要我自己去判断,在工厂中实现这个判断逻辑,我最终只负责接收创建的对象即可,这也是我对工厂模式的理解。将创建对象的具体业务逻辑封装在工厂中,使用时只传递对象的状态即可,最终在工厂中会生产出我们想要的对象。并且这样很好的封装了业务逻辑,将对象的创建与业务逻辑拆分,由工厂实现即可。

策略模式实现:

策略模式:可以理解为定义多种策略,每种策略都进行封装,这是对象的一种行为实现。
策略模式实现如下:

  • 创建策略接口
  • 创建具体策略实现类实现策略接口
  1. //策略接口
  2. public interface Tactics {
  3. void router();
  4. }
  5. //具体策略实现,首次路由策略
  6. public class FirstRouter implements Tactics {
  7. @Override
  8. public void router() {
  9. //首次路由逻辑
  10. }
  11. }
  12. //具体策略实现,二次路由实现
  13. public class SecondRouter implements Tactics {
  14. @Override
  15. public void router() {
  16. //路由重算逻辑
  17. }
  18. }
  • 创建封装策略类,封装策略的具体实现
  1. //封装策略,将策略的具体实现进行封装,禁止外部直接访问该具体实现过程
  2. public class RouterPackage {
  3. private Tactics tactics = null;
  4. public RouterPackage(Tactics tactics) {
  5. this.tactics = tactics;
  6. }
  7. public void toDo() {
  8. tactics.router();
  9. }
  10. }

通过业务具体实现过程:
  1. //创建父类接口
  2. public abstract class RouterImpl {
  3. public abstract void router(long dimensionId);
  4. public void doRouter(long dimensionId,int router) {
  5. }
  6. }
  7. //单票首次路由逻辑:
  8. public class ParcelFirstRouter extends RouterImpl{
  9. @Override
  10. public void router(long dimensionId) {
  11. //实现逻辑
  12. }
  13. }
  14. //包裹首次路由实现:
  15. public class ContainerFirstRouter extends RouterImpl{
  16. @Override
  17. public void router(long dimensionId) {
  18. //实现逻辑
  19. }
  20. }

工厂实现:


  1. //创建工厂
  2. public abstract class RouterFactory {
  3. abstract RouterImpl createRouter(Class c);
  4. }
  5. //工厂实现类实现具体的策略
  6. public class FirstRouterFactory extends RouterFactory
  7. {
  8. @Override
  9. RouterImpl createRouter(Class c) {
  10. RouterImpl router = null;
  11. try {
  12. router = (RouterImpl)Class.forName(c.getName()).newInstance();
  13. }catch (Exception e) {
  14. e.printStackTrace();
  15. }
  16. return router;
  17. }
  18. }
  • 将生成的策略执行具体的策略逻辑

    1. public class RouterContext {
    2. private RouterImpl routerImpl;
    3. public RouterContext(RouterImpl router) {
    4. this.routerImpl = router;
    5. }
    6. public void doRouter(long id) {
    7. //具体的执行逻辑
    8. }
    9. }
  • 将工厂模式与策略模式结合实现

    1. public class FactoryAndTactis {
    2. public void sendRouter(long id) {
    3. //创建工厂
    4. ParcelFirstRouterFactory firstRouterFactory = new ParcelFirstRouterFactory();
    5. DimensionEntity parcel = getDimension(id);
    6. //执行首次路由
    7. if (parcel.getType == Dimension.PARCEL_FIRST) {
    8. //首次路由
    9. ParcelFirstRouter parcelFirstRouter = firstRouterFactory.createRouter(ParcelFirstTactis.class);
    10. RouterContext routerContext = new RouterContext(parcelFirstRouter);
    11. routerContext.doRouter(parcel.getId);
    12. } else if (parcel.getType == Dimension.PARCEL_SECOND) {
    13. //二次路由
    14. }
    15. }
    16. }