V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ooToo
V2EX  ›  程序员

接盘项目重构优化, 求解? 或者简单点, 接入了几家不同的供应商, 怎么实现

  •  
  •   ooToo · 2017-07-12 23:41:17 +08:00 · 2175 次点击
    这是一个创建于 2695 天前的主题,其中的信息可能已经有所发展或是发生改变。

    接入了几家不同的供应商, 需要调用供应商的 http 接口. 供应商接口逻辑大同小异(个别参数有差别, 同一接口 URL 基本不一样的), 怎样实现好些呢? 策略设计模式?


    现在实现方案是这样的, 请 v 友帮忙看下怎么优化好些, 或者帮忙指下这里有哪些硬伤, 多谢了.
    如示例代码, VendorBase 是一个接口, FirstVendorImpl, SecondVendorImpl 分别是两家供应商对接的实现, 分别从 FirstVendorAPI, SecondVendorAPI 拿到参数和 URL.
    但是 FirstVendorImpl, SecondVendorImpl 逻辑是一样的很多重复代码, 为了使用 FirstVendorAPI 和 SecondVendorAPI.
    如代码中所示 FirstVendorAPI 都是 static 常量, static method. 想把 VendorAPI 抽象出来, 变量和方法都改成非 static 的.
    FirstVendorAPI 和 SecondVendorAPI 都继承 VendorAPI, 每次获取参数都通过对象来获取可以吗?
    public class FirstVendorAPI {
            public static final String REGISTER_ACCOUNT_URL = "/registerAccount";
    
            public static final JSONObject getRegAccountParams(String id) {
                JSONObject params = new JSONObject();
                params.put("id", id);
                return params;
            }
    }
    
    public class SecondVendorAPI {
        public static final String REGISTER_ACCOUNT_URL = "/2/registerAccount";
    
        public static final JSONObject getRegAccountParams(String id) {
            JSONObject params = new JSONObject();
            params.put("id", id);
            return params;
        }
    }
    
    
    public class FirstVendorImpl  extends VendorBase {
        @Override
        public String registerAccount(String id) {
    
            JSONObject params = FirstVendorAPI.getRegAccountParams(id);
            String url = FirstVendorAPI.REGISTER_ACCOUNT_URL;
            JSONObject retJsonObj = getHttpsResponse(url, params);
        }
    }
    
    public class SecondVendorImpl  extends VendorBase {
    
    }
    
    第 1 条附言  ·  2017-07-13 09:16:08 +08:00

    FirstVendorAPI,SecondVendorAPI这两个实现太笨了, 很多方法都是一样的, 再加入新的vendor又复制好多代码 下面这样会好点吗

    
    public class ApiBase {
            public String REGISTER_ACCOUNT_URL = "/registerAccount";
    
            public JSONObject getRegAccountParams(String id) {
                JSONObject params = new JSONObject();
                params.put("id", id);
                return params;
            }
    }
    public class FirstVendorAPI extends ApiBase {
           //变量覆盖父类, (总感觉配置的URL这样写, 放到对象里不合适)
    //或者构造参数的方法跟URL分开, 放到不同实现类里?
            public String REGISTER_ACCOUNT_URL = "/registerAccount";
    
           //有必要就扩展, 否则返回父类方法
            public JSONObject getRegAccountParams(String id) {
                  
            }
    }
    
    5 条回复    2017-07-13 09:17:09 +08:00
    sagaxu
        1
    sagaxu  
       2017-07-13 01:31:20 +08:00 via Android   ❤️ 1
    去年接盘过一个类似项目,复制粘贴的代码特别多,到处 switch(vendorId),然后自家平台作为 vendor 时还是单独一套完全不同的逻辑,十来家 vendor,相当混乱。

    后来我采取了边开发新需求边重构的方式,第一步,先定义一个 interface,所有的 vendor 都实现这个 interface,等稳定运行了几周后,开始了第二步,消除了 switch,从 vendorId 到 vendorImpl 采用查表的方式,并且所有接口都面向第一步重构出的 interface。然后是第三步,把自己平台当做一个普通 vendor 处理,消除特殊处理逻辑。第四步,还没做完,就是抽出 basevendor,更大程度的复用 vendor 的实现,等这步做完,就可以很方便的把 http 改为异步调用了。现在已经 20 几家 vendor 了,但是代码行数比原来还少了。
    ghos
        2
    ghos  
       2017-07-13 08:53:16 +08:00 via Android   ❤️ 1
    目前也是 多实现+查表路由 楼下的大佬们有更好的办法吗
    ooToo
        3
    ooToo  
    OP
       2017-07-13 09:03:43 +08:00
    @sagaxu @ghos 感谢两位
    ghos
        4
    ghos  
       2017-07-13 09:04:28 +08:00
    ooToo
        5
    ooToo  
    OP
       2017-07-13 09:17:09 +08:00
    @ghos 好的, 多谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5315 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 03:52 · PVG 11:52 · LAX 19:52 · JFK 22:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.