更新中

软件设计的原则

先学习软件设计的基本原则,虽说笔者主攻方向为基于 Unity 引擎的游戏开发,但是游戏开发与软件开发有许多共通处,学习游戏设计模式可以为后续开发与工具的学习运用打下坚实的基础

开闭原则(OCP)

软件设计的基本原则,后续六个原则的最终目的都是为了满足开闭原则
解释:对扩展开放,对修改封闭。就是说编写软件框架时,要多扩展,少修改。
实现的例子:面向接口编程
比如有限状态机(状态模式的最常见的实现)的实现,对于状态,我们一般都是先定义状态接口

1
2
3
4
5
6
7
8
public interface IState{
void Enter();

void Update();

void Exit();
...
}

然后再编写的状态管理器StateManager,后续的状态机使用只需要实现状态接口并创建状体管理器实例,就可以正确运行。

优点:提高代码健壮性,易维护和扩展
缺点:往往会增加代码量和阅读难度


单一职责原则(SRP)

解释:每个类或者方法只负责干一件或一类事情,不要节外生枝负责过多的事务。
实现的例子:并不固定,更多的是一种思想,比如Unity中游戏实体的移动,可能会创建一个MoveComponent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MoveComponent : MonoBehavear {

//references
...

private float _speed
...

public void Move(Vector2 moveDir){}

public void Stop(){}

public void SetSpeed(){}
}

需要移动功能时,直接获取该组件,调用方法。如果移动逻辑出现问题,只需要修改该组件的代码。

优点:高内聚,逻辑独立,便于维护
缺点:增加代码量;可能导致功能颗粒度太小,增加使用复杂度。


里氏替换原则(LSP)

解释:是对于继承的使用规范,要求我们使用继承时,对于父类的方法尽量不要修改而是采用扩展新的方法来达到扩展功能的目的。
继承设计的目的是提取类中相同的部分,构成父类,这种统一性其实指的是行为的一致性,也就是说继承可以在多个类中包含相同行为时,为了简化使用,编写通用代码的目的而使用。而行为的一致性又取决于项目需求。实际使用时要灵活变通。
实现:这里主要是展示一下如何遵守规范。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//鸟类基类
public class Bird{
void Fly(){

}
}

//错误继承
public class Ostrich : Bird{

}

//正确继承
public class Yanzi : Bird{

}

在上面的例子中,对于Fly方法,鸵鸟由于不能飞,对于飞行的实现,就只能采取空实现或者其他不符合飞行行为的实现,此时当外部使用者使用该实现类时,使用该方法得到的结果可能就是错误的。当然这种例子很单薄,我们都知道鸵鸟不可以飞。

优点:实现开闭原则;有利于增加系统的健壮性
缺点:有时需要针对需求判断继承是否合理


依赖倒置原则(DIP)


接口隔离原则(ISP)


迪米特法则(LOD)


合成/聚合复用原则(CARP)