Unity3D 设计模式几大原则详解

原创 2017年09月11日 19:15:43

第一则:单一职责原则
1.定义:什么是单一职责原则呢?
我个人的理解就是一个类值负责一个职责,或者通俗的说就是一个类只实现一个功能,也就是不存在多于一个导致类进行变更的原因!
2.针对的问题:有就是说什么时候才会产生这种问题呢?
例如:原本有一个类叫PlayerControl,然后这个类有两个功能或者说职责,移动职责和攻击职责这两个职责,然而当我们需要修改移动的时候,可能会导致原本符合要求且正常执行的攻击出现问题,那么这个时候就导致问题的出现!
3.那么单一职责原则到底怎么用呢?
其实单一职责原则很简单,及时你不懂设计模式,也不了解各大原则,也可以很轻松的理解单一职责原则,解决上述问题就要用到单一职责原则,即分别创建两个类PlayerMove类与PlayerAttack类,PlayerMove类实现移动职责,PlayerAttack类实现攻击职责,修改单一职责时与另外的职责互不影响!这个比较容易理解,就不举例说明了!
4.遵循单一职责原则的有点有哪些呢?
1).可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
2).提高类的可读性,提高系统的可维护性;
3).变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。

第二则:里氏替换原则
1.定义:什么是里氏替换原则呢?
我相信当第一次看到这个名字的时候都有一个同感,就是里氏替换原则是个什么东西呢?从字面上我们根本无法得到任何信息,得到的就是一脸懵逼,感觉是一个很深奥的东西,而且应该很抽象,这个就是我对里氏替换原则的第一印象,但是我们看到(氏)这字时候想到的应该是姓氏,这么分析的话里氏替换原则就是,由姓里的人提出的替换原则,没错,事实就是这样的!好的,言归正传,我们来看一下里氏替换原则的定义吧:所谓里氏替换原则就是子类可以扩展父类的功能,但不能改变父类原有的功能。
2.针对的问题:有就是说什么时候才会产生这种问题呢?
有一个移动的功能由PlayerMove类来完成,现在需要对移动功能进行扩展,扩展后的功能为移动的时候播放动画,这时候扩展后的功能由原有的移动功能和新功能(播放动画)组成,新功能由PlayerMove类的子类PlayerAnimation类来完成,则子类PlayerAnimation在完成播放动画功能的同时导致原有功能移动出现异常!
3.解决问题就需要用到里氏替换原则
使用继承时,遵循里氏替换原则,子类PlayerAnimation继承父类PlayerMove时,除了添加新的方法实现新功能播放动画之外,不要重写父类的方法,也不要重载父类的方法,也就是说完全继承,只添加,不修改!
4.举例说明

public class PlayerMove
{
    void Move()
    {
        //控制移动
    }
}

public class PlayerAnimation : PlayerMove
{
    void Animation()
    {
        //播放动画
    }
}

5.总结
1).子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
2).子类中可以增加自己特有的方法。
3).当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
4).当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

第三则:依赖倒转原则
1.定义:什么是依赖倒转原则?
先抽象问题,然后将抽象的问题一点点的实现,也就是说具体实现的细节依赖于抽象,而不是抽象依赖于具体实现的细节!高层模块不应该依赖低层模块,二者都应该依赖其抽象!
2.问题产生的原因?
类PlayerAttack直接依赖类PlayerInfo,假如要将类PlayerAttack改为依赖类PlayerAttackAttribute,则必须通过修改类PlayerAttack的代码来达成。这种场景下,类PlayerAttack一般是高层模块,负责复杂的业务逻辑;类PlayerInfo和类PlayerAttackAttribute是低层模块,负责基本的原子操作;假如修改类PlayerAttac,会给程序带来不必要的风险
3.解决这样的问题需要用到依赖倒转原则
将类PlayerAttack修改为依赖接口IPlayer,类PlayerInfo和类PlayerAttackAttribute各自实现接口IPlayer,类PlayerAttack通过接口IPlayer间接与类PlayerInfo或者类PlayerAttackAttribute发生联系,则会大大降低修改类PlayerAttack的几率。
4.总结
1).低层模块尽量都要有抽象类或接口,或者两者都有。
2).变量的声明类型尽量是抽象类或接口。
3).使用继承时遵循里氏替换原则。

第四则:接口隔离原则
1.定义:什么是接口隔离原则?
客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上—->个人理解的是,如果想要实现移动,其中有两个接口都有移动方法,其中接口A中除了有移动方法外,还有很多其他的方法,接口B中只有移动的方法,那么应该选择实现接口B!
2.问题产生的原因?
类1通过接口IPlayer依赖类2,类3通过接口Iplayer依赖类4,如果接口I对于类1和类2来说不是最小接口,则类2和类4必须去实现他们不需要的方法,这样就会导致代码的冗余!
3.解决这样的问题需要用到接口隔离原则
将臃肿的接口Iplayer拆分为独立的几个接口,类1和类3分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则
4.总结
1).接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
2).为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
3).提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。

第五则:迪米特法则又叫最少知道原则
1.定义:什么是迪米特法则?
一个对象应该对另一个对象保持最少的了解,也就是说类与类之间应该保持联系越少越好,降低两个类之间的耦合度,以保持想对独立!
2.问题产生的原因?
类与类之间的关系密切,耦合度大,当一个类发生改变时,对另一个类的影响很大。
3.解决这样的问题需要用到迪米特法则
就是采取迪米特法则,尽量降低类与类之间的耦合,做到高内聚,低耦合

第六则:组合复用原则
1.定义:什么是组合复用原则?
组合复用原则也叫合成/聚合复用原则(CARP),就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。 尽量使用对象组合,而不是继承来达到复用的目的!
2.什么是合成?
合成表示一种强的拥有关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样,打个比方:人有两个胳膊,胳膊和人就是部分和整体的关系,人去世了,那么胳膊也就没用了,也就是说胳膊和人的生命周期是相同的
合成关系用实心的菱形+实线来表示
3.什么是聚合?
聚合表示一种弱的拥有关系,体现的是A对象可以包含B对象,但是B对象并不是A对象的一部分,打个比方:人是群居动物,所以每个人属于一个人群,一个人群可以有多个人,所以人群和人是聚合的关系
聚合关系用空心的菱形+实线来表示
4.优点
新对象存取成分对象的唯一方法是通过成分对象的接口;这种复用是黑箱复用,因为成分对象的内部细节是新对象所看不见的;这种复用支持包装;这种复用所需的依赖较少;每一个新的类可以将焦点集中在一个任务上;这种复用可以在运行时动态进行,新对象可以使用合成/聚合关系将新的责任委派到合适的对象。
总体上来说合成/聚合复用的好处是,优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类和集成层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
5.总结
一般而言,如果两个类之间是“Has-A”的关系应使用组合或聚合,如果是“Is-A”关系可使用继承。”Is-A”是严格的分类学意义上的定义,意思是一个类是另一个类的”一种”;而”Has-A”则不同,它表示某一个角色具有某一项责任。

总原则:开闭原则

1.定义:什么是开闭原则?
一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。只允许增加,不允许删除或者修改!
2.问题产生的原因?
在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。
3.解决方式
当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化
4.总结
其实,我们遵循设计模式前面6大原则,以及使用23种设计模式的目的就是遵循开闭原则。也就是说,只要我们对前面6项原则遵守的好了,设计出的软件自然是符合开闭原则的,这个开闭原则更像是前面六项原则遵守程度的“平均得分”,前面6项原则遵守的好,平均分自然就高,说明软件设计开闭原则遵守的好;如果前面6项原则遵守的不好,则说明开闭原则遵守的不好。

1.工厂模式:http://blog.csdn.net/battletiger/article/details/77947295
2.策略模式:http://blog.csdn.net/battletiger/article/details/77949668
3.命令者模式:http://blog.csdn.net/battletiger/article/details/78020310

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Unity3D 封装WWW

using System.Collections; using System.Collections.Generic; using UnityEngine;public class WWWTest {...

Unity3D 设计模式---工厂模式

1.工厂模式的定义 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new ...

Unity3d程序必备设计模式六大原则

Unity3d程序必备设计模式六大原则 Unity编程众所周知,它是属于脚本化,脚本没有一个具体的概念跟架构,导致在项目过程中,经常出现哪里需要实现什么功能,就随便添加脚本,结果,就造成了一片混乱,不...

设计模式几大原则

谈到设计模式,不能不说一下GRASP (职责分配原则),这个比模式更重要.我将再后边接着来分析. 下面我来分析一下设计模式原则,以及在设计模式中的体现.主要参考:程杰 (这里用DH代替)  和Jus...

设计模式出现之前的几大原则

设计模式属于OO的一部分, Gof的23种模式只不过是设计模式的沧海一粟,不同的领域都会产生不同的设计模式,当然你也可以总结出自己的设计模式。 对于学习设计模式的方法,我们不需要一开始就花很长的时间...

设计模式的几大原则

设计模式的几大原则
  • tuwen
  • tuwen
  • 2011年03月04日 19:02
  • 699

Unity3D中实现简单工厂设计模式

  • 2014年06月03日 17:15
  • 11.33MB
  • 下载

Unity3D设计模式之观察者模式

  • 2017年08月06日 16:29
  • 48B
  • 下载

Unity3d 一个优秀的程序必备的几种设计模式

编程众所周知,它是属于脚本化,脚本没有一个具体的概念跟架构, 导致在项目过程中,经常出现哪里需要实现什么功能,就随便添加脚本, 结果,就造成了一片混乱,不好管理。 更有甚者,自己的写的代码闲置一...

[Unity3d]一个优秀的程序必备的几种设计模式(待续)

[Unity3d]一个优秀的程序必备的几种设计模式 分类: Unity3D unity编程众所周知,它是属于脚本化,脚本没有一个具体的概念跟架构, 导致在项目过程中,经常...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Unity3D 设计模式几大原则详解
举报原因:
原因补充:

(最多只允许输入30个字)