设计模式原则个人拙见

一,单一职责原则
定义:就是一个类只做自己的事,别的都不管。一个条职责的潜台词的就是,专注做一个事。
举例:一台台式电脑的组成部件有电源,主板,显卡等,每个部件都有自己的职责,不能都写到一个类里,要分开定义类 自己只做自己的事。

二,开闭原则
定义:一个类应对扩展开放,对修改关闭。简单说,就是一个类里的功能不能随意修改,但却能通过继承这个类来对它的功能扩展。
举例:有一个Hero的类,其中定义了共有的功能(普通攻击,被动,技能1,2,3),很多hero都继承了这个父类,但有一天设计了一个新hero,却有4个技能,我们一定不能去修改父类里添加一个技能4,这样就会影响到其他hero,但却可以在新hero的类里扩展父类的方法,让它有技能4。

 public abstract class Hero:MonoBehaviour
    {
        public abstract void Attack();
        public abstract void Skill_Passivity();
        public abstract void Skill_1();
        public abstract void Skill_2();
        public abstract void Skill_3();
    }
    public class Hero1 : Hero
    {
        public override void Attack()
        {
            Debug.Log("释放hero1普通攻击");
        }
        public override void Skill_1()
        {
            Debug.Log("释放hero1技能1");
        }
        public override void Skill_2()
        {
            Debug.Log("释放hero1技能2");
        }
        public override void Skill_3()
        {
            Debug.Log("释放hero1技能3");
        }
        public override void Skill_Passivity()
        {
            Debug.Log("hero1被动技能");
        }
    }
    public class Hero2 : Hero
    {
        public override void Attack()
        {
            Debug.Log("释放hero2普通攻击");
        }
        public override void Skill_1()
        {
            Debug.Log("释放hero2技能1");
        }
        public override void Skill_2()
        {
            Debug.Log("释放hero2技能2");
        }
        public override void Skill_3()
        {
            Debug.Log("释放hero2技能3");
        }
        public override void Skill_Passivity()
        {
            Debug.Log("hero2被动技能");
        }
        public  void Skill_4()
        {
            Debug.Log("释放hero2技能4");
        }
    }

三,里氏代换原则
定义:一个软件如果使用的是一个基类的话,那么一定适 用于其子类,而且它根本不可能察觉出基类对象和子类对象的区别;必须指出,这个原则 反过来不一定成立,即一个软件实体使用的是一个子类的话,那么它不一定适用于基类。
核心:在使用基类的的地方可以任意使用其子类,能保证子类完美替换基类;
举例:就拿Unity引擎来说,Unity就是基类,unity5.x,unity2017.x,unity2018,都是Unity基类的子类
某人想用父类的Unity做一个游戏
父类的Unity,就可以完美的用unity2017代替,去完成这个游戏
在这里Unity2017就可以完全的代替掉父类,unity父类的所有的功能,Unity2017都会有,只是会扩展有新的功能
但父类就不能代替子类,可能unity扩展的功能父类unity却没有,当需要用到Unity2017的新功能时,unity父类就没办法完成了

public class Unity
{
    public void MakeAnimator()
    {
        Console.WriteLine("制作动画");
    }
    public void MakeUI()
    {
        Console.WriteLine("制作UI界面");
    }
}
public  class Unity5:Unity
{
    public void MakeParticle()
    {
        Console.WriteLine("制作粒子");
    }
}
public class Unity2017 : Unity
{
    public void Physics()
    {
        Console.WriteLine("物理系统");
    }
}
public class TestMain
{
    public void Main()
    {
        Unity unity = new Unity();
        unity.MakeAnimator();
        Unity unity1 = new Unity2017();
        unity1.MakeAnimator();
        Unity2017 unity2017 = (Unity2017)unity1;
        unity2017.Physics();
    }
}

四,依赖倒置原则
定义:依赖于抽象(编程),不依赖于具体(实现编程)。高层模块不应该依赖于底层模块,两个模块都应该依赖于抽象(抽象类/接口)。高层和底层不应该直接沟通,高层底层 之间,应该有一个中间层,负责两方沟通。
举例:1,一个不懂英语的中国人,要与一个不懂汉语的美国人交流,就需要一个翻译,那么这个中国人与美国人都依赖于翻译。
2,还拿Unity引擎说,在Unity上用C#开发产品可以发布到N个平台上,Unity 本身就做了一个“对接”的任务,把我们的代码里面的API,对接到该平台上相应的API。
高层和底层都依赖于抽象:我们的游戏是依赖Unity 的,各个平台的API 也是Unity 完成对接任务的。
五,接口隔离原则
定义:一个接口只定义一个方法,类间的依赖要建立在最小的接口。一个类不需要它用不到的接口。
举例:一款网络游戏包含前段界面,与后端的数据处理与储存,技术人员1是一个比较厉害的人,会前端与后端,现在有一个接口对他来说就比较合适,他一个人就能完成前段与 后端。

interface IGame
{
    void WriteFrontEnd();
    void WriteBackEnd();
}
public class Technicist1 :MonoBehaviour, IGame
{
    public void WriteFrontEnd()
    {
        Debug.Log("写前端");
    }
    public void WriteBackEnd()
    {
        Debug.Log("写后端");
    }
}

但这样厉害的人毕竟不多,现在有两个个技术人员,技术人员2和技术人员3,技术人员2只会前段,技术人员3只会后端,他们就不适合IGame这个接口了,他们没有办法即完成前段,又能完成后端,那么就可以讲IGame接口中的两个方法,写成两个接口,技术人员2就很合适IGameFrontEnd接口,技术人员3就很合适IGameBsckEnd接口。

 interface IGameFrontEnd
    {
        void WriteFrontEnd();
    }
    interface IGameBackEnd
    {
        void WriteBackEnd();
    }
  public class Technicist2 : MonoBehaviour, IGameFrontEnd
    {
        public void WriteFrontEnd()
        {
            Debug.Log("写前端");
        }
    }
    public class Technicist3 : MonoBehaviour, IGameBackEnd
    {
        public void WriteBackEnd()
        {
            Debug.Log("写后端");
        }
    }
如果是技术人员1要来做游戏,他就可以同时使用这两个接口了
 public class Technicist1 :MonoBehaviour, IGameFrontEnd, IGameBackEnd
    {
        public void WriteFrontEnd()
        {
            Debug.Log("写前端");
        }
        public void WriteBackEnd()
        {
            Debug.Log("写后端");
        }
    }

六,合成/聚合复用原则
定义:尽量使用对象组合,而不是继承来达到复用的目的。简而言之,要尽量使用合成和聚合,尽量不要使用继承。
合成:合成表示一种强的拥有关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样,打个比方:人有两个胳膊,胳膊和人就是部分和整体的关系,人去世了,那么 胳膊也就没用了,也就是说胳膊和人的生命周期是相同的
聚合:聚合表示一种弱的拥有关系,体现的是A对象可以包含B对象,但是B对象并不是A对象的一部分,打个比方:人是群居动物,所以每个人属于一个人群,一个人群可以有多个人,所以人群和人是聚合的关系
为什么尽量不要使用类继承而使用合成/聚合?

. 对象的继承关系在编译时就定义好了,所以无法在运行时改变从父类继承的子类的实现

. 子类的实现和它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化

. 当你复用子类的时候,如果继承下来的实现不适合解决新的问题,则父类必须重写或者被其它更适合的类所替换

这种依赖关系限制了灵活性,并最终限制了复用性

七,迪米特法则
定义:即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public 方法,不对外泄露任何信息
不和“陌生人”说话
只与你的直接朋友通信

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值