质量好网站建设公司,wordpress宝塔安装环境,网络营销渠道策略研究,怎么查看网站的ftp地址文章目录 1. 面向对象设计#xff0c;为什么#xff1f;2. 重新认识面向对象3. 面向对象设计原则3.1 依赖倒置原则(DIP)3.2 开放封闭原则(OCP )3.3 单一职责原则( SRP )3.4 Liskov 替换原则 ( LSP )3.5 接口隔离原则 ( ISP )3.6 优先使用对象组合#xff0c;而不是类继承3.7… 文章目录 1. 面向对象设计为什么2. 重新认识面向对象3. 面向对象设计原则3.1 依赖倒置原则(DIP)3.2 开放封闭原则(OCP )3.3 单一职责原则( SRP )3.4 Liskov 替换原则 ( LSP )3.5 接口隔离原则 ( ISP )3.6 优先使用对象组合而不是类继承3.7 封装变化点3.8 针对接口编程而不是针对实现编程 4. 将设计原则提升为设计经验 1. 面向对象设计为什么
变化是复用的天敌面向对象设计或者说使用了抽象原则的面向对象设计最大的优势在于 抵御变化
2. 重新认识面向对象
之前我们对面向对象的理解包括封装、继承、多态这是属于面向对象的底层思维理解。从抽象思维进行如下理解
理解隔离变化 从宏观层面来看面向对象的构建方式更能适应软件的变化能将变化所带来的影响减为最小。 各司其职 从微观层面来看面向对象的方式更强调各个类的“责任”由于需求变化导致的新增类型不应该影响原来类型的实现-所谓各负其责多态更多的使用 对象是什么 从语言实现层面来看对象封装了代码和数据。从规格层面讲对象是一系列可被使用的公共接口。从概念层面讲对象是某种拥有责任的抽象。
3. 面向对象设计原则
设计原则要比具体某一个模式更为重要后期讲到的模式当下已经不流行某些已经被有些语言模式替代甚至忘了也不重要。有了这些设计原则可以理解其他的模式甚至可以设计自己的模式。
有一种错误的观点就是将设计模式当做算法去学习后期可以看到两段代码非常相似但是表达的模式是完全不同的也有一种可能就是代码千差万别但是设计模式是一样的。
所有的设计模式都是依赖这里所讲的设计原则如果违背了设计原则这种设计模式就是错误的。设计原则是一把尺子可以用来衡量软件设计品质。 学习设计模式一定不要只看代码的调用流程如果你了解虚函数的调用机制23种设计模式可以很快看懂但是要掌握设计模式就需要从设计原则的方向出发。
3.1 依赖倒置原则(DIP)
高层模块(稳定)不应该依赖于低层模块(变化)二者都应该依赖于抽象(稳定) 。抽象(稳定)不应该依赖于实现细节(变化) 实现细节应该依赖于抽象(稳定)。
上面的话怎么理解呢上篇中Mainform依赖于Line和Rec。示意图如下图所示箭头指向的代表了依赖 Mainform属于高层模块Line和Rec属于底层模块由于底层模块是容易变化的高层模块是相当文档的稳定的东西依赖于变化的东西稳定的也就变成不稳定的而应该将二者都依赖于抽象。
转换为第二种方式示意图如下图所示 Mainform依赖于ShapeLine和Rec也是依赖于ShapeShape也就是上面讲到的抽象。
有些人喜欢在抽象类中使用子类那就违背了抽象(稳定)不应该依赖于实现细节(变化) 这是因为抽象应该是稳定的如果依赖于一个实现细节这个实现细节是容易变化的就会变成稳定的依赖于变化。
这里最关键的地方就是Line和Rec不稳定容易变化导致Mainform不稳定。
依赖倒置原则 DIP原则贯穿于所有的设计模式这种原则是十分依赖抽象类的。
3.2 开放封闭原则(OCP )
对扩展开放对更改封闭。类模块应该是可扩展的但是不可修改。
首先举一个现实生活的例子有一个需求需要做一套桌椅板凳将需求提交给一个木器加工厂加工过程中使用场景是在一个办公大楼所有的办公家具需要达到一个几级阻燃的标准现在将新的需求告诉加工厂木器加工厂如何应对呢有两种应对方法
将做好的东西扔掉重新再弄这是一种改变的做法不太好浪费程度很大。聪明的木器加工厂只需要刷一层防火涂料就可以了他已经做了一些工作只需要在前面基础上刷一层防火涂料这是一种扩展的做法。
从代码的角度分析上篇的代码中就使用了开放封闭原则第二种方法就是以扩展的方式来应对需求的变化。
当需求变化的情况下不要想着去更改应该想着增加一些东西来应对需求的变化。
3.3 单一职责原则( SRP )
一个类应该仅有一个引起它变化的原因。变化的方向隐含着类的责任。
有的时候你会发现一个类会写的很臃肿当一个类中放了太多的功能也就隐含了多个责任当隐含多个责任的时候就会出毛病多个责任将你往不同的方向拉扯用子类的时候一会这个方向一会那个方向。后期会讲到桥模式装饰模式都会遇到类的责任问题类的责任问题通常情况下表现不是那么强烈当遇到特殊的场合类的责任是非常重要。
3.4 Liskov 替换原则 ( LSP )
子类必须能够替换它们的基类(IS-A)继承表达类型抽象。
作为子类所有需要父类的地方都可以将子类传过去进行使用这是天经地义的但是具体实现时就是会有人打破这个原则。 例如有些程序员朋友喜欢在继承父类的子类中发现父类中的三个方法子类无法使用的这个时候会在子类的3个方法中throw exception这个做法就不对了。这就说明子类没有继承父类或者说有可能是组合关系。
3.5 接口隔离原则 ( ISP )
不应该强迫客户程序依赖它们不用的方法。接口应该小而完备。
“接口应该小而完备”中小的意思就是不要把不必要的方法public出去。如果只是子类使用的话就protected。如果本类使用的话就private。如果真正有必要暴露的情况下才将其public出去。 当你无节制的public出去就很容易让外部的客户程序对其产生依赖一旦产生依赖接口就需要保持稳定。
3.6 优先使用对象组合而不是类继承
类继承通常为“白箱复用”对象组合通常为“黑箱复用” 。继承在某种程度上破坏了封装性子类父类耦合度高。而对象组合则只要求被组合的对象具有良好定义的接口耦合度低。
更准确的继承关系其实是一种类属关系比如说动物继承自生物人又继承自动物。很多时候我们会错用继承通常我们会有另外一种表白方法对象组合class A中包含class BB可以是指针或者对象。
3.7 封装变化点
使用封装来创建对象之间的分界层让设计者可以在分界层的一侧进行修改而不会对另一侧产生不良的影响从而实现层次间的松耦合。
当设计的素养逐步提升是可以在软件领域划分分界层从传统面向对象思维封装就是封装代码和数据但是封装更高层次就是封装变化点一侧变化一侧稳定。
3.8 针对接口编程而不是针对实现编程
不将变量类型声明为某个特定的具体类而是声明为某个接口。针对业务类型而不是像string等的具体类客户程序无需获知对象的具体类型只需要知道对象所具有的接口。减少系统中各部分的依赖关系从而实现“高内聚、松耦合”的类型设计方案。
上篇中 vectorLine lineVector;vectorRect rectVector;就违背了针对接口编程的原则而
vectorShape* shapeVector; //放抽象接口
......
shapeVector[i]-Draw(e.Graphics); //使用接口的通用方法即可针对接口编程的原则通常是与依赖倒置原则(DIP)相辅相成违背了一个通常也就违背了另一个。
不同设计原则是从不同角度看问题的。
面向接口设计的深入思考产业强盛的标准接口标准化!
接口的标准化也就代表了工作的分配
4. 将设计原则提升为设计经验
设计习语 Design Idioms Design Idioms 描述与特定编程语言相关的低层模式技巧惯用法。 设计模式 Design Patterns Design Patterns主要描述的是“类与相互通信的对象之间的组织关系包括它们的角色、职责、协作方式等方面。 架构模式 Architectural Patterns Architectural Patterns描述系统中与基本结构组织关系密切的高层模式包括子系统划分职责以及如何组织它们之间关系的规则。
下篇将会真正进入每一个模式进入某一个模式之前需要深入领会上面提到8大设计原则只有这样才能灵活的运用某一种模式。