Javascript接口/松散耦合

时间:2017-03-08 09:44:25

标签: javascript design-patterns ecmascript-6

在像PHP这样的编程语言中,很多具体的实现都放在接口之后,所以更换具体的实现要容易得多,因为你是在编程接口而不是结构化。

在我们的项目中,我们想要实现一个名为moment.js的日期库来处理我们的日期,但是如果我们在所有的javascript中实现它,就会担心我们的代码会很难耦合。

要在javascript中创建一些接口,方法和属性可以由我们自己的库包装,这样我们可以更容易地换出我们正在使用的concrete日期库以防万一。

我想知道在javascript中是否存在某种模式或标准化方式。乍一看,它只是为我们自己创建一个库,我们将把复杂的可重用逻辑放在引擎盖下使用moment.js。

如果我们仍然在这里和那里使用moment.js功能,我们仍然紧密地联系它。如果我们实现了某种模式,我们只能通过适配器或接口与moment.js进行通信,那么我们就无法实现整个库的包装,这看起来很荒谬。

javascript开发人员如何处理这个问题?

1 个答案:

答案 0 :(得分:3)

我认为有两种方法可以解决这个问题。

  1. 您当前的方法:包装
  2. Duck typing一路走来!
  3. 当我选择包装的#1方法时。

    基本上你对图书馆的API风格不满意。例如,您反对流利API ,反之亦然。因此,您将整个库包装起来感觉更舒适,并且在一天结束时,当您切换到另一个库时,您只需要更改包装器的实现。

    当我选择<#>方式鸭子一直打字时

    您真正了解动态类型语言的优点和缺点,因此您不会被强类型语言的方法所陶醉,但您仍然可以在这两种编程风格上进行开发。

    此外,您已经了解我们开发人员倾向于认为我们每年或5年后都被迫进行技术转换,但这是一种错误的行为,因为做出了正确的决定不是永远的,它们可以在合理的长时间内使用,因此您的系统或应用程序可能需要的不仅仅是从库到另一个库。

    在像JavaScript这样的动态类型语言中,我们可以继续使用文档替换 interfaces 的需要。请检查以下代码段:

    function doStuff(moment) {
        var currentDate = moment(new Date());
    }
    

    是的,你正在注入moment,但是一旦你意识到你需要切换到另一个库,没有什么能阻止你创建一个包装器,因为你知道使用日期或多或少是一样的与任何图书馆。不要再加载 momentjs 并开发整个包装器,并调用自定义代码甚至是一个新的花哨的库!

    function moment(date) {
         return {
              date: date,
              ago: () => {
                  var date = this.date;
    
                  // do the stuff here to return a text like "3 hours ago"
    
                  return text;
              }
         };
    }
    

    你知道除非blabox没有输出给定函数调用者的预期结果,否则这将有效吗?

    你是否会因为某一天你想要从 momentjs 转到谁知道什么而过头?可能不是,因为你可以使用 momentjs 的流畅的API,并且从以相同方式调用并遵循相同API但暴露不同的函数开始创建备用实现并不困难实现。

    一旦你的 duck quack!,谁会关心它还是你的老鸭子还是年轻人?

    你想要另一个建议吗? You're not going to need it,如果你需要它,那就是提供新鸭子的问题。

    关于松耦合

    IMO,动态类型的语言本身就是松散的。由于调用者和被调用者之间没有API标识符(属性名称,函数名称......)之间的其他耦合,因此实现可以通过设计进行热切换。

    也许有一个例外情况:API具有特定于技术的内涵。例如,您需要调用名为sendUsingWebSockets的函数,并且您不希望将其耦合到特定的通信技术,因此您将该特定函数包装为send,并且某些设置定义了要发送的方法数据(REST,WebSockets,WebRTC ......)。

    回答OP在某些评论中解释的一些问题......

      

    剩下的唯一问题是你会对使用a的人说些什么   用于突变目的的包装?人们写一个包装方法   检索一个日期,并通过在其前面加上一些东西来改变它   就像一串'date:'或类似的东西。我一直告诉别人   为这样的情况写一个完整的包装器是不值得的   因为那里它不能保证所有的小日期实例都是   需要相同的'date:'字符串前缀。

    在过去的十年中,Web开发已经发生了很多变化。我们处于UI框架的时代,并且数据绑定存在于每个UI框架中超过5年。

    添加日期与UI要求相关联,我不会在应用程序服务中硬编码。

    例如,旧的AngularJS 1.x具有指令组件,您可以在其中实现该前缀,而无需在模型或服务中使用硬编码前缀:< / p>

    function showDateDirective() {
         return {
             scope: {
                 date: "="
             },
             link: (scope, element) {
                  element.text(`date: ${scope.date.[call here a formatting function]()}`);
             }
         };
    }
    
    module.directive("showDate", showDateDirective);
    

    也就是说,当你需要显示一个日期时,你只需将它绑定到某个元素,该指令将完成剩下的工作:

    <span show-date="model.date"></span>
    

    您需要更改该前缀吗?更改指令实现,您可以在几秒钟内完成工作!