面向对象的六大原则

一、单一职责原则

        每一个类只负责一项工作或职责,类中应该是一组相关性很高的函数、数据的封装。

        定义职责:根据具体的经验和具体的业务逻辑、功能进行拆分。

        降低代码耦合度:通过职责拆分,类之间的依赖关系更清晰,降低代码的耦合度。

        提高可维护性和可读性:单一职责的类更容易维护,开发者可以快速定位到问题的具体位置,不需要额外阅读大量无关的代码。

        促进重用性:单一职责或功能的类更易于在其他上下文中重用,功能单一也更容易集成到其他项目中。

二、开闭原则

        软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是对于修改时封闭的。

  • 对扩展开放:当需求变化时,应该能够通过添加新的代码而不是修改已有的代码来扩展软件的行为。例如,在一个图形编辑器中,若要支持新的形状类型,应当能够在不修改现有形状处理逻辑的情况下,实现并添加这种新形状的支持。

  • 对修改关闭:已经经过测试和验证的代码不应该因为需求的变化而被直接修改,以避免引入新的错误。保持原有代码的稳定性是开闭原则的核心思想之一。

        实现策略
  • 使用抽象构建框架:通过定义抽象层(如接口或抽象类),可以让具体实现细节依赖于这些抽象而非其他具体实现。这样,当需要新增功能时,只需添加新的具体类而不必修改原有的抽象层。

  • 多态的应用:利用面向对象编程中的多态特性,使得同一操作作用于不同的对象可以有不同的解释,从而产生不同的执行结果。比如,通过方法重写,子类可以提供特定于自身的实现,同时保持父类方法签名不变。

  • 设计模式的支持:许多设计模式如策略模式、观察者模式等都体现了开闭原则的思想。它们提供了灵活的机制来扩展系统行为,而无需修改现有的代码结构。

三、里氏替换原则

        里氏替换原则的核心在于确保继承关系中的子类可以替代父类被使用时,程序的行为应该是正确的。这意味着子类不仅需要实现父类的所有方法,还不能改变这些方法的预期行为。

  • 避免违反LSP的情况

    • 前置条件不得加强:子类的方法不能比父类的方法要求更严格的输入参数。
    • 后置条件不得削弱:子类的方法返回的结果至少要满足父类方法的契约(即保证至少相同的输出质量或范围)。
    • 副作用必须一致:子类方法执行过程中产生的任何副作用都应与父类方法保持一致。
  • 实际应用中的考虑

    • 接口隔离原则的应用:为了更好地遵循LSP,有时候需要重新审视类的设计,可能需要通过接口隔离原则将庞大的接口拆分成多个小接口,使得不同的子类只需要实现与其职责相关的接口部分。
    • 谨慎使用继承:不是所有的类间关系都适合用继承表达。有时,组合或其他设计模式可能是更好的选择,以避免强制实现不合理的LSP约束。

四、依赖倒置原则

        高层次模块不应该依赖于低层次模块,二者都应该依赖于抽象;同时,抽象不应该依赖于细节,细节应该依赖于抽象。

  • 高层次与低层次模块
    • 高层次模块包含复杂的业务逻辑或决策规则。
    • 低层次模块通常实现具体的、基础的功能,如输入输出、设备访问等。

传统上,高层次模块直接调用低层次模块,形成紧耦合关系。依赖倒置原则主张打破这种直接依赖,通过引入抽象层来解耦两者。

  • 依赖于抽象而非具体实现
    • 抽象化:使用接口或抽象类定义高层次和低层次模块之间的交互方式。这样做的好处是可以在不改变高层代码的情况下替换不同的底层实现。
    • 反转控制:将依赖关系从“高层模块 → 低层模块”转变为“高层模块 ← 抽象层 → 低层模块”。这种转变允许系统更加灵活地适应变化,因为具体的实现可以通过依赖注入等方式动态配置。
        实现策略
  • 依赖注入(Dependency Injection, DI):这是一种常见的实现依赖倒置的方式,其中外部实体负责提供依赖的对象给需要它们的组件,而不是让这些组件自己创建依赖对象。这可以通过构造函数注入、属性注入或方法注入完成。

  • 工厂模式和策略模式:这两种设计模式经常用于支持依赖倒置。工厂模式可以用来创建一系列相关对象而不指定具体类型,而策略模式允许算法在运行时相互替换,都是基于抽象而非具体实现的例子。

  • 接口隔离原则的应用:为了更好地遵循依赖倒置原则,可能还需要应用接口隔离原则(Interface Segregation Principle),即不应强迫客户端依赖它们不使用的接口。通过细分接口,可以让每个接口只包含特定的行为,从而使得依赖更加清晰和集中。

五、接口隔离原则

        一个接口应该只包含客户端所需要的方法,而不应包含那些不需要的方法。这有助于减少接口的“胖”化,使得系统更加模块化、易于维护和扩展。

        详解

  • 避免“胖”接口:当一个接口包含过多的方法时,它可能会被多个不同的客户端使用,但并不是每个客户端都需要所有的方法。这种情况下,这个接口被称为“胖”接口。“胖”接口会导致不必要的耦合,因为实现类必须提供所有声明的方法,即使某些方法对特定的客户端没有意义。

  • 细分接口:ISP建议将大的接口拆分为更小、更具体的接口,以便不同的客户端只需要知道并实现与它们相关的那部分接口。这样可以提高代码的可复用性和灵活性。

        实现策略
  • 角色接口模式(Role Interface Pattern):为不同类型的客户端定义专门的角色接口。例如,在一个支付系统中,如果存在多种支付方式(信用卡支付、PayPal支付等),则可以为每种支付方式定义独立的接口,而不是让所有支付方式都实现同一个庞大的接口。

  • 分离关注点:通过细分接口,可以更好地分离系统的不同功能模块,使得每个模块只关注自己的职责。这样做不仅简化了模块间的交互,还提高了代码的清晰度和可维护性。

六、迪米特原则

        又称为最少知识原则(Principle of Least Knowledge),是面向对象设计中的一项重要原则。它旨在通过限制对象之间的交互来降低系统的耦合度,从而提高系统的灵活性和可维护性。

        迪米特原则的核心思想

迪米特原则建议一个对象应当尽可能少地与其他对象发生直接交互,尤其是避免与那些并非直接朋友的对象进行交互。具体来说,对象只能与以下几种对象进行交互:

  1. 自身:对象可以调用自身的成员方法。
  2. 直接组成部分:对象可以直接访问其属性或成员对象的方法。
  3. 作为参数传递进来的对象:方法调用过程中传入的对象。
  4. 在方法内部创建的对象:在方法内部临时创建的对象。

        详解

  • 减少耦合:遵循迪米特原则有助于减少类之间的依赖关系,从而降低系统中的耦合度。当一个类的内部实现发生变化时,如果该类只与其直接的朋友交流,那么这种变化对其他类的影响将被最小化。

  • 增强模块独立性:通过限制对象之间的交互范围,迪米特原则鼓励开发者构建更加独立、自包含的模块。每个模块只需关注自己的职责,而不需要了解整个系统的复杂细节。

你可能感兴趣的:(android,面向对象)