面向对象6大原则

来源:互联网 发布:名字壁纸制作软件 编辑:程序博客网 时间:2024/05/20 22:27
部分参考自《大话设计模式》《设计模式之禅》


单一职责原则:避免写牛类,类似在as3里,文档类不要写太多逻辑,而应该尽量只负责进行对象的实例化new  和 参数初始化等工作

接口职责单一,不过分耦合不关联的方法在同一个接口里
方法职责单一,比如修改用户姓名、电话、身份证数据,尽量不通过一个方法传入多个参数去同时修改,而是分成对应一个数据一个方法,令方法粒度足够小

影响类结构变化的原因要单一









================================


里氏代换原则:
父类出现的地方,可以替换成子类(因为继承)
子类出现的地方,未必完全可以用父类代替(子类有的方法父类未必有)


1.子类必须完全实现父类的方法

2.子类可以有自己的修改(即重写 重载 或其它父类中没有的方法等)

3.子类中override的方法,传入参数类型必须是与父类相同类型,或是子类型,即参数是Sprite,子类重写,参数也必须是Sprite或子类MovieClip等
(当然也可以传入与父类不相同的参数,只要参数类型同属一接口就可以,比如父类是Sprite,子类重写,改成传入displayObject类型也可以,但在子类中使用是不安全的,可能传入的对象没Sprite及其子类所具有的startDrag方法)

原话是:覆盖或实现父类的方法时 输入参数可以被放大(即子类化),但一般编程时override都是使用相同的类型,使用时才因应多态性传入子类使用,所以本条意义在传入参数使用时,会相对容易显浅说明意思。



4.子类中override的方法,返回类型必须是与父类相同类型,或是子类型,即返回类型是Sprite,子类重写,返回类型也必须是Sprite或子类MovieClip等
(外部对象是依靠接口来使用的,如果这里私自提升为displayObject类型,那就违反了面向接口编程的原则)

原话是:覆盖或实现父类的方法时 输出结果可以被缩小(即父化),比如返回类型是MovieClip的,外部对象调用并返回结果后,这个MovieClip类型可以被作为displayObject类型对象看待,即父化









====================================


依赖倒置原则:(面向接口数据类型编程)
编程时尽量依赖接口类型,少依赖具体类型,例如一个司机驾驶汽车的方法,传入参数应该是  :car ,而不是:benz  或 :BMW

或者比如说数据库应用项目,高层调用模块,应该面向数据操作接口,接口里定义了增删查改等接口方法,具体实现在底层的数据实现类中,高层不关心底层实现,底层是SQL还是Access不重要

另外依赖接口,可以令开发工作分工,一个模块只要面向一个固定好的接口,就可以编写测试数据,等到对应接口实现类编程完成 再行连接,就不用等到实现完成,才开始测试。


依赖的三种写法:

1. 构造函数 依赖注入
构造函数(_参数:接口类型)          如  Main(_obj:MovieClip)

2. setter方法(属性存取器) 依赖注入
public function set 属性名(_参数:接口类型)     如 public function set GF(_obj:boy)  这是同性恋的类型 限定只能传入boy类型

3. 接口声明 接口注入

public class Main extendes MovieClip{
    private var _mc:MovieClip     

在类体内声明持有对象,类型是接口类型






var 变量:数据类型 = new 类();

创建类实例时,数据类型尽量使用接口类型,
这里当然这里不是指   var _mc:MovieClip = new MovieClip(); 这种
而是指  
var _gf:people = new girl();
var _gf:people = new boy();
这种

因为面向的是接口类型 人类people  ,只要是实现了人类行为的类,那么boy 和 girl都没所谓了,

依赖倒转原则是基于接口多态使用而存在的。



依整倒转原则是六大设计原则中,较难权衡实现中的一点,它是实现开放封闭原则的重要前提,

因为只有面向接口对象,才能保证数据类型的转换正常(不会出现异常,比如bitmap就是displayObject的子类,但它没有Sprite类的startDrag方法,强行传入的话,就会报错)




面向 接口数据类型 编程,是依赖倒转原则的核心法则








============================================

接口隔离原则:

如同单一职责,接口的创建除了要求单一职责外,还要求尽可能考虑拆分性

使用单一职责,一个面向机关单位内部图书馆的查询功能接口,可能是优秀的

但如果有一天这个系统需要部署部分功能向社会公众开放(即非单位内部性)

在接口中声明的部分接口方法 , 在子类中可能就要作为留空声明,即假方法,

使用接口的对象是根据接口API调用的,明明是一个空方法,还是提供给调用者使用,

虽然调用时没实际处理功能(即面向公众的功能中,下载图书光盘的功能可能是不允许的,但空方法还是可以调用)


这种设计不是面向接口的良好习惯



在顾及单一职责原则的前提下,接口应尽量考虑部分  为个别用户 服务定制 的需求

即提供图书光盘下载的功能,不应该声明在当前接口中,而应该另外声明一个接口,

使用时,归属单位内部的功能模块,通过组合实现两个接口的方式,来达到提供下载服务


对外开放的功能模块,仅实现一个接口的方式,来达到不提供下载服务的功能




=======================================


迪特米法则:当两个类没直接关系的时候,就不应该直接访问对,而是应该通过第三者通讯,类似单例进行事件侦听管理


例如一个公司的网管部,员工的电脑坏了,应该直接通知网管部主管,让他分配工作,而不应该通知网管部的员工

因为假如网管部小A有事离开,他又跟小B关系不是太好的,这样就不可以叫小B代劳了(毕竟有时候工作职责这种难区分),员工某某就只好干等小A回来才能修电脑了

如果是通过主管的,那小A没空,就可以叫主管临时再安排小B或者小C接替工作,不存在耦合,谁来修电脑也没所谓,因为他们对外的名称一致都是 "网管部的员工"



在实验中,就像两个绑定元件间,不应该直接访问对方的变量,元件属性等,而应该元件绑定类中声明一些操作方法,通过事件派发 或者 直接调用元件的public方法,来达到控制对象内部的功能





迪特米法则 的核心要求是类间解耦,低耦合,实现此法则会令到系统产生大量的中转或中转类,导致系统的复杂性提高,给维护带来了难度。


比如平时我们实验中用到的单例事件类,它就是一个为了解除元件间调用耦合而存在的第三方类,两者间通讯通过第三者(单例事件类)来完成解耦



迪特米法则要求的是类间解耦,但解耦是有限度的,在实际项目中,需要适度考虑这个原则,而不必过分遵循,不执行是不对的,但过分执行就是“过犹不及”。






===========================

开放封闭原则:

6大设计原则中,前5大原则其实都是开放封闭原则的具体形态,实际的目的都是为了 对扩展开放,对修改封闭

前5大设计原则只是面向对象设计时的工具和方法,开放封闭原则才是最终具体的目的意义。





1. 开闭原则对测试的影响

已经投产使用的代码,理论上都是已经通过验证测试,证明安全稳定的,如果有需求变更,我们没可能把对应的功能代码抽出来,直接修改 再扔回去的,这样会产生隐式潜在的危险。

通过一定的面向对象抽象手段,比如通过泛化抽象父类(通过继承),比如面向数据接口等,来确保替换的功能与已在服役运行的代码均是正确安全的

这样修改代码时,通过扩展,而不是直接修改,达到修改功能后的类,与被扩展的类安全性上都是一样的,可以减少二次测试稳定性的工作量




2. 开闭原则可以提高复用性

我们现在的做的实验中,针对一个功能 就写一段代码,N个功能就放在一个类里,这种功能类的粒度太大,可供复用的可能性极小

所以提倡抽离可用的代码,放到项目组中,供大家公共使用

粒度越小,可供复用的可能性就越大,抽离的工作量就越少




3. 开闭原则可以提高可维护性

功能增加或修改的时候,不是去修改对应类,而是通过扩展替换的方式,来达到功能的修改,这样的工作重点在于功能的扩展,而不用重新打开原来的代码,周围找函数 去修改,可维护性提高






反正 开放封闭原则 的目的就是通过约束,来达到代码的可维护性,这个也是面向对象编程 与 面向过程编程 的不同所在!!








USB接口其实就四条线,中间两条数据线,左右两条电源线,我们自己拿个电线,四条线接起来,一样可以连上USB信号

但为了规范化接口,所以才出现USB接口这种东东,


面向对象编程 也差不多,它的工作就是要制造很多 壳、接口出来,让对象与对象之间可以通讯,但又可以随时解耦

比如U盘,可以插在这台机上用,一拔出来,又马上可以插到另外一台机上去用



但制造这些壳、接口(就像USB接口就用到一个正方框的小铁皮,还有外壳的塑胶)是一件很艰苦、很繁复的工作,需要一些很抽象的层存在,去共同完成面向对象设计的构建,所以 面向对象编程 是相对难理解就是这样的!!!




面向对象编程 入门的核心是 明确  封装 的概念, 描述一个人,在时间轴上写代码就是一堆变量,函数的集合


只有封装成一个类,才可以直接  

var 人:people = new people()
人.age = 18;



这样控制,这就是封装

当然,还有之前提到的 迪特米法则,封装时其实就是要考虑什么东西是外部不可见的,什么是提供给外部可见的

就像人的思维 想法,是外人不知道的,但五官 身高等这些就是public可见的







面向对象编程 就是封装出一系列的对象 ,然后另外创建很多媒婆对象,通过这些媒婆对象去牵连对象与对象之间的关系,或者做传声筒,连接起对象与对象,共同完成整个系统的运行。
0 0
原创粉丝点击