身为程序员我们每天都与代码打交道,而编程思想则是程序员在编写程序时所遵循的一种思维方式和方法论。它涵盖了程序员在面对问题时的思考方式、解决问题的方法以及编写代码的技巧和规范,下面简单说一下
我们编程的过程中常见以下三种范式,分别是结构化编程**(Structured Programming)、 面向对象编程(Object-Oriented Programming)以及函数式编程(Functional Programming)**
结构化编程是一种编程范式,它强调在编写程序时应该使用结构化的、清晰、易于理解的控制结构,以提高代码的可读性和可维护性。结构化编程的核心思想是将程序的流程控制结构化为顺序、选择和循环,同时避免使用不受限制的分支和跳转语句。 结构化编程的主要特征包括以下几点:
结构化编程的目标是降低程序的复杂性,减少错误和调试的难度,使代码更具可读性和可维护性。
面向对象编程是一种常用的编程范式,它的核心思想是将程序中的数据(对象)和操作数据的方法(函数)组织成对象,以模拟现实世界中的实体和它们之间的关系。面向对象编程强调数据封装、继承和多态等概念,以提高代码的可重用性、可维护性和可扩展性。 面向对象编程的主要特征包括以下几点:
面向对象编程通常用于构建复杂的软件系统,它将问题分解为对象的组合,每个对象负责特定的任务。这种编程范式有助于提高代码的可维护性、可理解性和可扩展性,因此在现代软件开发中得到广泛应用。许多编程语言,如**Java、C++、Python、C#**等,都支持面向对象编程,提供了类和对象的概念以及相应的语法和工具。
函数式编程是一种编程范式,它将计算视为数学函数的求值过程,强调使用纯函数和避免可变状态和可变数据。函数式编程的核心思想是将计算过程分解为一系列函数的组合和应用,这些函数不会修改状态或产生副作用,而只是根据输入生成输出。函数式编程可以帮助程序员编写更简洁、可维护、并发安全的代码,并提供一种不同于传统命令式编程的思考方式。 函数式编程的主要特征包括:
函数式编程通常用于解决复杂的问题,如并发编程、数据处理、事件驱动编程等。一些编程语言,如Haskell、Scala、Clojure、Elixir等,被设计为纯函数式编程语言,而其他语言,如JavaScript、Python、Java等,则提供了函数式编程的特性和库。函数式编程的思想也在现代编程中得到了广泛的应用,尤其是在大数据处理、分布式系统和前端开发领域。
设计原则和架构之间有着紧密的联系。设计原则是我们进行架构设计的指导思想,它指导我们如何将数据和函数组织成类,以及如何将类链接起来成为组件和程序。而架构的主要工作则是将软件拆解为组件,设计原则则指导我们如何进行拆解、拆解的粒度、组件间依赖的方向以及组件解耦的方式等。
主导原则:OCP(开闭原则) 类和代码的层级上:SRP(单一职责原则)、LSP(里氏替换原则)、ISP(接口隔离原则)、DIP(依赖反转原则) 在组件的层级上:REP(复用、发布等同原则)、CCP(共同闭包原则)、CRP(共同复用原则)。 处理组件依赖问题的三个原则:无依赖环原则、稳定依赖原则以及稳定抽象原则。
这些设计原则和架构的原则都是为了提高软件的可维护性、可扩展性和可重用性。它们帮助我们构建出更加健壮、灵活和高效的系统。
设计原则是做设计时所要依据的准则,它为我们的设计提供向导,体现我们的设计价值观。遵循设计原则可以使我们的代码更加可读性、可维护性和可扩展性。同时,它也可以帮助团队成员更好地理解和维护代码,从而提高团队的协作效率。
开闭原则的目标是提高软件系统的可维护性、可扩展性和可复用性。它鼓励使用抽象、接口、多态等面向对象编程的特性来实现扩展,同时避免破坏现有代码,从而降低了引入新功能时引入错误的风险。
开闭原则通常与设计模式、依赖注入、接口抽象等编程概念和技术一起使用,以创建灵活且易于维护的软件系统。遵循这一原则有助于减少代码的耦合性,提高代码的可测试性,并支持持续集成和持续交付等开发实践。
2.SRP(单一职责原则)
单一职责原则的目标是确保每个类都专注于执行一项明确定义的任务,从而降低了类的复杂性,提高了代码的可理解性和可维护性。它有助于避免类的膨胀和混乱,减少了因修改一个职责而引起的潜在问题。
遵循单一职责原则通常需要进行类的拆分和重构,将大型、复杂的类拆分成多个小而精确的类,每个类负责一个明确的职责。这样的设计有助于降低耦合性,提高代码的可重用性,并支持面向对象编程的其他原则和设计模式。
3.LSP(里氏替换原则)
LSP的目标是确保在使用多态性时,代码可以安全地替换基类的实例为子类的实例,而不会引发错误或破坏程序的正确性。遵循LSP有助于提高代码的可维护性、可扩展性和可重用性,因为它允许开发人员在不改变现有代码的前提下,引入新的子类型。
这一原则的实际应用通常涉及到合理的继承和多态设计,以确保子类型可以无缝替换基类,从而实现面向对象编程的核心特性之一。
4.ISP(接口隔离原则)
ISP原则的目标是减少类之间的耦合性,提高代码的可维护性和灵活性。遵循ISP原则有助于防止类变得庞大而复杂,减少不必要的依赖关系,使代码更易于理解、测试和修改。
一个常见的实践是将一个大型接口分解成多个小型接口,每个接口只包含一组相关的方法。这样,类可以选择性地实现它们真正需要的接口,而不需要强制性地实现不相关的方法。这有助于遵循ISP原则,使接口更加灵活和可定制。
5.DIP(依赖反转原则)
DIP原则的目标是降低模块之间的耦合性,提高代码的可扩展性和可维护性。通过遵循DIP原则,可以实现以下优点:
DIP原则通常与依赖注入**(Dependency Injection)一起使用,依赖注入是一种实现DIP的方式,通过将依赖关系从高层模块外部注入,以确保高层模块不需要自己创建或直接依赖于底层模块的实例。这有助于更好地符合DIP**原则。
6.REP(复用、发布等同原则)
REP原则是指组件中的类与模块必须是彼此紧密相关的,一个组件不能由一组毫无关联的类和组件组成,它们之间应该有一个共同的主题或大致方向。同时,一个组件中包含的类和模块还应该是可以同时发布的,这意味着它们共享相同的版本号与版本跟踪,并且包含在相同的发行文档中。 需要注意的是,REP原则并不适用于所有情况。有时候,将相关的类和模块分离到不同的组件中可能更有利于代码的组织和维护。因此,在实际开发中,我们需要根据具体的需求和项目特点来灵活运用这个原则。
7.CCP(共同闭包原则)
对于大部分应用程序来说,可维护性的重要性要远高于可复用性。如果某个程序中的代码必须要进行某些变更,那么这些变更最好都体现在同一个组件中,而不是分布于很多个组件中。因为如果这些变更都集中在同一个组件中,我们就只需要重新部署该组件,其他组件则不需要被重新验证、重新部署了。 CCP的主要作用就是提示我们要将所有有可能会被一起修改的类集中在一处。也就是说,如果两个类紧密相关,不管是源代码层面还是抽象理念层面,永远都会一起被修改,那么它们就应该被归属为同一个组件。通过遵守这个原则,我们就可以有效地降低因软件发布、验证及部署所带来的工作压力。
通常情况下,类很少会被单独复用。更常见的情况是多个类同时作为某个可复用抽象定义被共同复用。CRP原则指导我们将这些类放在同一个组件中,而在这样的组件中,我们应该预见到会存在着许多相互依赖的类。 CRP原则的作用不仅是告诉我们应该将那些类放在一起,更重要的是要告诉我们应该将哪些类分开。因为每当一个组件应用了另一个组件时,就等于增加了一条依赖关系。虽然这个引用关系仅涉及被引用组件中的一个类,但它所带来的依赖关系丝毫没有减弱。也就是说,引用组件已然依赖于被引用的组件了。 由于这种依赖关系的存在,每当被引用组件发送变更时,引用它的组件一般也需要做出相应的变更。即使它们不需要进行代码级的变更,一般也免不了需要被重新编译、验证和部署。哪怕引用组件根本不关心被引用组件中的变更,也要如此。 因此,当我们决定要依赖某个组件时,最好是实际需要依赖该组件中的每个类。换句话说,我们希望组件中的所有类是不能拆分的,即不应该出现别人只需依赖它的某几个类而不需要其他类的情况。否则,我们后续就好浪费不少时间与精力来做不必要的组件部署。
REP、CCP、CRP 三个原则之间存在彼此竞争的关系,REP 和 CCP 是黏合性原则,它们会让组件变得更大,而 CRP 原则是排除性原则,它会让组件变小。遵守**REP、CCP **而忽略 CRP ,就会依赖了太多没有用到的组件和类,而这些组件或类的变动会导致你自己的组件进行太多不必要的发布;遵守 REP 、CRP 而忽略 CCP,因为组件拆分的太细了,一个需求变更可能要改n个组件,带来的成本也是巨大的。
9.无依赖环原则(Acyclic Dependencies Principle,ADP)
无依赖环原则有助于减少代码复杂性和提高系统的可维护性。它鼓励开发人员在设计和组织组件时考虑依赖关系,并避免不必要的复杂性和错误。这个原则在大型软件系统的设计和架构中特别有用,可以帮助避免潜在的设计问题。
10.稳定依赖原则(Stable Dependencies Principle,SDP)
稳定依赖原则有助于设计和组织软件系统,以确保高层次的模块或组件不容易受到底层模块的变化影响。这有助于降低系统中的意外副作用和错误,提高代码的可维护性和稳定性。在软件架构和设计中考虑稳定依赖原则可以帮助开发人员制定合理的依赖策略。
11.稳定抽象原则
稳定抽象原则与稳定依赖原则一起帮助开发人员设计稳定且易于维护的软件系统。它强调了抽象的重要性,高级别的抽象应该是系统的核心,并且应该是稳定的,以确保系统的稳定性和可维护性。通过合理设计抽象层次和依赖关系,可以更好地应对变化和需求的演化。
编程范式与设计原则是软件开发中的两个关键概念,它们对于构建高质量、可维护和可扩展的软件系统至关重要。编程范式提供了一种编码和思考的方法,而设计原则则为我们提供了一组指导原则,以确保代码的质量和可维护性。 总的来说,编程范式和设计原则是软件开发的基石,它们有助于创建高质量、可维护和可扩展的软件系统。了解它们并将它们应用到实际项目中将有助于提高代码的质量和可维护性,从而为用户提供更好的体验。