`
dingjob
  • 浏览: 183280 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

代码注意降低接口提供者和调用者的耦合度

阅读更多
描述: 写代码时,接口中尽量封装为对外透明,外面只管调用,不用关心
自己的状态。

比较下三段比较简单的代码:用于下单和删除时客户付费状态修改



1. updateCustomerPayingToExperience,updateCustomerExperienceToPaying 分开
if (ChanOrder.CONVERT_FEE_ORDER.equals(order.getIsConvertFee())) {
   this.updateCustomerPayingToExperience(order.getCustomerId());
    }
  }
 
if (ChanOrder.CONVERT_FEE_ORDER.equals(order.getIsConvertFee())) {
   this.updateCustomerExperienceToPaying(order.getCustomerId());
 }





2.第一次修改,两个方法合并,状态互转,只要都调这个方法就够了,调用接口处还是
要判断。

public void updateCustomerFeetype(CustomerDO customer) {
  
  String feeType = ChannelConstant.CHAN_CUSTOMER_FEE_TYPE_EXPERIENCE;
  // 获取客户当前付费状态,如果是试用客户,转化为付费客户。
  if (ChannelConstant.CHAN_CUSTOMER_FEE_TYPE_EXPERIENCE.equals(customer.getFeeType())) {
   feeType = ChannelConstant.CHAN_CUSTOMER_FEE_TYPE_PAYING;
  } 
  // 修改客户付费状态
  chanCustomerBOService.updateCustomerFeetype(customer.getCustomerId(), feeType);
 }


3.第二次修改,根据订单状态判断,任何地方调用都不会出错,接口出无需判断:
public void modifyCustomerFeeType(String customerId) {
  boolean hasFeeOrder = false;// 存在付费订单(包含试用转付费)
  boolean hasExperienceOrder = false;// 存在试用订单
  String customerFeeType;// 客户订单状态
 
  // 1.取得客户所有订单
  List<ChanOrder> orderList = channelOrderCommonDAO.getOrdersByCustomerId(customerId);
  for (ChanOrder order : orderList) {
   if(ChanOrder.ORDER_STATUS_ABOLISHED.equals(order.getStatus())){
    //作废订单不作为判断依据
    continue;
   }
   
   // 判断是否包含试用订单和付费订单
   if (ChanOrder.FEE_TYPE_YES.equals(order.getFeeType())) {
    hasFeeOrder = true;
   } else {
    hasExperienceOrder = true;
   }
  }
 
  // 2.仅当存在试用订单且不存在付费订单时,客户为试用客户
  if (hasExperienceOrder && !hasFeeOrder) {
   customerFeeType = CustomerDO.CUSTOMER_FEE_TYPE_FREE;
  } else {
   customerFeeType = CustomerDO.CUSTOMER_FEE_TYPE_PAID;
  }
  
  // 3.更新客户付费状态
  chanCustomerBOService.updateCustomerFeetype(customerId, customerFeeType);
 
 }


  总结下:
  降低耦合度是封装的要求,最近看了《代码大全》这本书关于接口的要求,颇有感触:
其中有这样一句话"不要对类的使用者做出任何假设,类的设计和实现应该符合在类的接口中所隐含的契约。它不应该对接口会被如何使用或不会被如何使用做出任何假设——除非在接口中有过明确说明"
  显然就是说要假设调用你的接口的人就是什么也不懂,随随便便就调用了,这种情况下不会出错。这也许就是对耦合度最朴素的解释。正常的流程就是这样,你提供了接口,就要对接口负责,我调用者不需要了解细节,对调用者完全是透明的。

  如下几段关于耦合的话也比较经典,不加修饰的摘抄一下:
让阅读代码比编写代码更方便,阅读代码的次数要比编写代码多得多,即使在开发的初期也是如此。因此,为了让编写代码更方便而降低代码的可读性是非常不经济的。尤其是在创建类的接口时,即使某个子程序与接口的抽象不很相配,有时人们也往往把这个子程序加到接口里,从而让正开发的这个类的某处调用代码能更方便地使用它。然而,这段子程序的添加正是代码走下坡路的开始,所以还是不要走出这一步为好。

留意过于紧密的耦合关系  “耦合(coupling)”是指两个类之间关联的紧密程度。通常,这种关联越松(loose)越好。根据这一概念可以得出以下一些指导建议:

■           尽可能地限制类和成员的可访问性。

■           避免友元类,因为它们之间是紧密耦合的。

■           在基类中把数据声明为private而不是protected,以降低派生类和基类之间耦合的程度。

■           避免在类的公开接口中暴露成员数据。

■           要对从语义上破坏封装性保持警惕。

■           察觉“Demeter(得墨忒耳)法则”(见本章第6.3节)

  合性与抽象和封装性有着非常密切的联系。紧密的耦合性总是发生在抽象不严谨或封装性遭到破坏的时候。如果一个类提供了一套不完整的服务,其他的子程序就可能要去直接读写该类的内部数据。这样一来就把类给拆开了,把它从一个黑盒子变成了一个玻璃盒子,从而事实上消除了类的封装性。

   同样关于,内聚性,这里也有比较好的诠释,搭车写一下:
内聚性要求接口类要实现抽象的一致性,方法要实现数据操作,存取等的一致性,我们写代码时,往往关注于快速实现和所谓的敏捷开发,而忘记了这个接口最初是用来干什么的,让接口变得臃肿不堪,难于维护,这实际上会让你后来的开发变得越来越不敏捷。因此良好的内聚性和接口的良好封装也应该成为我们的规范。

0
0
分享到:
评论

相关推荐

    WebServices服务接口调用---用ducument方式应用

    这种方式降低了服务与客户端之间的耦合度,使得服务更加通用,能够处理各种不同数据格式的请求。 在实现Document风格的Web服务时,通常会用到WSDL(Web Service Description Language)来描述服务接口和消息格式。...

    untiy 事件管理器,分发注册的事件,有效降低模块耦合度

    在Unity游戏开发中,事件管理系统是实现不同游戏对象间通信的关键工具,它允许组件之间以非侵入式的方式相互交互,从而降低了模块间的耦合度。"untiy 事件管理器,分发注册的事件,有效降低模块耦合度"这个标题恰好...

    springcloud feign 服务消费者 类似 webservice

    Feign的设计灵感来源于Netflix的Feign库,它的主要目的是简化微服务之间的通信,使得开发者可以像定义接口一样调用远程服务,从而降低了服务消费者与提供者的耦合度。 在传统的Web Service(WebService)中,我们...

    接口 接口的应用

    在编程领域,接口是一个至关重要的概念,尤其是在面向...通过接口,我们可以让代码更加模块化,降低耦合度,提高代码复用性和可扩展性。在实际项目中,无论是小型应用还是大型企业级系统,接口都是不可或缺的一部分。

    面向接口编程理解demo

    这降低了类与类之间的耦合度,使得系统更加灵活,易于修改和扩展。 2. **多态性**:通过接口,我们可以实现多态,即不同的类可以实现同一个接口,调用者只需知道接口,而无需关心具体实现。这增强了代码的复用性和...

    c++接口隔离原则1

    2. 为依赖接口的类定制服务,仅提供调用者需要的方法,屏蔽不需要的方法。 3. 了解环境,拒绝盲从,根据项目或产品的环境因素来拆分接口。 4. 高度内聚,减少对外交互,使接口用最少的方法去完成最多的事情。 应用...

    C语言接口与实现--创建可重用软件的技术源代码

    一个良好的接口设计可以使代码更易于理解和使用,降低耦合度,提高模块化程度,从而促进代码的复用。在C语言中,接口通常通过函数原型、结构体和枚举类型来定义。通过阅读`cinterface_source`中的代码,我们可以看到...

    接口的多态实现

    接口多态的实现不仅提高了代码的可读性和可维护性,还降低了类之间的耦合度。当需要添加新的功能或者替换现有功能时,只需添加新的接口或实现现有接口的新类,而无需修改现有代码。这对于大型项目和团队协作尤其重要...

    面向接口编程。面向接口编程。

    6. **降低耦合度**:通过将具体实现隐藏在接口之后,可以减少组件之间的相互依赖,从而降低系统的复杂性。 7. **模块化设计**:在大型项目中,面向接口编程有助于创建独立的模块,每个模块都有清晰的职责和接口定义...

    java面向接口编程

    2. **松耦合**:接口调用者与实现者之间通过接口连接,两者之间不必了解对方的实现细节,降低了耦合度。 3. **易测试**:接口使测试变得更加容易,因为可以方便地使用模拟对象(mock object)代替实际实现进行单元...

    WinForm跨窗口调用实例代码

    这种方法可以降低窗体之间的耦合度。 7. **依赖注入(Dependency Injection)**:在窗体构造函数中注入需要的服务或数据,使得窗体在创建时就能获取到所需资源,而不必直接引用其他窗体。 在实践中,选择哪种方法...

    利用c#编写的简单的接口实现

    - **解耦**:通过接口,实现类可以独立于调用者,降低耦合度。 - **多态性**:接口提供了一种方式,让不同类型的对象可以通过相同的方式交互。 8. **泛型接口** C#也支持泛型接口,可以限制实现接口的类型: `...

    接口操作数据库的简单实现

    这样可以降低耦合度,提高代码的可测试性和可维护性。 5. **JDBC(Java Database Connectivity)**:对于Java开发者,JDBC是连接数据库的标准API。我们可以通过实现特定的接口,比如`java.sql.Connection`、`java....

    观察者模式代码

    观察者模式,也被称为发布-订阅(Publish-Subscribe)模式,是软件设计模式中的行为模式之一,主要用于定义...在实际开发中,合理运用观察者模式可以提高代码的可读性,降低模块间的耦合度,提升系统的整体架构质量。

    中介者模式代码示例

    这个模式的主要目的是通过引入一个中介对象来封装一系列对象之间的交互,使得这些对象不必显式地相互引用,从而让对象间的耦合度降低,提高系统的可维护性和可扩展性。在这个“中介者模式代码示例”中,我们将会深入...

    Spring_依赖注入_面向接口编程

    这样,当我们需要更换服务实现时,只需更改配置,而无需修改调用者的代码。 在本项目"Spring_依赖注入_面向接口编程"中,`Spring2`可能包含以下内容: - 一个Spring配置文件(如`applicationContext.xml`),用于...

    Java语言程序设计_第5章_接口与多态课件及源代码

    3. **解耦合**:通过接口,类与类之间可以通过接口进行通信,降低了它们之间的耦合度。 多态性则是面向对象的一个重要特性,它允许我们用一个父类类型的引用操作子类的对象,或者将父类作为参数传递给方法。Java中...

    Visitor模式

    在Java中,`javax.lang.model.element.Element`接口和一系列实现类就是访问者模式的应用,它们提供了`accept()`方法,接受一个`ElementVisitor`。开发者可以自定义`ElementVisitor`来实现特定的访问行为,如生成源...

    设计模式-访问者模式(讲解及其实现代码)

    **访问者模式详解** 访问者模式是一种行为设计模式,它允许在不修改对象结构的情况下向对象添加新的操作。这种模式的核心思想是将数据结构与算法分离,使得算法...不过,也需要注意其带来的耦合度和结构变更的挑战。

Global site tag (gtag.js) - Google Analytics