概述
通过回答几个问题来了解《设计模式》的概念。
什么是经验?
经历了一个问题,摸索出解决方法,验证后正确,总结出“经验”。记录下来,下次碰到此问题,复用此解决方法。
优点:少碰钉子,省去重复劳动,节省时间
本质:键值对【问题,解决方法】
过程:面对一个问题,通过实践各种可能性,总结出正确的解决方法;记录此【问题,解决方法】键值对
什么是设计的本质?
划分角色,分配职责。
比喻:就像开公司一样,先定义好需要的职位,然后给每个职位定义职责;确保每个职位做事都非常专业,所有职位上的人协调起来可以做大事,运转流畅。
什么是设计模式?
关于 “面向对象设计” 的经验。 “根本” 是对面向对象思想的深刻理解 !
为什么要学习设计模式?
因为软件需求在不断变化,为了应对变化,程序用 “复杂和性能” 换取 “灵活性”;
使用封装创建对象间的分界层,将变化归到分界层的一侧,将变化的影响减到最小;
将容易变化的职责提取出来,创建一个新的角色,来实现这个职责
(程序中散落了多个变化点,修改起来麻烦,把它们抽取出来并分个类,就便于管理了,抽取就增加了中间层,以付出多余代码为代价)
(在不同的情况下,抽取方式不同,带来的效果也不同,前人总结经验后,归纳出了设计模式)
(在现实生活中,一个岗位的工作过于繁重,新增一个岗位分担其工作)
也可以理解成:根据具体情况,创建合理的角色,分配合理的职责
如何使用已有的设计模式?
1)对照使用场景
2)了解使用后的效果
3)记住实现方式
学习设计模式必须要清楚认识的一点?
没有一步到位的设计模式,针对具体问题,必须不断重构 !
(对学习经验的总结也是一样,人的认识是在螺旋式的上升,博客也必须不断重构)
设计模式解决问题的方法?
1)寻找合适的对象;
2)决定对象的粒度;
3)指定对象的接口;
4)描述对象的实现;
5)运用复用机制(对象组合,类继承,泛型等);
6)关联运行时刻和编译时刻的结构;
7)设计应支持变化(对需求变化的预见);
1)和2)的本质:划分角色; 3)和4)的本质:分配职责; 5)和7)是设计要达到的目的:代码复用,应对变化;
6)还没搞清;
设计模式根据目的分类?
1)创建型模式:与对象创建有关 ( 类 ---》 对象)
2)结构型模式:处理类和对象的组合 (基本类 ---》 合成类)
3)行为型模式:类与对象交互中的职责分配 (一个类 ---》 多个类)
用结构型模式描述类的内部结构,(本质:类依赖于它的属性,对两者进行职责分配 和 合理描述定义)
用创建型模式约束类的实例化,(本质:将new封装到方法中,再根据具体情况将方法分类)
用行为型模式约定对象之间的通信方式。
设计模式根据范围分类?
1) “类” 模式:静态,处理类和子类的关系(继承)
2) “对象” 模式:动态,处理对象间的关系(对象组合)
继承:在原有基础上修修补补(override是修,扩展方法是补)
组合:用现有的东西组装(联想组装电脑的过程)
面向对象设计原则?
1)单一职责:一个类只有一个职责,是唯一引起它改变的原因(高内聚)。
2)开闭原则:类模块可以扩展,但不可修改(关键是使用好 “抽象” 和 “多态”)。
3)替换原则:在程序中,子类可以替换父类(因为 “良好的子类” 是 “父类” 的一种特殊情况)。
4)依赖原则:业务关系由 “抽象类和接口” 描述, “具体类” 负责相关实现。
5)接口分离原则:接口根据特定 “客户类” 而分离,随某一客户类需求而变化(接口单一职责)。
从设计原则到设计模式要明确的思想?
1)针对 “接口” 编程,而不是针对 “实现” 编程
2)优先使用对象组合(has a),而不是类继承(is a)
3)封装变化点
面向对象程序的内涵?
设计 “类和相互通信的对象之间的组织关系”。
(写程序就像 “搭积木”,类就是 “积木模型”,好的程序只需要最少最简单的 “积木模型“,组合出各种效果)
浅陋的认识面向对象?
1)封装:隐藏内部实现
2)继承:复用已有代码
3)多态:改写对象行为
如何深刻理解对象?
1)概念层面:对某种职责的抽象
2)规格层面:公开的接口
3)语言层面:封装 “状态” 和 “行为”
“抽象类” 与 “接口” 的区别?
抽象类:定义是什么。 接口:规定做什么。
接口就像在画芯片的引脚,抽象类多了芯片内部一些固定的电路;
具体类就像某类芯片,实现各个引脚的功能,内部的电路都固定了;
程序中的两种思维?
1)分类思维:先粗分大类,在细分小类。思维结构是“树状”的。
2)步骤思维:将操作序列化,先做什么,后做什么。思维结构是“线性”的。
两种思维可以相互转化,数据结构中有关“树”的部分是基础理论,学好了就可以转化的很好。
个人觉得:分类思维适用于分析问题(因为人脑的思维有局限),步骤思维适用于写代码(因为代码是顺序执行的)
对于面向过程和面向对象的理解?
1)面向过程的代码像是“钢筋混凝土”,全部连在一起,是紧耦合。
2)面向对象的代码像是“把钢筋混凝土砸碎,分成小块的砖”,可以自由组合,是松耦合。
设计模式的基本工具?
抽象类/接口,继承,对象组合
(在不同的场合,运用人的逻辑思维使用这些工具,就出现了设计模式)
抽象类/接口:从抽象层面描述问题的结构
继承的含义是:我告诉别人,我要做什么
对象组合的含义是:我不是从头做,是在别人的实现基础上做(站在巨人的肩膀上 O(∩_∩)O~)
继承是封装不容易变化的部分,对象组合是封装容易变化的部分
突然忘了继承与对象组合的区别,它们太像了,被复用的类一旦变化,都会随着变化!
多角度思考?
继承:从父类的角度思考,是由父类向子类 扩展(扩散的过程);
从子类的角度思考,是由子类向父类 抽象(提炼的过程);
对象组合:从被组合对象思考,是把变化的部分抽象了出来,封装到另一个对象中;
从 组合对象思考,是复用自己的价值,使另一个对象省去重复劳动;
关于分层的理解?
上下结构:下层是基础,给上层提供服务;上层是使用者,调用下层的代码;是上下级的关系;
左右结构:相邻层之间是互相通信的关系,没有主次之分,通过约定接口来通信,而不是直接使用其中的类;
理解面向对象的核心?
通常认为OO的核心是封装:就是如何分类;
而忽略了它的另一个核心:消息机制,清晰描述对象之间的通信关系;
【若有所思】
面向对象中核心的思想是类,通常理解为分类,在学习了前3个模式后,突然觉得:“设计模式就是把原本灵活的程序,根据分类限制死,因为在具体需求的背景下,程序不会无限灵活,它的变化只会限制在设计模式的分类中”;
是否可以把“模式”理解为“沙盘”或“模具”,原本可以有无限种变化,在某个需求背景下,它的变化被限制,根据这个限制范围,做一个“沙盘”或“模具”,它足够解决此需求背景下的所有问题,且更有针对性。
在学习了前4个创建型模式后,发现封装的变化点都是放在非Client端,设计模式的目的是:“简化Client程序”,让类库做更多的工作。另外对封装有了一些个人的理解:就是抽取公共的部分,统一去管理,设计模式更喜欢封装到新建的类中。因此代码变多,使程序效率降低,这就是使用设计模式要付出的代价。
在学习了前4个结构型模式后,发现它们的共性是都用到了“对象组合”(一个对象或多个对象),选择性的使用“组合对象的抽象”,选择性的使用“类继承”(被组合类和组合类之间的继承)。由于后面两种是可选的,所以它们有2*2=4种组合情况。Adapter是单个“对象组合”,Composite是多个相同类的“对象组合”+“类继承”,Bridge是单个“对象组合”+“组合对象的抽象”,Decorator是单个“对象组合”+“组合对象抽象”+“类继承”。
发现一个现象,这3种设计模式在“底层”(面向对象思想层面)的差别很小,比如:是否使用“组合对象抽象”、“类继承”等。设计模式的命名和例子,是从它们在宏观上的表现来描述的。这让我想起时常说的一句话:“看人不要看表面,看事物要透过现象了解本质”。本质和表象是事物的两个方面,从两个角度去看问题可以认识的更清楚,但一定是本质决定表象,相似的表象也许会有截然不同的本质,好像李建忠老师在课程里常说的一句话:“相似的代码有可能是截然不同的设计模式,同一种设计模式却可能有完全不同的代码表示”。可见理解设计模式本质(面向对象思想)是关键。认识一个事物都是从表象开始的(客观规律,无法改变),要了解它的本质需要思考和洞察力(发挥主观能动性的时候),o(∩_∩)o 。
应对变化的方式:抽象。变化的各种情况互为“兄弟节点”,抽象出“父节点”,它就可以代替所有兄弟节点,从而应对变化。
行为型模式学习到Observer后,终于体会到“职责”和“协作”的概念。
“职责”由对象的行为体现,就是你能干什么。 “协作”由对象间的消息传递体现,就是你让对方做什么。
消息可以分解为3个部分:调用---》本身的含义---》实现。两头是adapter,分别连接发送者和接收者,并且是它们的一部分。
最后
以上就是专一毛豆为你收集整理的1.设计模式的基本概念和原则的全部内容,希望文章能够帮你解决1.设计模式的基本概念和原则所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复