大厂技术博客学习(1)

与其在各个抄来抄去的技术博客上看,不如直接看大厂博客,这是我觉得看过整体质量最高的博主了。

设计模式最佳套路1—— 愉快地使用策略模式

原文: 设计模式最佳套路1—— 愉快地使用策略模式 - 知乎

  • if-else 不超过 2 层,块中代码 1~5 行,直接写到块中,否则封装为方法
  • if-else 超过 2 层,但块中的代码不超过 3 行,尽量使用卫语句
  • if-else 超过 2 层,且块中代码超过 3 行,尽量使用策略模式

这里的用法,策略+spring,利用ApplicationContextAware建立工厂,使用时从工厂取即可,dubbo读Reference注解也干了一样的事情。

新建一个springboot工程 

类图看一下啊,就是一个策略接口,三个实现类,然后用工厂包策略,利用spring扩展点,在WebApplicationContext initialization completed之后,将上下文给factory,在bean初始化之后,将bean对象加入工厂持有的map中,接口过来就是松耦合的从工厂中获取相应的handler,执行handlerSubmit方法

 策略接口:

package com.strategy.demo.strategy;

import com.strategy.demo.strategy.params.CommonPairResponse;
import com.strategy.demo.strategy.params.FormSubmitRequest;

import java.io.Serializable;

public interface FormSubmitHandler<T extends Serializable>{
    String getSubmitType();
    CommonPairResponse<String,T> handleSubmit(FormSubmitRequest request);
}

策略实现类:

package com.strategy.demo.strategy.Impl;

import com.strategy.demo.strategy.params.CommonPairResponse;
import com.strategy.demo.strategy.FormSubmitHandler;
import com.strategy.demo.strategy.params.FormSubmitRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.ArrayList;

@Component
public class FormHsfSubmitHandler implements FormSubmitHandler<Serializable> {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public String getSubmitType() {
        return "hsf";
    }

    @Override
    public CommonPairResponse<String, Serializable> handleSubmit(FormSubmitRequest request) {
        logger.info("HSF 模式提交:userId={}, formInput={}", request.getUserId(), request.getFormInput());
        // 进行 HSF 泛化调用,获得业务方返回的提示信息和业务数据
        Object data = hsfSubmitData(request);
        CommonPairResponse<String, Serializable> response = CommonPairResponse.success("HSF 模式提交成功!", data);
        return response;
    }

    private Object hsfSubmitData(FormSubmitRequest request) {
        ArrayList<Long> result = new ArrayList<>();
        result.add(165L);
        return result;
    }
}
package com.strategy.demo.strategy.Impl;

import com.strategy.demo.strategy.params.CommonPairResponse;
import com.strategy.demo.strategy.FormSubmitHandler;
import com.strategy.demo.strategy.params.FormSubmitRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class FormModelSubmitHandler implements FormSubmitHandler<Long> {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public String getSubmitType() {
        return "model";
    }

    @Override
    public CommonPairResponse<String, Long> handleSubmit(FormSubmitRequest request) {
        logger.info("模型提交:userId={}, formInput={}", request.getUserId(), request.getFormInput());
        // 模型创建成功后获得模型的 id
        Long modelId = createModel(request);
        return CommonPairResponse.success("模型提交成功!", modelId);
    }

    private Long createModel(FormSubmitRequest request) {
        // 创建模型的逻辑
        return 123L;
    }
}

方法返回:

package com.strategy.demo.strategy.params;

import lombok.Data;

@Data
public class CommonPairResponse<E, T> {

    private String returnCode;
    private String returnMsg;
    private Object data;

    public static <E, T> CommonPairResponse success(E e, T t) {
        CommonPairResponse<E, T> response = new CommonPairResponse<>();
        response.setReturnCode("000000");
        response.setReturnMsg(e.toString());
        response.setData(t);
        return response;
    }

    public static <E, T> CommonPairResponse failure(T t) {
        CommonPairResponse<E, T> response = new CommonPairResponse<>();
        response.setReturnCode("999999");
        response.setReturnMsg(t.toString());
        response.setData(null);
        return response;
    }

    public String getReturnCode() {
        return returnCode;
    }

    public void setReturnCode(String returnCode) {
        this.returnCode = returnCode;
    }

    public String getReturnMsg() {
        return returnMsg;
    }

    public void setReturnMsg(String returnMsg) {
        this.returnMsg = returnMsg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

方法请求 

package com.strategy.demo.strategy.params;

import lombok.Data;

import java.util.Map;

@Data
public class FormSubmitRequest {
    private String submitType;
    private Long userId;
    private Map<String, Object> formInput;

    public String getSubmitType() {
        return submitType;
    }

    public void setSubmitType(String submitType) {
        this.submitType = submitType;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Map<String, Object> getFormInput() {
        return formInput;
    }

    public void setFormInput(Map<String, Object> formInput) {
        this.formInput = formInput;
    }
}

工厂:

package com.strategy.demo.strategy;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@Component
public class FormSubmitHandlerFactory implements InitializingBean, ApplicationContextAware {

    public static final Map<String, FormSubmitHandler<Serializable>> FORM_SUBMIT_HANDLER_MAP
            = new HashMap<>(8);

    private ApplicationContext appContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.appContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 将 Spring 容器中所有的 FormSubmitHandler 注册到 FORM_SUBMIT_HANDLER_MAP
        appContext.getBeansOfType(FormSubmitHandler.class)
                .values()
                .forEach(handler -> FORM_SUBMIT_HANDLER_MAP.put(handler.getSubmitType(), handler));
    }
}

具体serviceImpl

package com.strategy.demo.service.impl;

import com.strategy.demo.service.FormService;
import com.strategy.demo.strategy.FormSubmitHandler;
import com.strategy.demo.strategy.FormSubmitHandlerFactory;
import com.strategy.demo.strategy.params.CommonPairResponse;
import com.strategy.demo.strategy.params.FormSubmitRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Map;

@Service
public class FormServiceImpl implements FormService {

    @Autowired
    private FormSubmitHandlerFactory formSubmitHandlerFactory;

    @Override
    public CommonPairResponse<String, Serializable> submitForm(FormSubmitRequest request) {
        String submitType = request.getSubmitType();

        Map<String, FormSubmitHandler<Serializable>> formSubmitHandlerMap =
                formSubmitHandlerFactory.FORM_SUBMIT_HANDLER_MAP;

        FormSubmitHandler<Serializable> handler = formSubmitHandlerMap.get(submitType);
        if (handler == null) {
            return CommonPairResponse.failure("非法的提交类型: " + submitType);
        }
        CommonPairResponse<String, Serializable> response = handler.handleSubmit(request);
        return response;
    }
}

测试一下

 

提交非法类型时:

 

 OK

以上算是复现完了,再做一下课外作业:

这是xxl-rpc里关于扫描被@XxlRpcService注解的类

package com.xxl.rpc.core.remoting.provider.impl;

import com.xxl.rpc.core.remoting.provider.XxlRpcProviderFactory;
import com.xxl.rpc.core.remoting.provider.annotation.XxlRpcService;
import com.xxl.rpc.core.util.XxlRpcException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;

/**
 * xxl-rpc provider (for spring)
 *
 * @author xuxueli 2018-10-18 18:09:20
 */
public class XxlRpcSpringProviderFactory extends XxlRpcProviderFactory implements ApplicationContextAware, InitializingBean,DisposableBean {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(XxlRpcService.class);
        if (serviceBeanMap!=null && serviceBeanMap.size()>0) {
            for (Object serviceBean : serviceBeanMap.values()) {
                // valid
                if (serviceBean.getClass().getInterfaces().length ==0) {
                    throw new XxlRpcException("xxl-rpc, service(XxlRpcService) must inherit interface.");
                }
                // add service
                XxlRpcService xxlRpcService = serviceBean.getClass().getAnnotation(XxlRpcService.class);

                String iface = serviceBean.getClass().getInterfaces()[0].getName();
                String version = xxlRpcService.version();

                super.addService(iface, version, serviceBean);
            }
        }

        // TODO,addServices by api + prop

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        super.start();
    }

    @Override
    public void destroy() throws Exception {
        super.stop();
    }

}

有没有发现什么相同不同

如果你想加入一个其他的strategy,可以直接面向接口编程,而不需要修改任何的原有类,符合设计模式基本原则

以上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值