OO设计原则总结

什么是设计原则? 

设计原则是基本的工具,应用这些规则可以使你的代码更加灵活、更容易维护,更容易扩展。

基本原则

oop

 

  • 封装变化Encapsulate what varies.
  • 面向接口编程而非实现 Code to an interface rather than to an implementation.
  • 优先使用组合而非继承 Favor Composition Over Inheritance

SRP: The single responsibility principle 单一职责

系统中的每一个对象都应该只有一个单独的职责,而所有对象所关注的就是自身职责的完成。

Every object in your system should have a single responsibility ,and all the object s services should be focused on carrying out that single responsibility .

 

  1. 每一个职责都是一个设计的变因,需求变化的时候,需求变化反映为类职责的变化。当你系统里面的对象都只有一个变化的原因的时候,你就已经很好的遵循了SRP原则。
  2. 如果一个类承担的职责过多,就等于把这些职责耦合在了一起。一个职责的变化就可能削弱或者抑制这个类其它职责的能力。这种设计会导致脆弱的设计。当变化发生的时候,设计会遭到意想不到的破坏。
  3. SRP 让这个系统更容易管理维护,因为不是所有的问题都搅在一起。
  4. 内聚Cohesion 其实是SRP原则的另外一个名字.你写了高内聚的软件其实就是说你很好的应用了SRP原则。
  5. 怎么判断一个职责是不是一个对象的呢?你试着让这个对象自己来完成这个职责,比如:“书自己阅读内容”,阅读的职责显然不是书自己的。
  6. 仅当变化发生时,变化的轴线才具有实际的意义,如果没有征兆,那么应用SRP或者任何其它的原则都是不明智的。

DRY : Don't repeat yourself Principle

通过抽取公共部分放置在一个地方避免代码重复.

Avoid duplicate code by abstracting out things that are common and placing those thing in a single location .

 

  1. DRY 很简单,但却是确保我们代码容易维护和复用的关键。
  2. 你尽力避免重复代码候实际上在做一件什么事情呢?是在确保每一个需求和功能在你的系统中只实现一次,否则就存在浪费!系统用例不存在交集,所以我们的代码更不应该重复,从这个角度看DRY可就不只是在说代码了。
  3. DRY 关注的是系统内的信息和行为都放在一个单一的,明显的位置。就像你可以猜到正则表达式在.net中的位置一样,因为合理所以可以猜到。
  4. DRY 原则:如何对系统职能进行良好的分割!职责清晰的界限一定程度上保证了代码的单一性。

OCP : Open-Close Principle开闭原则

类应该对修改关闭,对扩展打开;

Classes should be open for extension ,and closed for modification .

 

  1. OCP 关注的是灵活性,改动是通过增加代码进行的,而不是改动现有的代码;
  2. OCP的应用限定在可能会发生的变化上,通过创建抽象来隔离以后发生的同类变化
  3. OCP原则传递出来这样一个思想:一旦你写出来了可以工作的代码,就要努力保证这段代码一直可以工作。这可以说是一个底线。稍微提高一点要求,一旦我们的代码质量到了一个水平,我们要尽最大努力保证代码质量不回退。这样的要求使我们面对一个问题的时候不会使用凑活的方法来解决,或者说是放任自流的方式来解决一个问题;比如代码添加了无数对特定数据的处理,特化的代码越来越多,代码意图开始含混不清,开始退化。
  4. OCP 背后的机制:封装和抽象;封闭是建立在抽象基础上的,使用抽象获得显示的封闭;继承是OCP最简单的例子。除了子类化和方法重载我们还有一些更优雅的方法来实现比如组合;

怎样在不改变源代码(关闭修改)的情况下更改它的行为呢?答案就是抽象,OCP背后的机制就是抽象和多态

  1. 没有一个可以适应所有情况的贴切的模型!一定会有变化,不可能完全封闭.对程序中的每一个部分都肆意的抽象不是一个好主意,正确的做法是开发人员仅仅对频繁变化的部分做出抽象。拒绝不成熟的抽象和抽象本身一样重要。
  2. OCPOOD很多说法的核心,如果这个原则有效应用,我们就可以获更强的可维护性 可重用 灵活性 健壮性 LSPOCP成为可能的主要原则之一

LSP: The Liskov substitution principle

子类必须能够替换基类。

Subtypes must be substitutable for their base types.

 

  1. LSP关注的是怎样良好的使用继承.
  2. 必须要清楚是使用一个Method还是要扩展它,但是绝对不是改变它。
  3. LSP清晰的指出,OODIS-A关系是就行为方式而言,行为方式是可以进行合理假设的,是客户程序所依赖的。
  4. LSP让我们得出一个重要的结论:一个模型如果孤立的看,并不具有真正意义的有效性。模型的有效性只能通过它的客户程序来表现。必须根据设计的使用者做出的合理假设来审视它。而假设是难以预测的,直到设计臭味出现的时候才处理它们。
  5. 对于LSP的违反也潜在的违反了OCP

DIP:依赖倒置原则

高层模块不应该依赖于底层模块 二者都应该依赖于抽象

抽象不应该依赖于细节 细节应该依赖于抽象

  1. 什么是高层模块?高层模块包含了应用程序中重要的策略选择和业务模型。这些高层模块使其所在的应用程序区别于其它。
  2. 如果高层模块依赖于底层模块,那么在不同的上下文中重用高层模块就会变得十分困难。然而,如果高层模块独立于底层模块,那么高层模块就可以非常容易的被重用。该原则就是框架设计的核心原则。
  3. 这里的倒置不仅仅是依赖关系的倒置也是接口所有权的倒置。应用了DIP我们会发现往往是客户拥有抽象的接口,而服务者从这些抽象接口派生。
  4. 这就是著名的Hollywood原则:"Don't call us we'll call you."底层模块实现了在高层模块声明并被高层模块调用的接口。
  5. 通过倒置我们创建了更灵活 更持久更容易改变的结构
  6. DIP的简单的启发规则:依赖于抽象;这是一个简单的陈述,该规则建议不应该依赖于具体的类,也就是说程序汇总所有的依赖都应该种植于抽象类或者接口。
  7. 如果一个类很稳定,那么依赖于它不会造成伤害。然而我们自己的具体类大多是不稳定的,通过把他们隐藏在抽象接口后面可以隔离不稳定性。
  8. 依赖倒置可以应用于任何存在一个类向另一个类发送消息的地方
  9. 依赖倒置原则是实现许多面向对象技术多宣称的好处的基本底层机制,是面向对象的标志所在。

ISP:接口隔离原则

不应该强迫客户程序依赖它们不需要的使用的方法。

 

  1. 接口不是高内聚的,一个接口可以分成N组方法,那么这个接口就需要使用ISP处理一下。
  2. 接口的划分是由使用它的客户程序决定的,客户程序是分离的接口也应该是分离的。
  3. 一个接口中包含太多行为时候,导致它们的客户程序之间产生不正常的依赖关系,我们要做的就是分离接口,实现解耦。
  4. 应用了ISP之后,客户程序看到的是多个内聚的接口。

 

转载于:https://www.cnblogs.com/vincent_shi/archive/2009/11/16/1603724.html

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

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

相关文章

kubectl get node运行时出现:Unable to connect to the server: x509: certificate signed by unknown authority

kubectl get nodes运行时出现:Unable to connect to the server: x509: certificate signed by unknown authority原因:我们在运行kubeadm reset时,没有删除原先的$HOME/.kube文件导致新建的kubelet报错。实际上在kubeadm reset执行后&#x…

设置在VS2005的IDE中迅速打开xaml文件

设置在VS2005的IDE中迅速打开xaml文件 本人使用普通台式计算机做WPF开发,每次打开xaml的时候,都需要等半天,那叫一个慢呀,实在受不了。即使是一个新建的xaml文件,打开都慢。怎样解决VS2005的IDE中打开xaml文件慢的问题…

Git分支(远程)

1、远程分支的表示形式:远程仓库名称/分支名,如:origin/master;2、一次Git克隆会建立你自己的本地分支:master和远程分支:origin/master,它们都指向origin/master分支的最后一次提交&#xff1b…

kubeadm join时出现错误:[ERROR Port-10250]: Port 10250 is in use [ERROR FileAvailable--etc-kubernetes-pki

kubeadm join时出现错误:[ERROR Port-10250]: Port 10250 is in use;[ERROR FileAvailable--etc-kubernetes-pki-ca.crt]: /etc/kubernetes/pki/ca.crt already exists初次使用kubeadm构建k8s集群,所以对子节点加入管理节点的过程认识不足&am…

cs文件中控制页面table的大小、title名称(.aspx)

1. title 控制HTML:<title id"mytitle" runat"server"></title> CS: protected System.Web.UI.HtmlControls.HtmlGenericControl mytitle;mytitle.InnerText "Hello World"; 2. 页面table 控制HTML:<TABLE idTabl…

TCP/IP详解学习笔记(2)-数据链路层

TCP/IP详解学习笔记(2)-数据链路层数据链路层有三个目的&#xff1a; 为IP模块发送和 接收IP数据报。 为ARP模块发送ARP请求和接收ARP应答。 为RARP发送RARP请 求和接收RARP应答ip大家都听说过。至于ARP和RARP&#xff0c;ARP叫做地址解析协议…

vi 按了ctrl+s怎么办

【转载】 手香的不得了 http://blog.sina.com.cn/lx987654321123456789 今天白痴了一把&#xff0c;用vi的时候&#xff0c;习惯性的用了ctrl-s&#xff0c;一下子僵掉了网上一查&#xff0c; 原来&#xff1a; CTRLS表示停止向终端停止输出; CTRLQ恢复向终端输出流. 严重bs自己…

POJ 1966 Cable TV Network (最大流最小割)

$ POJ~1966~Cable~TV~Network $ $ solution: $ 第一眼可能让人很难下手&#xff0c;但本就是冲着网络流来的&#xff0c;所以我们直接一点。这道题我们要让这个联通图断开&#xff0c;那么势必会有两个点变得不连通&#xff0c;这道题的数据范围很小&#xff0c;所以我们试着暴…

harbor安装时出现ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug in

harbor安装时出现ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value current val…

几大开源项目

7-Zip 4.32&#xff1a;文件压缩工具&#xff0c;可与Windows资源管理器集成 A Note 4.2.1&#xff1a;可在Windows桌面放置便笺&#xff0c;并可提供闹钟提醒功能 Abakt 0.9&#xff1a;能够以压缩方式对文档进行备份 Abiword 2.27&#xff1a;Windows写字板的替代程序&…

如何恢复Linux下被误删除的文件以及如何防止文件被删除

【卸载被误删除文件所在的分区&#xff0c;或以只读方式mount】当你发现你误删除了文件后&#xff0c;要做的第一件事情是马上卸载被误删除文件所在分区&#xff0c;或者以只读的方式来挂在该防区。如果误删除的是根分区&#xff0c;最好直接断电&#xff0c;进入单用户模式&am…

配置msdtc

配置msdtc需要分别配置数据库服务器和开发机&#xff0c;因为只有两个机器都配置正确了&#xff0c;分布式事务才不会报乌七八糟的错误。如果数据库服务器和开发机是同一台机器&#xff0c;那就不用看本文了&#xff0c;因为不存在分布式事务的问题。 数据库服务器和开发机中配…

GooglePR说明

内容摘要&#xff1a;无论是对普通网络冲浪者还是网站管理员来说&#xff0c;Google都是目前世界范围内最受欢迎的搜索引擎。它每天处理的搜索请求高达1.5亿次&#xff0c;几乎占全球所有搜索量的1/3。网络冲浪者对Google情有独钟&#xff0c;是由于Google所提供的快速搜索速度…

什么是套接字?Socket基本介绍

什么是套接字&#xff1f;Socket基本介绍一、什么是套接字&#xff1f;二、套接字特性三、套接字缓冲区一、什么是套接字&#xff1f; 套接字是一种通信机制&#xff08;通信的两方的一种约定&#xff09;&#xff0c;socket屏蔽了各个协议的通信细节&#xff0c;提供了tcp/ip…

[ZJOI2007] 时态同步

题面 显然的一个建模是&#xff0c;每个叶子对应一个权值&#xff0c;代表比最晚的叶子早了多久&#xff0c;然后我们要做的就是给每条边赋上值&#xff0c;使得每个叶子到根的路径上的所有边权值和等于叶子的权值。 我们贪心的想一想&#xff0c;必然是离根越近的边赋值多的情…

dsad

应该来说这是两两配对的时间 mouseenter和mouseleave是只对选中的元素的生效 mouseover和mouseout是只对选中的元素及其子元素生效 <iframe width"100%" height"300" src"//jsfiddle.net/xiadd/4hno1wgf/embedded/" allowfullscreen"all…

ARM-Button-Driver-硬件图

1、实物图 2、CPU接线图 3、实际硬件接图 转载于:https://www.cnblogs.com/xmphoenix/archive/2011/11/02/2233519.html

动态创建ActiveRecord条件的查询 MyQuery

在CMS中。我们经常会按一定的条件来进行搜索。如果用户没有选择这个条件的话&#xff0c;我们就不能将它放到sql中也许我们可以用自己拼装sql语句的方式很好的实现这种查询。然后再前面过滤掉一些危险的参数但是参数过滤有一个不好的地方是。会把一些信息给过滤掉了。在castle …

kubenetes中port、targetPort、nodePort、containerPort的区别与联系

kubenetes中port、targetPort、nodePort、containerPort的区别与联系首先给出一张kubenetes结构图&#xff1a;containerPort containerPort是在pod控制器中定义的、pod中的容器需要暴露的端口。Pod中容器暴露的端口 targetPort targetPort是pod上的端口&#xff0c;从port/nod…

Entity Framework中使用IEnumerableT、IQueryableT及IListT的区别

1. IEnumerable<T> IEnumerable<T> &#xff1a;对于在内存中集合上运行的方法&#xff0c;返回的可枚举对象将捕获传递到方法的参数。在枚举该对象时&#xff0c;将使用查询运算符的逻辑&#xff0c;并返回查询结果。 IEnumerable<T>在.Net2.0引入。 IEnumb…