Java细数面向对象的十大设计原则有哪些

网友投稿 289 2022-07-26


目录1 概述2 十大设计原则2.1 DRY (Don’t repeat yourself)2.2 封装变化2.3 开闭式设计原则2.4 单一责任原则2.5 依赖反转原则2.6 喜欢复合胜过继承2.7 里式替换原则2.8 接口隔离原则2.9 为接口编程而不是实现2.10 授权原则3 总结

1 概述

面向对象设计原则是 OOP 编程的核心,但我见过大多数 java 程序员追求设计模式,比如单例模式、修饰模式或者观察者模式,却没有把足够的精力放在学习面向对象的系统分析上。

学习抽象、封装、多态和继承等面向对象程序设计的基础知识是很重要的。但与此同时,了解面向对象设计原则也同样重要。

我经常见到不同经验水平的 Java 程序员和开发人员,他们要么从未听说过这些 OOP 和 SOLID 设计原则,要么根本不知道特定设计原则提供了什么好处,以及如何在编码中应用这些设计原则。

尽管学习任何设计原则或模式的最好方法是通过一个现实世界的例子来理解违反这一设计原则的后果,但本文的主题是介绍 Java 程序员的面向对象设计原则,这些程序员要么没有接触过这些原则,要么处于学习阶段。

2 十大设计原则

2.1 DRY (Don’t repeat yourself)

我们的第一个面向对象设计原则是 DRY,顾名思义就是 DRY (不要重复你自己) ,意思是不要写重复的代码,而是使用抽象。

如果在两个以上的地方有一个代码块,可以考虑将其作为一个单独的方法,或者如果多次使用hard-coded值,则将其作为公开的 final 常量。这个面向对象设计原则的好处在于维护。

2.2 封装变化

在软件领域,只有一件事情是不变的,那就是“变化”。所以,封装你期望或怀疑将来会变化的代码。

如果你使用 Java 编码,那么遵循默认情况下将变量和方法设为私有的原则,并逐步增加访问权限,就像从私有到受保护而不是公有一样。

在 Java 中的一些设计模式使用封装,工厂设计模式是封装的一个例子,它封装了对象创建代码,并提供了以后引入新产品的灵活性,对现有代码没有影响。

2.3 开闭式设计原则

根据这个 OOP 设计原则,“类、方法或函数应该为扩展打开(新功能) ,为修改关闭”。

理想情况下,如果您只是添加新的功能,那么您的代码应该经过测试,这就是开放关闭设计原则的目标。

2.4 单一责任原则

单一责任原则是另一个 SOLID 设计原则,在 SOLID 缩写上代表“ s”。根据 SRP,一个类更改的原因不应该超过一个,或者一个类应该总是处理单个功能。

这个原则的主要好处是它减少了软件的单个组件和代码之间的耦合。

例如,如果你在 Java 的一个类中放置了多个功能,它会引入两个功能之间的耦合,即使你改变了一个功能,也有可能破坏了耦合功能,这需要进行另一轮测试,以避免在生产环境中出现任何意外。

2.5 依赖反转原则

不要要求依赖性,它将由框架提供给您。这在 Spring 框架中得到了很好的实现,Spring 框架是编写实用应用程序的最流行的 Java 框架之一。

这个设计原则的美妙之处在于,通过 DI 框架注入的任何类都很容易用模拟对象进行测试,并且更容易维护,因为对象创建代码集中在框架中,而客户端代码并没有被这些代码凌乱地丢弃。

有多种方法可以实现依赖注入/代理,比如使用像 AspectJ 这样的 AOP (Aspect Oriented Programming)框架所做的字节码插装,或者使用像 Spring 中使用的代理。

2.6 喜欢复合胜过继承

在 OOP 中,有两种重用已经编写的代码的通用方法,继承和复合,两者都有自己的优点和缺点,但是,一般来说,如果可能的话,您应该总是倾向于复合而不是继承。

组合允许在运行时通过设置属性和使用接口组合一个类来改变类的行为,我们使用多态性提供了灵活性,可以在任何时候用更好的实现来替换。

2.7 里式替换原则

根据里式替换原则的说法,子类型必须是超类型可替换的,我的意思是使用超类型的方法或函数必须能够毫无问题地处理子类的对象。

LSP 与单一责任原则和接口隔离原则原则密切相关。

如果一个类有更多的功能,那么子类可能不支持某些功能,并且违反 LSP。

为了遵循 LSP SOLID 设计原则,派生类或子类必须增强功能,而不是减少功能。LSP 代表 SOLID 缩写上的“ l”。

违反里式替换原则的最著名一个例子就是java.sql.Date 。因为java.sql.Date 继承了java.util.Date ,但是,使用java.sql.Date与时间相关的方法,都会抛出java.util.NotSupportedException 异常。

2.8 接口隔离原则

接口隔离原则指出,如果客户端不使用某个接口,那么它就不应该实现该接口。

这通常发生在一个接口包含多个功能,而客户机只需要一个功能而不需要其他功能时。

毫无疑问,接口设计是一项棘手的工作,因为一旦发布了接口,就无法在不破坏所有实现的情况下更改它。当然,java8的默认或者防御方法特性确实提供了一种界面演进的方式,但并不是所有的编程语言都支持这些特性。

2.9 为接口编程而不是实现

程序员应该始终为接口编程,而不是为实现编程,这将导致灵活的代码,可以与任何新的接口实现一起工作。

具体来说,你应该对变量使用接口类型,方法的返回类型,或者 Java 中方法的参数类型,比如使用 SuperClass 类型来存储对象而不是使用 SubClass。

比如,可以使用:

List numbers= getNumbers();

而不是:

ArrayList numbers = getNumbers();

2.10 授权原则

这是很有用的设计原则,也遵循职责分离逻辑。也就是说,不要自己做所有的事情,把它委派给和它相关的类。

委托设计原则的一个经典例子是 Java 中的 equals ()和 hashCode ()方法。

为了比较两个对象是否相等,我们要求类本身进行比较,而不是让 Client 类进行检查。

这种设计原则的主要好处是没有代码的重复,并且非常容易修改行为。事件委托是此原则的另一个示例,其中将事件委托给处理程序进行处理。

3 总结

所有这些面向对象设计原则都可以帮助您编写灵活和更好的代码,实现高内聚性和低耦合性。

理论是第一步,最重要的是培养出应用这些设计原则的能力。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot详细列举常用注解的说明
下一篇:mybatis中的if test判断入参的值问题
相关文章

 发表评论

暂时没有评论,来抢沙发吧~