面向对象学习小结

2019年7月31日我第一次写下开始学习面向对象的博文,到现在已经一年多一点了,对面向对象设计有了一些新的体会吧。

这一年我并没有做什么面向对象的软件设计,不得不说一开始的基础太薄弱了,每次想要动手发现自己欠缺的太多了。

而简单的系统软件,像之前那个销售管理系统,我可以做到,但老实说,我并没有感受到面向对象的魅力在哪里,我并没有怎么分离对象,也没有经历需求的改变,一切都在静态条件下完成的,我花了半天时间理解题意,半天时间解决一些数据读取保存的问题,然后就直接敲代码了,收获也是有的,面对对象的设计,将数据和方法封装在一起,至少编程能力是提升了一丢丢的。

当时我的想法也很简单,总公司,子公司,这就是两个对象,子公司有很多自己的数据,总公司可以读取这些子公司的数据,还有一些其他的动作,如增删改查。

从题意上看,这就已经足够完成这个任务了。经过这一次的练习,我对编写类有了一定的自信,后来也开始在OpenCV的类库中挑选了一个Sinpleblobdetector类,通过继承的方式给它增加一些新的功能,由此创建了第一个我自己设计的类。到这里我开始理解到类的优点了,同时意识到实现一个类的功能与如何去分解问题创建拥有不同属性和方法的类同等重要。实现一个类的功能是算法问题,如何去分解问题才是面向对象应该着重考虑的事情。那么如何去分解??像上面的销售管理系统,我是按现实中的实际存在的成分去分解的,还有OpenCV里的cvMAT,这是按照数据代表的实际意义去分解的,它代表了图像。到后来我真的想去实现一个较为复杂的软件设计了,因为需要有GUI编程,我去学习了Qt,一开始涨着自己有学习matlab GUI的学习经验,直接上手就去看了Qt的帮助文档(ps:这个时候我对类的理解还没有达到现在的水平),看的一塌糊涂。。signal,slot的概念分不清,怎么去写这些的语法也不清楚,qt自生成文件的格式不清除,qt的事件循环机制不清楚。。花了好长时间,老老实实去看了一个Qt入门的教学视频,将一些基础操作和一些基本的概念了解一下之后,再看文档,慢慢的我开始理解Qt的类脉络图了。

我了解的qt类最多的就是widgets了,我就以它为例子,讲一下在我眼里它是什么样的。
定义:用于构建 GUI 界面的 C++ 图形组件类

在我眼里widgets就是那些在界面上显示的按钮,文字,表格,图片等等。

这是第一层,从宏观视觉角度,它就是在界面上显示的图形的基础。

第二层,根据数据类型的不同,需要不同的框去显示这个图像,还需要一些开关啊,选择项,这就是不同的按钮,下拉框,滑块。这些组合在一起就是所有我需要的图形了。

第三层,那如何实现这些不同的按钮,滑块,显示框呢?对一幅图形来说都有啥?在图像上显示的大小,颜色,形状这些基本的属性,还有一些对于不同的图形来说有不同要求的属性,如按钮,它有不同的状态,按下有一个颜色,抬起有一个颜色等等。还有就是它必须能响应我的操作,我点它,它要能有一个反应,鼠标,键盘的操作要能改变它的属性。
实现这些就是一个图形的实现。

第四层,每一个图形都实现一边大小,颜色,形状,字体,回复我的响应事件。好累啊,好麻烦,既然所有这些都有这些属性,我为什么不设计一个只有这些属性的图形呢,它不需要包含那些特殊的属性,就大家都有的我也有就好了,然后那些类在实现的时候继承这个公有的不就好了。这一层应该就是widgets了。(个人见解,水平有限,切勿轻信)

第五层,在往下的话还可以怎么分,像响应点击,划过,拖动等事件就可以专门创建一个动作类,然后每一个图形类包含它不就都有这个属性了,越到底层越是抽象,不仅仅局限于简单的分离了。

所以从上面的分析可以得出较为浅显的结论:

面向对象要学习的是将问题域通过一系列分层,分离 等抽象方法,将具有一系列相同特征的 对象 封装成,通过类之间的组合继承来实现与问题域一一对应

我刚才在上面是从目之所视的图形开始分离的自顶向下的分离,还有一些分离所用到的思想在一些面向对象课程中都有讲到,像学堂在线的软件工程课程有讲这些分析方法。

到这里为止是我之前趟过的一些雷吧,到现在才可以说面向对象设计的学习之路才正式走上轨道吧。

那为什么我会花了这么多时间呢?面对一门新的课程,如何去学习,学习方法是什么样的,从哪里入手,关键是什么,这些在我脑海里有一些模糊的概念,趁今天我要剖析一下我自己。

将我的内心每一步的与实际学习的内容和最后的效果做一个比较,从而尝试得出结论。

第一阶段:
想法:寻找面向对象书籍,开始学习面向对象编程,提升自己
实际:书籍找的是面向对象的分析与设计,设计模式,面向对象技术(matlab),深入浅出MFC,最开始看的是MFC这一本,因为上面讲会有一些C++的基本知识在里面,适合有一定编程能力又不了解面向对象的读者。因为之前在看matlabGUI编程时看过一个MVC模式,知道它是面向对象的编程,一直想尝试写一个类似的。
效果:一团乱糟糟,直接面对虚函数,多态等概念而完全不知道这些东西存在的意义,为什么要有多态,为什么要有虚函数,继承有啥用,为啥有些地方要用组合,一无所知,直接面对概念化的实践迅速消磨了我对学习的热情,所以放下了一阵子。MVC更是一头雾水,有这个类,那个类,这个类显示,那个类存数据,还要有一个类连接它们两个。真的到底怎么实现啊,这就是我当时的心声,说这么一大堆有啥用??我还是不会编程实现啊。。。能不能教我编程实现的,有没有这么一本书,一门课程,这是我当时心里最大的诉求。

第二阶段:
想法:之前被磨灭了热情之后,都没怎么在意面向对象的事情了,属于无心插柳柳成荫吧。我表弟的同学有一个大作业,自己做不出来寻求帮助,我看了一下想练练手。
实际:最开始分析题意,发现自己并没有什么思绪,无奈百度搜资料看别人怎么做的,然后只看别人的设计思路,自己依葫芦画瓢,设计了总公司和子公司类,总公司类的行为属性和子公司的行为属性独立编程,没copy代码。
效果:开始认为对象就是现实世界的真实存在的物体,它有属性,行为,如子公司有公司名,公司号这些固定的属性,销售额等可变属性,无行为。母公司能读取20个子公司的数据等等行为。我开始对对象有了更深一步的理解。

第三阶段:
想法:这里有回到了带有强烈目的性的学习过程了,因为某些原因我需要自己编写一个软件用来和下位机通信,本来读取保存也就够了,但总想挑战一下,想同时实现读取与处理与显示功能,于是开始了第三阶段的查资料。
实际:由于上一次看书看的我头发昏,这一次果断选择看教学视频,我选择的是学堂在线的软件工程,有两位老师的课程我都选了,都看了,第一个讲的内容是:初识软件工程——编写高质量代码——单元测试——软件开发过程(看到这里我开始不想看了,面向对象啊,我不想知道这些,到底咋写面向对象程序啊!!!,这就是当时的想法)——团队开发管理——敏捷开发——需求获取——用例建模——面向对象分析与设计(直接跳到了这里,然后看到卡片法,类图建模什么的就知道又不是教我写的,放弃)——(其他内容),我开始转向另一门课程,这门课程一开始将一些数据结构的知识,我之前看过一些数据结构与算法,也算勉勉强强跟上了,后面就开始是黑白盒,自顶向下分离,还有别的一些分离我不记得了,总之到最后我的感觉就是???所以到底咋编写呢??就这么不了了之,看了一段之后就放在一边了。

第四阶段:
想法:这里也是无心插柳柳成荫,第二阶段对对象的概念有了实际上手的经验后,我开始尝试自己写一些类,也是运气,我的实验过程中需要用到斑点检测的算法,我查资料发现OpenCV中有一个sinpleBlobdetector类可以用分水岭的思想解决斑点检测的问题,但问题也出在这里,真的太sinple了,斑点检测的非常不全,虽然很精准,但信噪比低的地方完全就啥也没有。但我要处理的图像在图形结构上和我前面的光学系统参数是有着联系的,它们按规则排布,所以我想用规则,以已知点为基础去推导未识别的点,所以需要在原来的类基础上进行一定的改造。
实际:我用的是继承,将原来sinpleblobdetector类直接继承到新的我生成的类,然后对里面的数据进行操作,就是加上一个斑点补全的函数。
效果:开始理解继承的实现对于编程的好处,好方便一个,可以直接在上面进行我想要的操作而不需要重新写代码,nice。

第五阶段:
想法:无心插柳柳成荫。看了一些Qt的编程,想自己写一个串口,纯c++无任何包实现这个功能,我可没这个自信,所以跑去看qt里面的QSerialPort类,学习它的用法,然后回顾了一下QWidgets。
实际:实际效果可以看我之前的博文,我是如何看Qserialport类和设计的什么样的界面都在上面,凭借这一次的学习,我对类的概念可谓是突飞猛涨似的理解加深,因为QserialPort里面的信号是继承的一个虚拟类的,叫做QIOdevice类,我对继承的概念有了更进一步的体会,一个类实体中共有的部分可以提取出来作为一个基类,这样具有相似属性的类都可以继承这个基类而降低我的编程难度,哇,美滋滋。
效果:继承对于编程的便利性,简直不要太爽。这一部分体会到了继承这一特点完全超越普通的结构化编程的地方了。

第六阶段:
想法:回顾了一下自己之前写的面向对象学习的博客,想着这些学习内容有点浅薄片面,想做一个总结,面向对象究竟是什么,如何去学习。
实际:这就是这一篇博文的前半部分,回顾了一下自己的学习历程,将自己阶段性的理解放在上面,为了讲清楚面向对象在我心中的样子,我举了qt Widgets类的例子,跑去重新看了qt5类图,发现类与类之间的继承关系是由其共有的属性或者行为决定的,组合关系是可以囊括在一个抽象的大类下,但每一个都有其特殊的地方,这些组合关系中的类可以单独存在,也可以和组合中的其他类组成新的结构,进而得到了上半部分的最后一句话:
面向对象要学习的是将问题域通过一系列分层,分离 等抽象方法,将具有一系列相同特征的 对象 封装成,通过类之间的组合继承来实现与问题域一一对应
效果:开始认识到面向对象的本质是一种方法论,而不是一种实现技术,它不是教我们如何去编写代码而是教我们如何去看待一个问题,然后才是这个问题如何在计算机中实现,当然这两个问题并不可分,本质上技术的发展是从问题如何在计算机中实现到在什么角度去看待问题更容易在计算机中实现,这种角度的实现比其他角度看待问题的实现方式优越在哪里。而我们学习的阶段是前人发展总结的基础上,他们总结出来在这个角度,用这种方法去分析问题域可以更好,更快,更准确的得到在计算机中实现的方式。
面向对象只是一种看待问题域的角度而已,学习面向对象是去学习如何分离,分类,分层问题域,将复杂的问题域变成一个一个的对象及它们之间的关系。编程的复杂度取决于我们去分析问题域与需求的契合解。越是契合则编程的难易程度,可移植性等等都会呈现一个好的状态。像是单一职责法则等都是寻找契合解与需求变换之间的平衡。在这个层面上去看面向对象,终于不再是盲人摸象,对整个体系有一个从上到下的俯视之势,能够从根源上去理解这些概念,剩下的就是遵循前人的思路,去体会他们面对问题域与软件实现上的想法了。

学习的方法论:自顶向下先理解整体的知识结构,某项知识或者技术结构在整体中的作用,最后才是如何实现某项技术。
但要说一开始就能站在巨人的肩膀上吗?难,我花了一年时间才慢慢的理解到现在的程度。。方法固然有问题,但要说最致命的还是我没有认认真真的去理解学堂在线里面的两门视频课程,现在看起来觉得那两位老师全部讲到了最精华的点上了,无奈我太浮躁了,没有顺着这些前辈高人的思路,而一味的想去用自己的思维方式,或者说想用自己之前的一些经验去套在完全不同的知识体系中,这才是最大的问题,当然只要能坚持下去总有一天能够豁然开朗,茅塞顿开,没有掌握精髓的学习固然很慢,但也不全是绝望,时常思考总结,静下心想一想我有没有做错,每一个小点的作用,优点,实在不明白就放下做点别的,也许就会无心插柳柳成荫。

在学习的过程中我看的是面向对象的分析与设计这本书,清华大学出版社出版的,里面讲了面向对象设计的整个完整的概念和流程,非常详细,前面的概念和原理必要性,中间的思考方法,后面的实现层次分明。
唯一让我感觉比较遗憾的是从需求分析到中间的基本模型构建并没有一个很好的映射关系,让我有点不明所以,当然这些部分同样重要,对于功能与后续分析与编程的完整性是不可或缺的,但类与对象的构建,如何组织它们的关系我还存在疑问,以后对这个问题有了更深的理解之后再来写下一篇博客吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值