设计模式之美
王争
前Google工程师,《数据结构与算法之美》专栏作者
立即订阅
17458 人已学习
课程目录
已更新 20 讲 / 共 100 讲
0/6登录后,你可以任选6讲全文学习。
开篇词 (1讲)
开篇词 | 一对一的设计与编码集训,让你告别没有成长的烂代码!
免费
设计模式学习导读 (3讲)
01 | 为什么说每个程序员都要尽早地学习并掌握设计模式相关知识?
02 | 从哪些维度评判代码质量的好坏?如何具备写出高质量代码的能力?
03 | 面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?
设计原则与思想:面向对象 (11讲)
04 | 理论一:当谈论面向对象的时候,我们到底在谈论什么?
05 | 理论二:封装、抽象、继承、多态分别可以解决哪些编程问题?
06 | 理论三:面向对象相比面向过程有哪些优势?面向过程真的过时了吗?
07 | 理论四:哪些代码设计看似是面向对象,实际是面向过程的?
08 | 理论五:接口vs抽象类的区别?如何用普通的类模拟抽象类和接口?
09 | 理论六:为什么基于接口而非实现编程?有必要为每个类都定义接口吗?
10 | 理论七:为何说要多用组合少用继承?如何决定该用组合还是继承?
11 | 实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?
12 | 实战一(下):如何利用基于充血模型的DDD开发一个虚拟钱包系统?
13 | 实战二(上):如何对接口鉴权这样一个功能开发做面向对象分析?
14 | 实战二(下):如何利用面向对象设计和编程开发接口鉴权功能?
设计原则与思想:设计原则 (3讲)
15 | 理论一:对于单一职责原则,如何判定某个类的职责是否够“单一”?
16 | 理论二:如何做到“对扩展开放、修改关闭”?扩展和修改各指什么?
17 | 理论三:里式替换(LSP)跟多态有何区别?哪些代码违背了LSP?
不定期加餐 (2讲)
加餐一 | 用一篇文章带你了解专栏中用到的所有Java语法
加餐二 | 设计模式、重构、编程规范等相关书籍推荐
设计模式之美
登录|注册

04 | 理论一:当谈论面向对象的时候,我们到底在谈论什么?

王争 2019-11-11
考虑到各个水平层次的同学,并且保证专栏内容的系统性、全面性,我会循序渐进地讲解跟设计模式相关的所有内容。所以,专栏正文的第一个模块,我会讲一些设计原则、设计思想,比如,面向对象设计思想、经典设计原则以及重构相关的知识,为之后学习设计模式做铺垫。
在第一个模块中,我们又首先会讲到面向对象相关的理论知识。提到面向对象,我相信很多人都不陌生,随口都可以说出面向对象的四大特性:封装、抽象、继承、多态。实际上,面向对象这个概念包含的内容还不止这些。所以,今天我打算花一节课的时间,先大概跟你聊一下,当我们谈论面向对象的时候,经常会谈到的一些概念和知识点,为学习后面的几节更加细化的内容做一个铺垫。
特别说明一下,对于今天讲到的概念和知识点,大部分我都是点到为止,并没有展开详细讲解。如果你看了之后,对某个概念和知识点还不是很清楚,那也没有关系。在后面的几节课中,我会花更多的篇幅,对今天讲到的每个概念和知识点,结合具体的例子,一一做详细的讲解。

什么是面向对象编程和面向对象编程语言?

面向对象编程的英文缩写是 OOP,全称是 Object Oriented Programming。对应地,面向对象编程语言的英文缩写是 OOPL,全称是 Object Oriented Programming Language。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《设计模式之美》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(217)

  • 王争 置顶
    在这篇文章中,“面向对象编程”一词多义,不同的场景、语境下,解释不同。文章中没有点到这一点,我这里稍微补充说明一下:
    1. 文章前半部分,面向对象编程指的是一种编程风格或者范式。
    2. 文章后半部分,在讲到面向对象分析、设计、编程的时候,面向对象编程是一种行为。
    2019-11-11
    3
    93
  • 王争 置顶
    UML中定义了类之间的关系:泛化、实现、关联、聚合、组合、依赖,试问下小伙伴们,你们都能搞清楚这几个的区别吗?能否准确的用不同的箭头、图线来画出来吗?即便你能画出来,团队里的小伙伴都能看懂吗? 不过,关于类之间的关系,我后面会在实战篇中讲到的,但是,我会简化成四种关系,更好理解。
    2019-11-11
    18
    54
  • 辣么大
    关于uml类图引起了大家的广泛讨论。我同意老师的观点,uml类图还是太复杂了。我给大家一个链接。Uml类图是不用记的。用的时候看一下cheat sheet就行。https://github.com/gdhucoder/Algorithms4/blob/master/designpattern/pic/umlcheatsheet.jpg
    2019-11-11
    1
    47
  • 极客不落🐒
    Day007 04
    关于 UML 推荐一本书《Java Modeling In Color With UML》和一个神器:https://app.zenuml.com
    2019-11-11
    3
    23
  • 确认过眼神
    对于uml来说,简单点是可以的,但是对于规范还是要有的。如果不规范,会的人看不习惯,不会的人容易被带入误区。想学的人,画得再难也会去看,不想学的人,画得再简单易懂,也不会去学。
    2019-11-11
    5
    22
  • 卢爱飞
    我理解的是要因场景而异,但是最终的目的都是降低沟通的成本。
    场景1:在大多数人对UML不是很熟练的情况下,如果采用UML来进行沟通,大家在理解上一定会存在Gap,无形之中会提高学习和沟通的成本,在这种情况下,建议不使用UML。举个例子,《实现领域驱动》的作者一开始是使用UML和领域专家沟通,作者认为UML很简单,但是许多领域专家或开发人员并不能很好地理解,最后又出现了ES(事件风暴)的形式来替代。
    场景2:如果需要准确传达设计意图,还是需要UML这样的通用设计工具的,目的也是降低沟通的成本。例如,架构师的设计理念想准确传达给工程师,如果使用UML工具,可以避免模糊意图,带来额外的沟通成本。
    敏捷宣言的第一条就是“个体和沟通”高于“流程和工具”。所以要因人而异,因场景而异,在专栏里“很多类图我并没有完全遵守 UML 的规范标准”的策略,我想是一个不错的折中。
    2019-11-11
    2
    19
  • 黄林晴
    打卡~
    我觉得在工作中,如果完成一个功能需要30分钟,其实25分钟都在思考,25分钟在设计,实际编码时间只需要5分钟,而前面25分钟就是编码设计
    2019-11-11
    2
    13
  • 丁丁历险记
    下班后发现争哥让我出代码示例和说明区别,赶紧做。
    写点简单粗暴的个人理解。
    一 show me the code ..
    泛化(Generalization)class BaseComponent { ... } class Dingdding extend BaseComponent { .. }
    实现(Realization) 类实现接口 虚线加三角interface crud { func create(); func update();func get(); func() del{ } }
    class DingdingModel implements crud {
    func create(){ ...}
    func update(){ ...}
    func get(){ ...}
    func del(){ ...}
    }
    关键是后面四个 (关联,聚合,组合,依赖)先说关联关系。 (A has B)
    class DingdingUser {
    privte $account; //有一个账号对象,
    }
    再说聚合,是一种特殊的关联。
    聚合,组合, 一对多的关联
    聚合关系是“has-a”关系,组合关系是“contains-a”关系,少一个宿主对象死掉没。
    uml2.x 已合并这种无聊的区分
    聚合示例class birdsGroup(){
    private $birds;
    //聚合往往可以干增减相关的操作
    public func addBird( $bird) { ... }
    public func removeBird( $bird) { ... }
    }
    组合示例。class bird (){public $wing; //鸟由翅膀 组成.
    }
    最后说关联合依赖。
    泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖
    2 然后说些个人理解:我回顾了一下,oop 的过程。
    在框架的辅助下,数据库建模一作,其实文件放哪,啥关系就出来了,画uml 图反正了一个体力活。
    往往是去实现一个需求,将一个业务流走通,写了一段代码后,发现这里写死了,于是做点配置管理(中心控制原则) ,一个类权责过多,于是将其支解。(类的单一职责原则),重复的代码出现了,赶紧抽离出来,先简单粗爆的用一个类的静态方法抽(很多大神不建议这样做,我不明其理,慢慢研究), 某个操作,有几种不同的类可以去做实施。例如日志。(redis 写日志,文本日志,数据库日志,控制台输出) 于是搞个工厂模式,遵守下dip原则,让Log::log($log_msg, $type,$tags) 成为一种面向抽象开始,而不是面向具体实现。老板看到gmail 的undo 很酷闲着蛋疼的让你对所有操作 ,都要求在半分钟类允许undo ,上个command 应付下,不出意外 没多久,老板的redo 需求来了,就顺着扩展 ,进一步的有时候,一个主体业务完成后,要做一堆关联的杂七杂八的事,于是搞个观察者模式,这样将主体业务和后序操作业务解耦了。 继续扯到解藕(decouple)了, 我粗浅的来看,折腾设计模式,本质是解藕,找到合适的方法,在合适的场景下做对应的解藕操作。
    这么一折腾下来,类和类啥关系,好像压根没太在意到。。。。 但类之前又确实有关系 。 挺想想知道其它伙伴们是如何做oop 的。
    自我总结,套路包确实掌握了几个,但总感觉是在很浅的层面上折腾,上述错的乱七八糟的,烦请指正,个人平时就这么想的,这八个月就跟着争哥好好学习了。
    2019-11-12
    7
    8
  • daniel李
    当看到老师说uml意义不大的时候我就懵了,还好原来是指不需要按严格标准死磕uml。

    我平时在功能开发初期和后期都是用uml把我的想法可视化然后让师兄审核,减少pr被reject机率。而且也容易让别的工程师接手做功能拓展。

    不过确实互联网公司如果不是大厂,确实很少人能看懂uml。

    作者回复: 实际上,大厂也未必都在用。比如类图中几种类关系,同学们有几个能准确的用不同的图线画出来呢?

    2019-11-11
    4
    7
  • NeverMore
    对于UML,我觉得同样不要过于“学院派”,过度求其严谨,而忘记使用它的目的是什么,此谓舍本逐末。毕竟它终究只是一个工具,最终能够服务于我们的表达,方便我们的交流即可。是否要简化,当然也要看场景,至少对于学习这门课程而言,并不需要让其过于复杂而提高我们的学习成本。
    另外,我特别欣赏老师这种删繁就简、力求简约和高效的风格,或许这也是一种极客精神吧。
    2019-11-11
    6
  • 方向
    UML在毕设时候是必须的,什么用例图,时序图,活动图,非得写上去才显得高大上,但一直不得要领,当时也是网上搜相关的模仿着填充进去。始终认为这种图的目的也是为了传达明确的设计意图,遵循最基本的规范能够达到看懂、意图明确的效果就行了。
    2019-11-11
    6
  • 香蕉派2号
    1.同意老师观点,UML是提供一种规范和准则,如果严格的按照规范来做可能过犹不及,在时间成本和规范之间必尽量要做到平衡。
    2.除了以上的概念,还想到了低耦合高内聚,模块化,可维护性,可扩展性,可复用性,对象的唯一性,对象的分类(是is-a还是has的关系)等。
    2019-11-11
    6
  • 唐龙
    即便我们使用面向对象编程语言,写出来的代码也不一定是面向对象编程风格的,也有可能是面向过程编程风格的。嗯~刚学C++的时候干过这事。
    2019-11-11
    2
    4
  • BBQCAPTURE
    专栏重点是设计模式,只要便于理解,什么样的图都没关系的,凡事都要抓住重点,我觉得软件开发最大的忌讳就是追求完美,死扣细节。
    2019-11-11
    3
  • 编程界的小学生
    1.我觉得首先uml这东西很牛逼,很有必要去画,但是也需要分场景,比如crud还强行画一个出来那就是浪费时间,比如超级复杂的东西要画,那我觉得就可以简化,多配上文字注释。比如需求一般,不是很复杂也不是很简单的那种也可以好好画一下,必要的地方配上文案描述。uml能帮助我们瞬间理解这个东西到底要做什么,流程是怎样的,画出来不光是现在看还是以后复习看,他都很香!
    2.我觉得缺少了一个“组合”,首先要以类和对象作为代码的基石,还要能灵活的支持组合特性才算不严谨的面向对象语言。组合算封装特性的一部分吗?还是说只要以类和对象为基石的开发语言都支持组合?

    作者回复: 组合跟封装应该没啥关系呢。

    2019-11-11
    3
  • 忆水寒
    UML设计的合理,新开发者也能去快速开发。关键还是看自己开发还是别人开发。作为学习来说,简单的UML能表达意思即可。
    2019-11-11
    3
  • 村口叶师傅
    UML类图在功能开发完成后的交付文档中一般都会提供,方便其他同事了解代码。我不能保证看的人都懂UML类图,但是自己要尽量保证其正确性,最起码让懂的人能看明白
    2019-11-13
    2
  • 王加武
    对于UML(统一建模语言),我个人觉得它的作用还是很大的,因为它可以帮助开发人员更好的去分析一个软件的设计过程,通过它的哪些表示的方法吗,会让人的思路更加的清晰,如果是一个软件的负责人,那么使用UML来分析问题,我觉得再好不过。
    软件开发是一个工程问题,就好比盖房子,只有每一步都规划好,分析好,设计好,盖出来的房子才好,总之,我个人觉得值得花时间去学UML!
    2019-11-12
    2
  • 青青子衿
    我们是围绕着对象或类来做需求分析和设计的。分析和设计两个阶段最终的产出是类的设计,包括程序被拆解为哪些类,每个类有哪些属性方法,类与类之间如何交互等等。它们比其他的分析和设计更加具体、更加落地、更加贴近编码,更能够顺利地过渡到面向对象编程环节。这也是面向对象分析和设计,与其他分析和设计最大的不同点
    曾经面试的时候被问到,领域驱动设计和数据表驱动设计有什么区别,我觉得王老师的这句话总结的很到位
    2019-11-11
    2
  • shniu
    1.对uml,真正掌握确实有难度,很容易忘记,原因可能是自己并没有真正的理解设计这件事,比如说uml中是用泛化还是实现不是问题的本质,本质是对于一个特定问题,要如何设计才是尽可能最好的;这中间有两层:将自己的想法转成可表达的设计和将可表达的设计让别人也能理解你的意图,而uml就是一种可表达的方式,至于是不是uml并不重要;但是uml有一套规范,而且知名度高,大家多少都有一些了解,所以就成了一种大家相互沟通的通用语言,所以学uml是需要的。我现在是傻傻分不清泛化、实现、关联、聚合、组合、依赖和他们的表达形式。
    2. 想到了编程范式,虽然不是它不是面向对象独有的东西,OO只是众多范式中的一种。
    2019-11-11
    2
收起评论
99+
返回
顶部