面向对象的反思

更新日期: 2020-03-05阅读: 1.8k标签: 面向对象

缘起

上周修改一个Bug,本来以为只需要做一些小调整就可以,后来还是发现由于受对象间的状态影响,出现了另一个错误。这也让我进一步思考对于系统设计和建模来说:面向对象是错误的,会带来后期的很多问题。


面向对象

在面向对象的设计中,系统是由对象和让对象状态发生改变的方法,让对象到达另一种状态来达到目的的。当系统渐渐变大,对象渐渐变多,每个对象间的纠缠越来越多的时候一个对象的状态受到多个控制信号的机会就越来越多,作为状态的使用者,你越来越无法判断你所用对象的状态——时常由于外部改动让状态发生的改变,你的编程假设也就失败。这通常会造成Bug的产生,而且很难定位和修复这样的Bug。

代码的观点来说,操作对象的代码和对象结合的太紧密,你复用的机会会越来越少,对象上的方法是针对这个对象的特化方法,你很难加以利用。所谓的高内聚让你对于已有的方法只能看,而不能用,相信对于维护代码的同学特别有这样的感觉:你的需求基本上另一个对象已经满足了80%的功能,或者你想剥离其中某个方法,会发现根本没有办法拨出来,这个方法跟对象紧密的结合在了一起。

对于维护调试来说,你会发现当系统出现问题时候,你很难改变对象上的方法,很多时候看似有问题的方法对于这个特定的对象来说居然是正确的,前提是有很多Setup让对象处理这样的状态。在调试的时候好像一些几何相关的谜题,你移动了一个角度,以为这样就能通过,其实移动带来的副作用让你无法通过。


函数式架构

系统的设计还是要采用函数式的结构,把系统看做一个数据转换器(transform),而不是状态修改器(modification)。输入点上,数据是已经求值后的不可变(immmutable)值,经由数据变换,数据的二次变换,数据的三次变换(可能是要呈现的记过),比如输出html。系统更多的像是一些管道相连的一大堆通用数据处理器。

当系统出现问题时,你可以检查输入/输出,或者直接模拟输入/输出来诊断问题。这个有点像是维修模块化的电子元件,方法通常有两个:

  • 你测量输入端的电流电压和输出端的电流电压,来确定这个电子器件是否按照预期工作。
  • 或者你逐个替换系统中的元件,直到你发现当某个零件替换后,系统正常工作了。

你如果观察维修小工,你会发现他会在这两个方法见频繁转换。

由于是同用数据结构和通用数据处理,这让复用变的可以预测(Predict),如果输入和输出可以达到你的需求,那么这个函数你就可以拿来使用。好像维修小工,并不在意某个电容是哪个生产商生产的一样,达到要求就能用。


现实例子

由于状态变化原来越频繁,面向对象缺点也就越来越突出,比如近年来的前端由纯展示(View)变成了应用(App)。所以使用jquery来修改组件的状态已经不能满足需要了,现在的Component-组件化越来越成为主流。无论是vue还是react,和其对应的 ElementUI 和 Ant Design ,让你可以对组件细节不用关心而很好的使用和替换组件。你给组件以数据,组件做这个数据的变换,变成一种呈现方式。通过约定,或者一个转换器,同一组数据,你输入到 ElementUI 和 Ant Design 出来的只是风格的偏好不同,而结果应该是一直的。

函数式架构的重点在于连接而构成的系统。通用的元件(数据结构)加上通用的变换(函数),而不是由一个个定制的对象(类型实例)而组成的,这样的系统很脆弱,坏了你没有办法维修和更换——因为都是定制的。

总结下来,当系统变得复杂以后,通过状态变化带来的副作用让系统变得脆弱和无法维护,而函数是的数据加通用处理机制会让系统工作的更好。

首发: https://www.imzjy.com/blog/object-oriented-design-retro


链接: https://www.fly63.com/article/detial/8119

JavaScript面向对象思想及继承(转载)

什么是面向对象编程思想,为什么要用面向对象思想。js中的面向对象思想和其他静态语言相比有什么不同。js中prototype,constructor,__proto__这些都是什么鬼?

面向对象设计的6个设计原则

面向对象设计的6个设计原则:1.单一职责原则,2.里氏替换原则,3.依赖倒置原则,4.接口隔离原则,5.迪米特法则,6.开闭原则

面向对象设计与分析

面向对象方法是一种运用对象,类,继承,封装,聚合,关联,消息,多态等概念和原则来构造软件系统的开发思想(方法)。

ES6 class与面向对象编程

在ES5中,我们经常使用方法或者对象去模拟类的使用,并基于原型实现继承,虽然可以实现功能,但是代码并不优雅,很多人还是倾向于用 class 来组织代码,很多类库、框架创造了自己的 API 来实现 class 的功能。

浅析面向过程与面向对象

在面试时经常会被问到面向过程和面向对象有什么区别,虽然都是编程的一种思想,但是他们的侧重点不同,我们从以下几个方面进行简单总结。

面向对象三大特征(封装,继承,多态)

代码封装可以避免代码冗余,避免去哪聚变量污染,本质就是把公共的代码抽离出来在需要的地方随时调用在继承中也有体现

面向对象设计的 10 条戒律

我们正在审查一些代码,并开始讨论为什么我们走捷径,不遵循常识原则。虽然每个人在对待关于类应该如何基于功能上下文来构建的问题上都有自己的智慧,但仍然有一些基本原则值得我们在设计类的时候牢牢记住

JavaScript 中的面向对象编程

JavaScript 是一个强大的面向对象编程语言,但是,并不像传统的编程语言,它采用一个以原型为基础的OOP模型,致使它的语法让大多数开发人员看不懂。另外,JavaScript 也把函数作为首要的对象,这可能会给不够熟悉这门语言的开发人员造成更大的困惑

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!