zoukankan      html  css  js  c++  java
  • 简单工厂模式

    本系列总结的设计模式,皆在实际的生产项目中有实际的运用,实例也皆为项目中的例子。

    场景

    需要将net 项目中的一个推荐接口,迁移到java 。

    推荐接口的内容是根据不同的类型做出不同的推荐,历史的net代码冗余太多,大概有7,8个if...呈现在主方法里。每个if里有在相应的biz类中有对应的业务代码。

    如果有新的类型推荐,则会在主方法里新增一个if()...然后再相应的biz  里写业务代码。

    if (request.type = "A")
    {
        //recommend plane
        return response;
    }
    if (request.type = "B")
    {
        //recommend bus
        return response;
    }
    if(request.type = "R")
    {
        //recommend round plane
        return response;
    }
    // C,X ....

    形成原因

    相信所有的业务系统都会有类似的代码,新增一个类型,用if()..可以快速实现逻辑。这样也没有什么问题。

    自己也分析了下,为什么业务系统代码普遍代码质量不高的原因。

      1.逻辑需要快速实现,怎么方便怎么来

      2. 整体的业务系统没有定义一个清晰的代码规则和编码约束。

      3. coder的技术水平层次不齐。

    迁移改造

    这种场景决定用抽象工厂去做相应的改造,根据不同的recommendType 来做出相应的推荐。每种type对应有自己的实现子类.

    Factory类 根据recommenType 去找到对应的子类。

    /**
     * Created by liyangyang on 2017/10/18.
     */
    @Service
    public class RecommendInfoFactory implements IRecommendInfoFactory {
        @Autowired
        @Qualifier("A")
        private RecommendInfoOfTypeA recommendInfoOfTypeA;
    
        @Autowired
        @Qualifier("B")
        private RecommendInfoOfTypeB recommendInfoOfTypeB;
    
        @Autowired
        @Qualifier("Default")
        private RecommendInfoOfTypeDefault recommendInfoOfTypeDefault;
    
        @Autowired
        @Qualifier("H")
        private RecommendInfoOfTypeH recommendInfoOfTypeH;
    
        @Autowired
        @Qualifier("NJSH")
        private RecommendInfoOfTypeNJSH recommendInfoOfTypeNJSH;
    
        @Autowired
        @Qualifier("R")
        private RecommendInfoOfTypeR recommendInfoOfTypeR;
    
        @Autowired
        @Qualifier("X")
        private RecommendInfoOfTypeX recommendInfoOfTypeX;
    
        @Autowired
        @Qualifier("KT")
        private RecommendInfoOfTypeKongTie recommendInfoOfTypeKongTie;
    
        @Override
        public IRecommendInfo getInstance(String recommendType) {
            IRecommendInfo recommendInfo;
            //根据推荐类型,判断推荐内容
            switch (recommendType){
                case "A":
                    recommendInfo = recommendInfoOfTypeA;
                    break;
                case "B":
                    recommendInfo = recommendInfoOfTypeB;
                    break;
                case "H":
                    recommendInfo = recommendInfoOfTypeH;
                    break;
                case "R":
                    recommendInfo = recommendInfoOfTypeR;
                    break;
                case "X":
                    recommendInfo = recommendInfoOfTypeX;
                    break;
                case "NJSH":
                    recommendInfo = recommendInfoOfTypeNJSH;
                    break;
                case "KT":
                    recommendInfo = recommendInfoOfTypeKongTie;
                    break;
                default:
                    recommendInfo = recommendInfoOfTypeDefault;
                    break;
            }
            return recommendInfo;
        }
    }

    推荐的主方法:

    public GetRecommendListResponseType getRecommendList(GetRecommendListRequestType request)
    {
        //根据不同的recommendType 去找到对应的实现子类
        IRecommendInfo recommendInfo = recommendInfoFactory.getInstance(request.getRecommendType());
        //调用实现子类的逻辑得到对应的推荐
        GetRecommendListResponseType response = recommendInfo.getRecommend(request, cityInfo, distance, addition);
        
        return response;
    }

    相应的实现子类 A , B , C 。。。:

    /**
     * Created by liyangyang on 2017/10/18.
     */
    @Service
    @Qualifier("A")
    public class RecommendInfoOfTypeA implements IRecommendInfo{
        @Autowired
        private IGetRecommendListCommonBiz getRecommendListCommonBiz;
    
        @Override
        public GetRecommendListResponseType getRecommend(GetRecommendListRequestType request, RecommendInfoOfCityEntity cityInfo, double distance,
                                                         HashMap<String,String> addition) {
            GetRecommendListResponseType responseType = new GetRecommendListResponseType();
            List<RecommendInfo> recommendInfos = Lists.newArrayList();
    
            //推荐机票
            RecommendInfo recommendInfo = getRecommendListCommonBiz.getRecommendPlane(request, cityInfo, distance,addition);
            if (!Objects.isNull(recommendInfo)) {
                recommendInfos.add(recommendInfo);
                responseType.setRecommendList(recommendInfos);
            }
    
            return responseType;
        }
    }

    优点

     1. 相比 net 中的 if()... 形式,每个子类都对应自己的职责,职责和对应的代码结构更清晰。

     2. 新增一个recommendType, 只需新增对应的实现子类。基本满足对扩展开放,对更改封闭。

    缺点

     1. 类文件太多。

     2. 新增一个recommendType, 还需要在Factory类中,新增一个case 来实现子类的路由。没有满足更改封闭。

    改进

     1. 用抽象工厂 + 反射 来自动路由相应的子类。但反射对应的效率会是个瓶颈。

    PS: java 中的多态实现:一个接口对应不同的实现。比如A,B,C 实现同一个接口。

          java 中spring boot 容器是以接口的形式注入到容器中的。 默认是一个接口只有一个实现类。这样自动装配的时候,就会默认去找到接口对应的实现。

          但如果 一个接口有N个子类实现,spring boot 容器装配的时候就会出错。因为它不知道去装配那个子类。

          在相应的子类上添加 @Qualifier("A") 注解注入,装配的时候也加上 @Qualifier("A") 。

          对应解释: https://www.cnblogs.com/smileLuckBoy/p/5801678.html

    六度与心 修行苦 苦修行
  • 相关阅读:
    Angularjs中文教程
    IE兼容性 css处理常见
    手写画板实现并转化成图片
    canvas 最基本简单的示例
    凡科 网站地址
    IOS学习之路二十二(UIAlertView获得文本框内容及添加北京图片)
    IOS学习之路十四(用TableView做的新闻客户端展示页面)
    IOS开发之路二十一(UIWebView加载本地html)
    iOS学习之路十三(动态调整UITableViewCell的高度)
    IOS学习之路十二(UITableView下拉刷新页面)
  • 原文地址:https://www.cnblogs.com/hdtechnology/p/8734357.html
Copyright © 2011-2022 走看看