游戏编程模式-设计模式01(基础)

tech2023-08-27  119

什么是好的架构

当你的代码需要改变时,仅需改变小部分代码就可以完成任务,架构的关键点就是应对改变

架构的关键目标:最小化你在编程前需要了解的信息。当软件不存在良好的架构时,你需要将几乎所有代码都浏览几遍来理解这个程序要做什么,而良好架构帮助你更好的分清你需要了解的部分,将你不需要了解的部分划分开

耦合

当两个功能是耦合在一起的,当你想要了解其中一个功能时,你同时也不得不了解另一个功能的代码。从编程后期来讲,耦合使你更改其中一个功能的代码时,不的不去更改另一个功能的代码,使修改代码的成本升高

好架构的代价

用了更多的时间花费在项目代码的管理上面,一个不留神的举措可能使整个架构都崩盘你需要“赌”你这个地方的代码在未来需要灵活性,如果他在未来都不需要做出改变,则会使项目总体的抽象和扩展增加,使项目更加复杂

所以你得控制平衡

为了在项目的整个生命周期保持其可读性,需要好的架构需要更好的运行时性能需要让现在想要的特性更快地实现

三个诉求都有冲突,就像你的程序想要使用更少的内存且拥有更快的速度一样,只能依照你的项目取其中的平衡点

引用大佬的建议和开发方法

建议:

抽象和解耦让扩展代码更快更容易,但除非确信需要灵活性,否则不要在这上面浪费时间。在整个开发周期中为性能考虑并做好设计,但是尽可能推迟那些底层的,基于假设的优化,那会锁死代码。快速地探索游戏的设计空间,但不要跑得太快,在身后留下烂摊子。毕竟你总得回来打扫。如果打算抛弃这段代码,就不要尝试将其写完美。最重要的是,如果你想要做出让人享受的东西,那就享受做它的过程。

开发方法:

让你的代码更简单,使用最直接的解决方案。 你读过这种代码后,完全理解了它在做什么,想不到其他完成的方法。

你的目标是正确获得数据结构和算法(大致是这样的先后),然后再从那里开始。 发现如果能让事物变得简单,最终的代码就更少, 就意味着改动时有更少的代码载入脑海。

代码通常跑的很快,因为没什么开销,也没什么代码需要执行。 (虽然大部分时候事实并非如此。你可以在一小段代码里加入大量的循环和递归。)

简单的代码并不意味着需要更少的时间编写。 你会这么觉得是因为最终得到了更少的代码,但是好的解决方案不是往代码中注水,而是精炼代码。

只需要很少的逻辑就可以覆盖整个用况。

什么是设计模式

设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案,及开发软件的通用模板。通过使用设计模式可以让代码结构更加清晰、可重用性可靠性更高、便于他人理解。

该理念最初由GOF(Gang of Four:四人帮)提出。包括三类(共23种):

创建型模式:提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活结构型模式:关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式行为型模式:特别关注对象之间的通信

ps:不要为了装b而使用设计模式

面向对象设计常用设计原则

单一职责原则

定义:一个类应该只有一个职责,否则类应该进行拆分。职责指发生变化的原因

    当一个类变化的原因过多,会导致多个改变类的状态(可以理解为类的属性)的职责累积到一个类中,使类的耦合度增强;当运行其中一个职责时可能导致另一个职责的运行发生错误;当需求更改时,更改类的一个功能不能影响到其他功能;将多个职责分到不同的类中,会使类的结构更加清晰,可读性更高

开-闭原则

定义:一个软件实体例如类、模块和函数应该对扩展开放,对修改关闭。

    当软件需要改变时,尽量让软件实体适合通过扩展的方式来更改,而不是通过更改现有的代码。开闭原则可以减少基类的粒度,使代码可重用性增加;可以提高软件的可维护性,在需要更改时只需要扩展代码,不用再去过多接触原来的代码了

里氏替换原则

定义1:所有引用基类的地方必须能透明地使用其子类的对象。 定义2:如果对每一个类型为 T1的对象O1,都有类型为 T2 的对象O2,使得以 T1定义的所有程序 P 在所有的对象 O1 都代换成 O2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。

该原则是实现开-闭原则的重要原则之一

含义:

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

依赖倒置原则

定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。这里抽象可以理解为抽象类或者接口,细节理解为实现类。即针对接口编程,而不是针对实现类

    类A依赖于类B,而需要将A改为依赖于类C,这里的A就是高层模块,B C为底层模块,要完成这种更改,必须修改类A,如果将类B和类C都改为依赖于某个接口或者抽象类,则A就不需要进行修改

编程建议:

低层模块尽量都要有抽象类或接口,或者两者都有变量的声明类型尽量是抽象类或接口使用继承时遵循里氏替换原则

接口隔离原则

定义:客户端不应该依赖它不需要的接口,类间的依赖关系应该建立在最小的接口上

    当一个接口过于庞大,有多个实现类依赖于改接口时,将不同实现类所依赖的方法分别创建单独的接口进行依赖,将接口进行分离,降低接口的耦合度

最少知识原则(迪米特法则)

定义:一个对象应该对其他对象保持最少的了解

    一个类应该对自己依赖的类知道的越少越好,尽量不让其他类以局部变量的形式进入自己类的内部,当多个类依赖多个类时,创建几个中间类对基类进行组合,使子类只依赖于一个类。这降低了类的耦合性

少用继承多用组合(合成复用)

定义:在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现,即将多将基类对象作为成员来使用而不去继承基类。如果使用继承,必须严格遵守里氏替换原则

参考: 游戏编程模式https://gpp.tkchu.me/architecture-performance-and-games.html 设计模式六大原则:https://blog.csdn.net/zhengzhb/article/details/7278174 程序员必备的七大面向对象设计原则:https://blog.csdn.net/Good_Luck_8/article/details/72901705

最新回复(0)