当前位置: 首页 > 编程日记 > 正文

OOP 面向对象 七大原则 (一)

OOP 面向对象   七大原则 (一)

  大家众所周知,面向对象有三大特征继承封装多态的同时,还具有这七大原则,三大特征上一篇已经详细说明,这一篇就为大家详解一下七大原则: 单一职责原则,开闭原则,里氏替换原则,依赖倒置原则,接口隔离原则,迪米特法则,组合聚合复用原则

  单一职责原则:一个类只负责一个领域的内容,简而言之就是自己的类负责自己的事情,与别的类互不干涉

  场景案例:女孩子购物

  

/*** 	oop 单一原则实现*  @author gongliying* 	@data 2019-06-10*/aaa(){class People{getAll(){console.log("打车去Dior实体店买口红")console.log("打车去Only实体店买裙子")}}new People().getAll();}

打车去实体店买口红跟打车去实体店买裙子,我虽然写在了同样一个方法里面,但是呢却不能同时进行

解决思路:面向对象单一职责,一个类只做一件事情,互不干涉

aaa(){class People{Dior(content){console.log('打车去Dior实体店买' + content)}Only(content){console.log('打车去Only实体店' + content)}getAll(){this.JD('口红')this.TM('裙子')}}new People().getAll();        //打车去Dior实体店买口红
                                     //打车去Only实体店买裙子
                                        }

这样事情就解决了,一个类方法只做一件事情,我在Dior的方法中只能去买口红,不能去进行买裙子的操作,这就是单一原则

   开闭原则:对修改关闭,对扩展开放

    一个对象(模板,类,方法)只要是在生命周期内,都会发生变化,而开闭原则就是在不修改原有模块的基础上,扩展其功能

    还以口红为例,商场中有一家店面里面之后Dior和CHANEL两个品牌,那么店员介绍的品牌不是Dior就是CHANEL,一般情况下都会这样写

/*** oop 开闭原则实现* @author 宫丽颖* @date 2019-06-13*/achieve(){let  type ='dior' if (type == 'dior') {console.log('这是dior')}else{console.log('这是chanel')}}        
     //这是dior

这样写是没有什么问题的,但是呢,店面中又有新牌子了ysl,这就变成不是dior 不是CHANEL就是ysl了  随之我们的代码就又变成的这样  

/*** oop 开闭原则实现* @author 宫丽颖* @date 2019-06-13*/achieve(){let  type ='chanel' if (type == 'dior') {console.log('这是dior')}else if(type == 'chanel'){console.log('这是chanel')}else{console.log('这是ysl')}
                    //这是chanel},

随着商店店面更新的口红牌子越来越多,需求越来越多的时候,随之意味这样的代码,对原来代码的修改也越来越多,如果一不小心改错的话,可能整段就垮掉,为了解决这样的事件,建议使用开闭原则,对修改关闭,对扩展开放

/*** oop 开闭原则实现* @author 宫丽颖* @date 2019-06-13*/achieve() {let  type = 'ysl'if (type == 'dior') return this.dior.dior();if (type == 'chanel') return this.chanel.chanel();if (type == 'ysl') return this.ysl.ysl();},dior : {dior() {alert('这是dior')}},chanel : {chanel() {alert('这是chanel')}},ysl : {ysl() {alert('这是ysl')}}           //结果为弹出  这是ysl

这样增加需求的时候直接在data里面定义一个就好了,再多的需求也不怕不怕啦~~~

  里氏替换原则:父类能出现的地方,可以用子类代替,子类拥有父类的所有属性和方法,通俗来说子类拥有父类的功能,可以拓展父类的功能,但是不能修改父类的功能

  口红为例?

/*** oop 里氏替换原则实现* @author 宫丽颖* @date 2019-06-13*/achieve() {class Kouhong{constructor(e){this.name=e.namethis.price=e.price}look(){console.log(this.name,'的口红,一共',this.price,'元')}}//子类class Dior extends Kouhong{look(){console.log('这是',this.name,'的口红,一共',this.price)}}var kouhong = new Kouhong({name:"砖红色",price:300})var dior =new Dior({name:"脏橘色",peice:280})kouhong.look()   //砖红色 的口红,一共 300 元dior.look()      //这是 大红色 的口红,一共 280},

这样写的话,你会发现子类直接覆盖了父类的内容,修改了父类的功能,虽然代码上没什么问题,但是对于以后的优化有着很大的影响,也违背了里氏替换原则,里氏替换原则要求拥有父类的所有方法,可以扩展父类的方法,但是不能修改,我用历史替换比较一下

/*** oop 里氏替换原则实现* @author 宫丽颖* @date 2019-06-13*/achieve() {class Kouhong{constructor(e){this.name=e.namethis.price=e.price}look(){console.log(this.name,'的口红,一共',this.price,'元')}saw(){console.log('口红很贵哦的!!')}}//子类class Dior extends Kouhong{look(){console.log('这是',this.name,'的口红,一共',this.price)}}class CHANEL extends Kouhong{see(){console.log('这是',this.name,'的口红,一共',this.price,'元')}so(){console.log('因为那么贵所以才买不起嘛!!!!')}}var kouhong = new Kouhong({name:"砖红色",price:300})var dior =new Dior({name:"脏橘色",price:280})var chanel = new CHANEL({name:"豆沙色",price:320})kouhong.look()      //砖红色 的口红,一共 300 元            父类本身dior.look()         //这是 脏橘色 的口红,一共 280          子类1继承父类将父类方法覆盖chanel.look()       //豆沙色 的口红,一共 320 元       子类2继承父类显示父类方法chanel.see()        //这是 豆沙色 的口红,一共 320 元     子类2在继承父类上扩展自己的方法chanel.saw()        //口红很贵哦的!!             子类2继承父类另一个方法    子类继承了父类的所有方法chanel.so()         //因为那么贵所以才买不起嘛!!!!        子类2扩展自己的另一个方法},

由此可见,子类1在继承父类的时候将父类覆盖,但是子类2在继承父类的时候继承了父类的所有方法并扩展了自己的方法,这就是里氏替换原则

依赖倒置原则:程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。(节选自百度百科)

emmmm,很官方的一句话 ,我用白话解释一下,就是说高层的模块不要依赖于低层的模块,不要靠比自己层级低的模块,高层低层应该同时依靠抽象,而抽象不应该依赖于细节而是应该细节依赖抽象 ,要是还没有懂的话,画张图把,当然还是口红为例了

这样看是不是看懂了呢 这个人就是高层,左图就是在说 高层依赖低层,如果这个高层抹口红就只能抹口红,不能在抹其他的 ,要是想在抹别的,就要再加方法,太啰嗦

而右图就是在说明定义了一个抽象类抹,如果没有口红了还可以抹眼影啊,粉底之类的,人与眼影之间依赖抹这个抽象类来实现,这个抹眼影 这个细节依赖于抽象抹这个类,而这个高层人也可以创建不同的高层话不多说,代码附上

                    class cosmetics{daub(){console.log('抹了什么?')}}class kouhong extends cosmetics{go(){return "抹了口红"}}class yanying extends cosmetics{go(){return "抹了眼影"}}class fendi extends cosmetics{go(){return "抹了粉底"}}class people {constructor(name) {this.name = name}gotoEat(mo) {console.log(this.name, mo.go())}}kouhong = new kouhongyanying = new yanyingfendi = new fendigong = new people('宫')liying = new people('丽颖')gong.gotoEat(kouhong)      //宫 抹了口红gong.gotoEat(yanying)      //宫 抹了眼影gong.gotoEat(fendi)        //宫 抹了粉底liying.gotoEat(fendi)      //丽颖 抹了粉底

结果我不仅通过抹的抽象类,创建了不同的细节,还创建不同的高层,不同的人通过抹的类创建了不同的细节,他们之间是不会相互影响的,这就是依赖倒置原则。

转载于:https://www.cnblogs.com/gongliying/p/11000060.html

相关文章:

NodeJS 使用redis实现定时执行方法

NodeJS 使用redis实现定时执行任务 文章目录NodeJS 使用redis实现定时执行任务场景使用Redis定时器解决Redis定时器Redis发布订阅操作nodejs代码主意事项场景 用户下订单后,需要在5分钟内完成支付,否则订单关闭;用户在完成订单后&#xff0c…

Javascript获取页面、屏幕尺寸大小参数

Javascript获取获取屏幕、浏览器窗口 ,浏览器,网页高度、宽度的大小网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWidth (包括边线的宽)…

linux 进入单用户模式修改root密码

Redhat系统Root密码的修改 一台双系统的机器,忘记redhat 的root密码了。 一。相关方法如下:1. 开机在出现grub画面,按e键 2. 用上下键选中第二项(类似于kernel /boot/vmlinuz-2.4.18-14 ro rootLABEL/) 然后按e键编辑 3. 空格single结果如下&#…

精通Groovy

https://www.ibm.com/developerworks/cn/education/java/j-groovy/j-groovy.html https://juejin.im/entry/59bf6376f265da066b394310 groovy for eclipse插件wiki https://github.com/groovy/groovy-eclipse/wiki 转载于:https://www.cnblogs.com/hihtml5/p/8434040.html

C和指针-函数

一个函数的通常形式: type function_name(参数) { 代码块; } 在参数里面:变量和类型声明 写空函数备用! k&R C中,参数声明不一样 函数声明: 函数原型先写 缺省认定:声明函数原型…

网页生成pdf文件

在此介绍 两种方法。 一个是asppdf;一个是abcpdf。 都是收费的组件。需要注册码,但是也有破解的和trial的。 asppdf:http://www.persits.com/asppdf.exe (可以在http://www.asppdf.com/download.html输入一个email获取一个序列号&#xff…

vue中把props中的值赋值给data

父组件 <messageForm createMsgCallback"addCreateMsg" :name"sendForm.name"></messageForm> 子组件 props:{name:{type:String} }, computed: {computedName(){return this.name}},watch:{name:function(val) {console.log(val);this.sen…

Webservices,remoting,WCF比较一下

remoting用的少&#xff0c;再仔细琢磨

eclipse常用插件介绍

1. 测试覆盖率工具&#xff1a;EclEmma https://www.cnblogs.com/Ming8006/p/5811425.html 2. 单元测试系列&#xff1a;如何使用JUnitJaCoCoEclEmma完成单元测试 https://www.cnblogs.com/zishi/p/6726664.html转载于:https://www.cnblogs.com/yelongsan/p/8436281.html

SQL Server基础操作(此随笔仅作为本人学习进度记录七 !--存储过程)

存储过程存储过程分为系统存储过程和自定义存储过程存储过程通过将处理数据的程序从客户端应用程序移动到服务器,存储过程是放在服务器上的&#xff0c;通过客户端下达指令调用存储过程的时候&#xff0c;这个过程是在服务器上发生的&#xff0c;自然就不会占用网络的带宽就会降…

JS基础类型和引用类型

JS基础类型和引用类型脑图

(转)WinForm控件使用文章收藏整理完成

http://home.cnblogs.com/group/topic/29829.html 对C# WinForm开发系列收集的控件使用方面进行整理, 加入了一些文章, 不断补充充实, 完善这方面. 基础 - 常用控件 C# WinForm开发系列 - CheckBox/Button/Label/ProgressBar WinForm下CheckedListBox的数据绑定 Winform 下…

Hdu 2795

Billboard 题型&#xff1a;线段树 描述&#xff1a;板子h*w上贴1*w0的广告&#xff0c;从左上角贴起&#xff0c;询问广告所在的row。 思路&#xff1a;将h分段&#xff0c;结构中增加w域&#xff0c;保存区间[a,b]所以行剩余可贴的最大量。 代码 //1828MS 6340K#include <…

认识一下Kotlin语言,Android平台的Swift

今天在CSDN首页偶然看到一个贴子JetBrains正式公布Kotlin 1.0&#xff1a;JVM和Android上更好用的语言 看完后&#xff0c;感觉Kotlin语法非常简洁&#xff0c;有一系列动态语言的特点&#xff0c;Lambda表达式。高阶函数。闭包&#xff0c;甚至有静态语言的类型检查&#xff…

php开发面试题---php面向对象详解(对象的主要三个特性)

php开发面试题---php面向对象详解&#xff08;对象的主要三个特性&#xff09; 一、总结 一句话总结&#xff1a; 对象的行为&#xff1a;可以对 对象施加那些操作&#xff0c;开灯&#xff0c;关灯就是行为。 对象的形态&#xff1a;当施加那些方法是对象如何响应&#xff0c;…

端口01 - 零基础入门学习汇编语言67

第十四章&#xff1a;端口01 让编程改变世界 Change the world by program 引言 CPU可以直接读写3 个地方的数据 &#xff08;1&#xff09;CPU 内部的寄存器&#xff1b; &#xff08;2&#xff09;内存单元&#xff1b; &#xff08;3&#xff09;端口。 这一章&#xff0c…

基于SSM实现二手交易系统

1、使用技术 SpringSpring MVCMybatisMysqlhtmljscss等 2、功能 用户注册用户登录物品推荐物品分类物品搜索物品发布物品详情购买商品我的主页等等 3、效果 4、视频介绍

RemoteFX原理简介

这几天&#xff0c;Windows 7 SP1的BETA版公开测试了&#xff0c;里面有一个功能&#xff0c;RemoteFX&#xff0c;算是softice比较期待的一个功能&#xff0c;总算是揭开了她的神秘面纱&#xff0c;横空出世&#xff0c;来到你身边。它的发布&#xff0c;对于微软桌面虚拟化解…

bzoj1079: [SCOI2008]着色方案(DP)

1079: [SCOI2008]着色方案 题目&#xff1a;传送门 题解&#xff1a; DP刚神多年前讲过的一道神题。 二话不说&#xff0c;上来就是一个六维数组&#xff1a;F[i][a][b][c][d][e]//表示上一次涂的颜色是还剩下i次可用的&#xff0c;a~e表示不同次数的颜色种数。 次数一样的颜色…

dedecms部分文章出现读取附加信息出错的解决办法

问题&#xff1a; 估计是新版本开发的时候&#xff0c;没有考虑旧版&#xff0c;文章内容为空的新闻&#xff0c;新版不在允许文章内容为空的新闻&#xff0c;这样旧版的内容为空的新闻升级后将无法再编辑。 解决&#xff1a;你可以对如下文件进行如下修改&#xff1a;article_…

程序员的周末:纯野的一天

牵强的标题自己写上这个标题都觉得挺牵强的。首先&#xff0c;我算不上是一个纯粹意义上的程序员了。虽然上了一个多月的班&#xff0c;但对于这份职业到底做什么我都还不是特别的清楚。每天做着一些类似文秘的工作&#xff0c;又类似技术支持的工作&#xff0c;还有点类似程序…

postgresql 分组查询第一条数据

SELECT * FROM ( SELECT ROW_NUMBER() OVER (partition BY k.word ORDER BY k."updatedAt" desc) rowId,* from keywords as k ) t WHERE rowId1

关于工作和生活

一、关于工作与生活 我有个有趣的观察&#xff0c;外企公司多的是25-35岁的白领&#xff0c;40岁以上的员工很少&#xff0c;二三十岁的外企员工是意气风发的&#xff0c;但外企公司40岁附近的经理人是很尴尬的。我见过的40岁附近的外企经理人大多在一直跳槽&#xff0c;最后大…

JVM GC 垃圾回收(二)之 判断那些可回收,怎么回收

1、哪些对象可回收&#xff1f; 可行性分析算法 通过一系列GC Roots&#xff08;1&#xff09;作为起始点&#xff0c;其到对象之间的引用&#xff08;2&#xff09;称为引用链&#xff0c;当对象到GC Roots之间不存在引用链相连&#xff0c; 则此对象是不可用的。如下&#xf…

nginx+lua实现上传文件到OSS

目录 技术点 openResty 下载安装 示例 oss.lua 文件 测试代码 text.lua nginx 配置 技术点 openResty OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台&#xff0c;其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并…

使用CEfSharp之旅(7)CEFSharp 拦截 http 请求 websocket 内容

使用CEfSharp之旅&#xff08;7&#xff09;CEFSharp 拦截 http 请求 websocket 内容 原文:使用CEfSharp之旅&#xff08;7&#xff09;CEFSharp 拦截 http 请求 websocket 内容版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。可点击关注博主 &…

sqlserver查询一个表的字段信息

select count(*) from syscolumns where idobject_id(表名) 转载于:https://www.cnblogs.com/dongpo888/archive/2011/05/11/2043370.html

ASP.NET无刷新客户端回调

首先说一下&#xff1a;Page.ClientScript 用于管理脚本、注册脚本和向页添加脚本。 返回结果:一个 System.Web.UI.ClientScriptManager 对象。 ClientScriptManager对象 是一些 在 Web 应用程序中定义用于管理客户端脚本的方法&#xff0c;其中有一个方法重载&#xff1a;stri…

common lisp里的几个操作符

setf 赋值操作符&#xff0c;定义一个全局变量。返回值是最后一个赋值的结果。 let 局部变量操作符。let表达式有两部分组成。第一部分是任意多的变量赋值&#xff0c;他们被包裹在一个()中&#xff0c;第二部分是任意数量的表示式作为 let 的函数体。let 表达式的返回值为 最…

敏捷宣言遵循的十二条原则

敏捷宣言遵循的十二条原则Twelve Principles behind the Agile Manifesto 我们遵循以下原则&#xff1a; We follow these principles: 我们最重要的目标&#xff0c;是通过持续不断地及早交付有价值的软件使客户满意。Our highest priority is to satisfy the customer throug…