本文主要干两件事情,推荐几本书,以及安利一点莫名其妙的笔记。
前面提到我被自己写的词法分析程序深深地伤害了,因为它竟然如此之丑,于是决心学习设计模式。
貌似一般很少能找到某个领域,是有一本公认的最权威的参考书籍的,然而设计模式就是这样的“异类”。GoF的<Design Patterns>简直是该领域的至尊。但是我要推另一本<Head First 设计模式>,适合完全没有什么OO经验的人去读。前者基于c++和少量smalltalk,后者基于Java。个人感受是第一本更像是一本字典,要理解各种模式的内涵可能会比较吃力,第二本则是绝对的神书,轻松爆笑不管多困都看的下,并且里面的例子更基础更具体,更适合入门。
因为最近刚刚开始学java的OO(Object Oriented),所以<Head First 设计模式>给了我很多的灵感。读到有不懂的地方我就去翻<Head First Java>,一周过去涨了很高的姿势。
有一些关于OO的想法要分享。
关于继承。以前不懂得继承是为了什么,做作业为了花样炫技就强行继承。后来这学期老师说继承不为什么,也只不过是为了复用一些代码,让你少码一点(当时我暗想:这理由好蠢)。后来过了好久,直到我在看设计模式的时候才重新想到这句话。我觉得其实复用的意义更在于它更支持“维护”,说的土一点是修改的时候你不用改得很崩溃。这是个很关键的点。
在c面向过程编程时也提到过类似的概念,比如要代码重构包装出一些子函数来,就是为了在出错时便于修改。打ACM的时候这也是很重要的,比如那些大模拟题,如果相同的代码段只是不断地ctrl v而不装在一个子函数里,当发现出错的时候一个一个改是要崩的,思路很容易就飞了。
继承所支持的“可维护”包括但不局限于此。但我感觉继承并不是OO的主角。
可能是因为刚学所以正热乎,我感觉多态才是OO的精髓,当然多态离不开继承等概念的配合,只是说多态这一概念本身最能体现OO的强大。
OO的基础就是抽象、封装、多态、继承。
OO原则:
封装变化(把可能发生变化的地方封装起来,如各种需求变更)。找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。建立可维护的OO系统,要诀就在于随时想到系统以后可能需要的变化以及应对变化的原则。
多用组合,少用继承。使用组合来建立系统具有更大的弹性,不仅可将算法族封装成类,更可以“在运行时动态地改变行为”,只要组合的行为对象符合正确的接口标准即可。对应“策略模式”
组合(composition)和委托(delegation)可以在运行时具有继承行为的效果。利用一般继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地扩展。我们可以利用此技巧把多个新职责,甚至是设计超类时没有想到的职责加在对象身上。而且,可以不用修改原来的代码。通过动态地组合对象,可以写新的代码、添加新的功能,而无须修改现有代码。既然没有改变现有代码,那么引进BUG或产生意外副作用的机会将大幅度减少。
针对接口编程,不针对实现编程(“接口”是一个概念,并不特指java里面的interface,因为有时类也可以作“接口”。另外因为JAVA不支持多重继承,所以它要变相靠“接口”来实现;我看GoF那本书中,C++中貌似就是直接用类来实现“接口”的)
为交互对象之间的松耦合设计而努力。这里针对有“交互”行为的对象间,对应“观察者模式”。
类应该对扩展开放,对修改关闭。对应“装饰者模式”。这一规则一般不可能被百分之百遵守,但是这个意识会帮助你权衡要遇到什么样的困境才值得去打破原则。
依赖抽象,而不要依赖具体类。“依赖倒置原则”(Dependency Inversion Principle)。大概是强调一个多态,即把抽象的方法放到抽象类中,而不是在基类中分类实现子类的函数(否则每次增删一个子类都得改动抽象类的函数实现)。
OO模式
策略模式:定义算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
观察者模式:在对象之间定义一对多的以来,这样一来,当一个对象改变状态,依赖它的对象都会收到通知并自动更新。
装饰者模式:动态地将责任附加到对象身上。想要扩展功能,装饰者模式提供了有别于继承的另一种选择。
工厂方法模式:定义了一个创建对象的接口(比如new的过程),但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。(大概是通过一个接口来控制一批接口生产出一个系列的产品。对于这个理解我暂时不敢确定)
后面还有适配器模式、模板模式、组合模式和MVC很著名,不知道还有没有时间好好看。
大概只学到这里,最近这一周的code世界观天翻地覆,以前以为懂得了那些基本概念就是懂了C++,现在想来真是管中窥豹。
毕竟纸上得来终觉浅,最近要用c++写一个电商,我还得花点功夫看看java的这些奇技淫巧在c++里是怎么做的(看来不得不啃GoF那本神书了)。这学期压力太大,没有太多自由学习的时间,先分享到这里,等电商写到告一段落再来更新一些心得。
0 等你来赞