面向对象设计7大原则

概述

熟练掌握和应用面向对象设计(Object Oriented Design,OOD)7大原则,是初/中级Java工程师向高级/资深工程师进阶的一个必备技能,它可以大大提升程序的可复用性和可维护性,也是重构代码的一大利器。7大设计原则包括开闭原则、里氏替换原则、依赖倒转原则、单一职责原则、接口隔离原则、组合/聚合复用原则、迪米特法则。

1.开闭原则

面向对象可复用设计原则中最基础的原则便是开闭原则(Open-Closed Principle,OCP)。开闭原则指的是在设计一个对象(类、模块、函数)时,应遵循或做到对扩展开放、对修改关闭,其核心思想是面向接口/抽象进行编程。比如第四方支付平台,集成微信支付服务时,遵循开闭原则的话,正常的做法就是先抽象设计一个支付接口,然后微信支付类实现该支付接口。以后平台集成更多如支付宝、华为、苹果等支付服务时,只需要扩展一个对应支付方式的支付类即可,这样既扩展了新的支付服务,同时避免了修改现有的支付接口以及微信支付类,最大限度保证了新代码不会影响现有的业务代码。这就是对扩展(新对象)开放,对修改(现有对象)关闭。

2.里氏替换原则

里氏替换原则(Liskov Substitution Principle,LSP)要求设计一个对象时,代码中任何父类对象可以出现的地方,子类都可以出现,即可以使用子类来代替父类。实现开闭原则的核心思想是面向接口/抽象进行编程,其关键步骤是抽象化,而父类和子类的继承关系就是抽象化的具体体现,所以里氏替换原则是对实现抽象化的具体步骤的规范,它是对开闭原则的补充。比如教学平台中新增加了学生用户Student,和教师用户Teacher一样进入个人中心,都需要登录,在设计或重构用户登录服务类时,抽象的用户User类作为教师Teacher和学生Student的父类,此时需要遵循出现用户User的地方,都可以使用新扩展的学生Student代替,当然也必须也可以使用教师Teacher代替,这样设计出来的User类,对用户登录服务类来说,后续扩展更多的用户User的子类比如家长、辅导员时,可以保证符合开闭原则。

3.依赖倒转原则

依赖倒转原则(Dependency Inversion Principle,DIP)指程序中要依赖抽象(接口/抽象类)而不是具体的实现(实现类)进行编程,即面向接口/抽象进行编程,这样可以最大程度降低模块之间的耦合。比如订单服务中,会调用(依赖)支付服务以完成订单的支付。此时的订单服务实现类代码中,声明或持有的应该是一个支付服务PayService接口,而不是具体实现类比如Alipay或WeChatPay,所有需要用到支付服务的地方,调用的都是PayService接口变量,即代码中都是接口,等到在运行时才实例化或注入具体的实现类,编写代码时不需要关心具体实现类,也就是面向接口/抽象编程。这样,在应用程序扩展或集成新的支付服务时,原来的订单服务代码可以不需要进行修改任何代码,这样也就符合了开闭原则。

4.单一职责原则

单一职责原则(Single Function Principle,SFP)又称单一功能原则,它规范设计一个类应只实现单一或独立的职责即业务功能。职责分明的设计,可以提高程序的可维护性。如果多个独立的业务功能设计在同一类中,当一个或多个业务功能扩展或变动需要修改代码时,可能会带来冲突问题,降低可维护性。比如订单服务中,又包含了用户服务,重构用户服务的代码时,相当于重构订单服务的代码,这是不合理的,容易造成混淆。

5.接口隔离原则

接口隔离原则(Inteface Segregation Principle,ISP)指设计时不同的功能应定义在不同的接口上,避免实现类依赖不需要的接口,换个角度理解就是一个类应该依赖尽量少的接口或实现类,减少程序的冗余性和复杂性。

6.组合/聚合复用原则

组合/聚合复用原则(Composition/Aggregation Principle,CARP)也叫做合成复用原则(Composition Reuse Principle,CRP),它指在一个新的对象中引入/注入现有的对象以达到功能复用和扩展的目的。简单讲就是尽量使用组合/聚合而不要使用继承

7.迪米特法则

迪米特法则(Low of Demeter,LoD)指设计一个对象时,尽可能少的与其它对象发生相互作用,即尽可能少的了解或依赖其它对象,降低耦合度。广义的迪米特法则,在类设计的具体操作上,主要通过以下三点来体现

  • 优先考虑将一个类设置为final不变类
  • 尽量降低一个类及其成员变量的访问权限
  • 谨慎使用序列化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/576195.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

discuz x2.5 DIY模块模板语法详解

基本语句 [loop]...[/loop]标签来循环显示模块中的数据;如果要在模板中多处循环可以使用[loop1]...[/loop1]的方式扩展(只能扩展1-9个) [orderN]...[/order]标签来替代默认loop中的第N个位置数据的展示,你可以使用[order1N]...[/o…

get请求可以传body吗_GET 和 POST 的区别?

同样还是面试被问到的问题,经过这两天的复盘,发现之前对其的了解只是冰山一角,这两天也学到了不少新的知识,不得不说面试的确能帮我们弥补一些不足。本文将从基本概念、两者之间的区别以及几个常见问题来进行介绍,首先…

WINCE 下配置 QT 的方法

1. 推荐安装环境 Windows XP SP3 VS2005(SP1)2. 载Qt for WinCE(eg. qt-everywhere-opensource-src-4.8.3.zip)3. 解压到C:\Qt\4.8.3WinCE4. 安装WinCE的SDK(如RNx,WinCE5.0的)5. 将C:\Qt\4.8.3WinCE\bin加到环境变量Path中6. 修改代码或配置(注1),否则…

AQS基本原理

什么是AQS? AQS即AbstractQueuedSynchronizer,是一个用于构建锁和同步器的框架。它能降低构建锁和同步器的工作量,还可以避免处理多个位置上发生的竞争问题。在基于AQS构建的同步器中,只可能在一个时刻发生阻塞,从而降低上下文切…

C语言 int** 二重指针的理解

#include <stdio.h> #include <stdlib.h>/*&根据值找地址*根据地址找值 */ f(int** q){//传入的是指针的地址 int i 3; printf("子函数 i的地址 %#X\n",&i); // *q 代表的就是p变量 *q &i; //*q指向是p的值 也就是…

ReentrantReadWriteLock源码分析

概述 ReentrantReadWriteLock维护了一对相关的锁&#xff0c;它们分别是共享readLock和独占writeLock。关于共享读锁和排他写锁的概念其实很好理解。所谓共享读锁就是一个线程读的时候&#xff0c;其它线程也可以来读&#xff08;共享&#xff09;&#xff0c;但是不能来写。排…

@Autowired、@Qualifier、@Resource的区别

参考博文&#xff1a; http://www.cnblogs.com/happyyang/articles/3553687.html http://blog.csdn.net/revent/article/details/49203619 http://blog.csdn.net/ad921012/article/details/49679745 spring不但支持自己定义的Autowired注解&#xff0c;还支持几个由JSR-250…

UINavigationViewController的backBarButtonItem设置技巧

之前大家是否疑惑为什么设置了类似这样的代码 UIBarButtonItem *backButton [[UIBarButtonItem alloc] initWithTitle:"返回" …

MySQL行锁和表锁的含义及区别

今天在开发测试时候出现了锁表&#xff0c;原因是因为我在本地开启了事务&#xff0c;代码中打了断点&#xff0c;然后测试同学测试时候出现了锁表&#xff0c;我去排查了问题&#xff0c;然后找到相关的资料了解下&#xff0c; 总结&#xff1a;原因的表没有加索引&#xff0…

Thinking In Design Pattern——Query Object模式

什么是Query Object模式 Query Object的架构设计 Query Object在服务层的应用 测试 Query Object模式 Query Object&#xff1a;可以在领域服务层构造查询然后传给资源库使用&#xff0c;并使用某种查询翻译器将对象查询&#xff08;Query&#xff09;翻译成底层数据库持久化…

linux gcc编译C程序 分享

一个c语言程序从源文件到生成可执行文件&#xff0c;编译器需要共经历4个步骤&#xff1a;1) 预处理&#xff1a;把c文件中预处理命令扫描处理完毕&#xff0c;即对源代码文件中的文件包含(#include)、预编译语句(如宏定义#define等)进行分析&#xff0c;此时生成的文件仍然是可…

java Arrays.copyOfRange使用方法

使用场景&#xff1a;比如当一个文本框输入多个值作为查询条件&#xff0c;这时候当输入的值过多&#xff0c;我们需要最大支持多少个&#xff1f;这时候&#xff0c;输入超出个数的值&#xff0c;就被截取不要 不然后台处理逻辑就要飞前台返回不能查询这样的提示&#xff0c;…

WinForm 中 comboBox控件之数据绑定

http://www.cnblogs.com/peterzb/archive/2009/05/30/1491923.html 下面介绍三种对comboBox绑定的方式&#xff0c;分别是泛型中IList和Dictionary&#xff0c;还有数据集DataTable 一、IList 现在我们直接创建一个List集合&#xff0c;然后绑定 View Code IList<string>…

MySQL常用引擎有MyISAM和InnoDB区别

MySQL常用引擎有MyISAM和InnoDB&#xff0c;而InnoDB是mysql默认的引擎。MyISAM不支持行锁&#xff0c;而InnoDB支持行锁和表锁。 如何加锁&#xff1f; MyISAM在执行查询语句&#xff08;SELECT&#xff09;前&#xff0c;会自动给涉及的所有表加读锁&#xff0c;在执行更新…

java中异常与return

抽时间整理了下java中异常与return&#xff0c;以前这块总是弄混淆&#xff0c;觉得还是写下来慢慢整理比较好。由于水平有限&#xff0c;仅供参考。废话不多说&#xff0c;直接上代码。 下面是两个方法&#xff1a; 1 public static int throwReturn(){2 int ret…

rocketmq 启动mqbroker.cmd闪退

非常奇怪&#xff0c;broker启动闪退&#xff0c;我就摸索了好久&#xff0c;网上各种百度&#xff0c;最后得到正解 将c盘下这个store下的文件全部删除&#xff0c;就可以启动了 猜测是可能mq非正常关闭&#xff0c;导致&#xff0c;具体懂原理的大佬可以来评论区说说

星星计算器

星星计算器&#xff1a; [ 机锋下载 ]第一款&#xff0c;呃&#xff0c;…&#xff0c;自家学习安卓的时候产的&#xff0c;功能和第二款有些类似&#xff08;而且在细节功能方面我也做了很多努力&#xff09;&#xff0c;不过已经十分强大了&#xff0c;并且有自己的创新&…

java基础复习-(run方法和start方法区别)

1&#xff0c;run方法是Runnable接口中定义的&#xff0c;start方法是Thread类定义的。 所有实现Runnable的接口的类都需要重写run方法&#xff0c;run方法是线程默认要执行的方法&#xff0c;是绑定操作系统的&#xff0c;也是线程执行的入口。 start方法是Thread类的默认执行…

Web.py Cookbook 简体中文版 - 如何使用web.background

注意&#xff01;&#xff01; web.backgrounder已转移到web.py 3.X实验版本中&#xff0c;不再是发行版中的一部分。你可以在这里下载&#xff0c;要把它与application.py放置在同一目录下才能正运行。 介绍 web.background和web.backgrounder都是python装饰器&#xff0c;它可…

为什么wait, notify,notifyAll保存在Object类中,而不是Thread类

一个较难回答的 Java 问题&#xff0c; Java 编程语言又不是你设计的&#xff0c;你如何回答这个问题呢&#xff1f; 需要对 Java 编程的常识进行深入了解才行。 这个问题的好在它能反映面试者是否对 wait - notify 机制有没有了解, 以及他相关知识的理解是否明确。就像为什么…