SpringBoot 实际项目开发中工厂模式的巧妙使用

简单工厂模式:

       简单工厂模式是创建型模式,创建型模式顾名思义,也就是说在创建对象的时候,遇到了瓶颈才会选择的设计模式。那么该什么情况使用呢。

   简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建并且返回哪一个产品类(这些产品类继承自一个父类或接口)的实例。

 那么也就是说:

   1、有已知的产品类

   2、你无法准确的知道编译哪个产品类

   3、需要在运行时决定创建哪个产品类

   4、产品类不多

   很明显看出,在创建对象上的灵活性高,但是工厂类只能创建可能会使用到的产品类,假如新添了产品类就得修改工厂类,这样就会违反开闭原则。

说明:从 策略模式 到 简单工厂模式(项目最初用策略模式,但遇到一些问题,下面会讲到。后来为了解决问题,改用简单工厂模式)

业务场景:

       本项目是管理硬件操作的后台管理系统,后台系统发一些指令到硬件,硬件返回json数据,后台解析数据,再根据数据返回给前端操作结果,当时首选使用策略模式,根据硬件返回的类型创建不同的类,不同的类进行相应的数据封装,封装后给前端。(比如不同的code,不同的message,不同的object啊);然后在发送的时候,用反射根据类型生成具体封装类。(整个过程用websocket连接,我们后台系统作为客户端发送指令到硬件服务端;同时后台也作为服务端将操作结果发送给浏览器)

例子:

      硬件返回的类型为:end

      接口类:

    public interface ReturnResult{
        public Result returnResult();
    }

     具体业务类

public class End implements ReturnResult{
        public Result returnResult(){
            int code = 200;
            String message = "成功";
            List<String> object = null;
            return Result(code,message,object); 
        }
    }

     策略类:

    public clas ReturnResultStrategy{
        //持有的具体策略的对象
        private ReturnResult returnResult;
        /**
         * 构造函数,传入一个具体策略对象
         * @param returnResult    具体策略对象
         */
        public ParamValidateStrategy(ReturnResult returnResult) {
            super();
            this.returnResult = returnResult;
        }

        /**
         * 策略方法
         */
        public Result retResult(){
            return retResult.returnResult();
        }

    }

       调用地方:

    //获取到的类型 type,从硬件来
    String type = "";
    //反射生成类
    Class<?> forName = Class.forName("com.utils."+type);
    //实例化对象
    Object obj = forName.newInstance();
    ReturnResultStrategy  returnResultStrategy = new ReturnResultStrategy((ReturnResult) obj);
    returnResultStrategy.retResult();

遇到的问题 || 为何改用简单工厂模式?:

在websocket类中,收到硬件发送过来的消息时,根据类型制定具体策略类时报null.

为什么报空呢?因为在某几个策略类中,注入了接口,并通过注入的接口调用了实现类的方法。这样我们就将自己的类交给了 Spring 帮我们管理。而在使用策略类时,是用的new对象。new对象意思就是我们自己管理类。这样一来,我们自己管理类中又让 spring 帮我们管理。那到底谁管理,类就懵逼了。就好像,周末的时候爸爸帮你报了吉他班,妈妈帮你报了舞蹈班;周末了,两个班的老师都打电话让你去学习,是不是很懵逼啊,到底去哪里呢,去吉他班,舞蹈班老师找不到你,只好给你妈妈报空null;去舞蹈班,吉他班老师又会给你爸爸报空null。只要有一个为空,回家都要挨揍,那你到底去哪里呢,横竖都挨揍,算了哪里都不去了,离家出走吧!

经过一系列吹牛逼,最终选择了简单工厂模式,都交给spring吧。

简单工厂:

      首先写一个工厂类:

    @Component
    public class ReturnResultFactory {
        @Autowired
        private Map<String, ReturnResult> context = new ConcurrentHashMap<>();
        
        public ReturnResult getDataViewClass(String rquestTypeStr) {
            return this.context.get(rquestTypeStr);
        }
        
    }

       具体业务类,实现的接口还是上面的接口

       重点在 @Component("end") 这个注解。springq启动的时候,spring的工厂类就会创建对象,用map封装,在这里key就是@Component的value值,值就是 End 这个类

    @Component("end")
    public class End implements ReturnResult {
        @Autowired
        private ResponseDataParse responseDataParse;
        
        /**
          *以下代码可以不用理解,只需要知道调用了注入进来的接口中的方法就ok了
        **/
        @Override
        public ResponseViewData returnRespViewData(String rquestTypeStr,String taskId,String data){
            if(rquestTypeStr.equals(WSRequestType.TAKE_BOX.getValue())){
                return responseDataParse.parseTakeBoxData(data);
            }else if(WSRequestType.STORE_BOX.getValue().equals(rquestTypeStr)){
                return responseDataParse.insertData(data);  
            }
            return null;
        }
    }

      调用的地方:

    @ClientEndpoint()
    @Component
    public class WSClient {

        @Resource
        ResponseViewDataStreategyFactory factory;

        public static WSClient wsClient;

        @PostConstruct
        public void init() {
            wsClient = this;
        }

        @OnMessage
        public void onMessage(String message){
            //message转成json对象后从中获取type
            String type = "";
            ReturnResult returnResult = wsClient.factory.getDataViewClass(type);
        }

    }

区别总结

 从上面的描述总结出,在运行时,两者都是通过传入参数进行配置,简单工厂模式则是选择创建出需要的对象,而策略模式则是配置出需要的行为算法。一个是对象创建,另一个是行为算法的替换。

猜你喜欢

转载自blog.csdn.net/weixin_40841731/article/details/83861285