ContinueBtn
BackMenuBtn
CampInfoUI
GamePause
GameStateInfoUI
SoldierInforUI
Rookie
Sergeant
Rifle
面向对象设计中常见的设计原则:
上述原则的作用:让自己设计实现出来的软件系统更加稳定,容易维护,并具有一致性
public context{}
开闭原则
1. 开闭原则定义 :一个软件实体应当对扩展开放,对修改关闭。也就是说在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,即实现在不修改源代码的情况下改变这个模块的行为。
2. 开闭原则分析:
(1)开闭原则由Bertrand Meyer于1988年提出,它是面向对象设计中最重要的原则之一。
(2)在开闭原则的定义中,软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类。
(3)抽象化是开闭原则的关键。
(4)开闭原则还可以通过一个更加具体的“对可变性封装原则”来描述,对可变性封装原则(Principle of Encapsulation of Variation,EVP)要求找到系统的可变因素并将其封装起来。
3. 开闭原则实例:
某图形界面系统提供了各种不同形状的按钮,客户端代码可针对这些按钮进行编程,用户可能会改变需求要求使用不同的按钮,原始设计方案如图所示:
现对该系统进行重构,使之满足开闭原则的要求。
对比分析
图(1):客户端的一个方法直接调用加法类,但是我想添加一个减法类,你就会发现添加减法类就得改变加法类中代码(用switch语句实现),这就违背了“开闭原则”,于是我们就应该重新重构。
图(2):在这个图中我们添加了一个运算类的父类,这样我们再添加减法类的时候就不用修改客户端类。
开闭原则总结:面对需求,对程序的改动是通过增加新代码进行的,而不是改变原来的代码。
依赖倒转原则
1.依赖倒转原则定义
2. 依赖倒转原则分析
3. 依赖倒转原则实例
某系统提供一个数据转换模块,可以将来自不同数据源的数据转换成多种格式,如可以转换来自数据库的数据(DatabaseSource)、也可以转换来自文本文件的数据(TextSource),转换后的格式可以是XML文件(XMLTransformer)、也可以是XLS文件(XLSTransformer
图一
图二
图(一)和图(二)分析:
图(一)为什么要到图(二)哪?因为该系统可能需要增加新的数据源或者新的文件格式,每增加一个新的类型的数据源或者新的类型的文件格式,客户类MainClass都需要修改源代码,以便使用新的类,但违背了开闭原则。现使用依赖倒转原则对其进行重构。
总结:高层模块不应该依赖底层模块,两个都应该依赖与抽象;抽象不应该依赖于细节,细节应该依赖于抽象。
里氏代换原则
1. 定义
2.分析
3. 实例
某系统需要实现对重要数据(如用户密码)的加密处理,在数据操作类(DataOperator)中需要调用加密类中定义的加密算法,系统提供了两个不同的加密类,CipherA和CipherB,它们实现不同的加密方法,在DataOperator中可以选择其中的一个实现加密操作。如图所示:
图一
图二
图(一)和图(二)分析:
图(一)为什到图(二)哪?因为如果需要更换一个加密算法类或者增加并使用一个新的加密算法类,如将CipherA改为CipherB,则需要修改客户类Client和数据操作类DataOperator的源代码,违背了开闭原则。现使用里氏代换原则对其进行重构,使得系统可以灵活扩展,符合开闭原则。
总结:子类型必须能够替换掉它们的父类型。
---------------------
单一职责原则
1. 定义
2. 分析
3. 实例
某基于Java的C/S系统的“登录功能”通过如下登录类(Login)实现:
图一
图二
图一和图二有什么区别哪?
图(一)功能太过于集成,严重违反类的单一原则。
五、接口隔离原则
1. 定义
2.分析
3.实例
下图展示了一个拥有多个客户类的系统,在系统中定义了一个巨大的接口(胖接口)AbstractService来服务所有的客户类。如图所示:
图一
图二
图(一)和图(二)分析:
图(一)为什么到图(二)哪?因为这样做既满足了接口隔离原则,又满足了单一原则,何乐而不为呢,但是也带来了很多的不便,类增多了。
总结:类应该完全依赖相应的专门的接口
---------------------
六、合成复用原则
1.定义
尽量使用对象组合,而不是继承来达到复用的目的。
2.分析
3. 实例
某教学管理系统部分数据库访问类设计如图所示:
图一
图二
图(一)和图(二)分析:
图(一)为什么到图(二)哪?因为如果需要更换数据库连接方式,如原来采用JDBC连接数据库,现在采用数据库连接池连接,则需要修改DBUtil类源代码。如果StudentDAO采用JDBC连接,但是TeacherDAO采用连接池连接,则需要增加一个新的DBUtil类,并修改StudentDAO或TeacherDAO的源代码,使之继承新的数据库连接类,这将违背开闭原则,系统扩展性较差。
总结:类中应用,尽量使用对象组合而不是用继承来达到复用的目的。
---------------------
七、迪米特法则
1. 定义
每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。
2. 分析
3. 实例
某系统界面类(如Form1、Form2等类)与数据访问类(如DAO1、DAO2等类)之间的调用关系较为复杂。如图所示:
图一
图二
图(一)和图(二)分析:
图(一)为什么到图(二)哪?因为这样就可以降低类的耦合性,是类中功能更加单一,相当于外观模式。
总结:一个软件实体应当尽可能少的与其他实体发生相互作用
---------------------
综述:以上就是其中程序员必备的七大面向对象设计原则,原则犹如国家的法规,这就是面向对象的准则,要使我们的编程更加灵活,封装性更好,复用性更高,易于维护我们需要我们的这些原则建设我们规范我们的程序。这样我们编写的才是高质量的程序。我们每个人都这样去做,我们的编程水平一定会进步一大截!
useing System.Collections;
useing System.Collections.Generic;
useing UnityEngine;
public class DM01State:MonoBeheaviour
{
void start()
{
Conetext context=new Conetext();
context.SetState(new ConcreteStateA(context));
/*
context.Handle(5);
context.Handle(20);
context.Handle(2);
context.Handle(10);
*/
}
}
public class Conetext
{
private IState mState;
public void SetState(IState state)
{
mState=state;
}
public void Handle(int arg)
{
mState.Handle(arg);
}
}
public interface IState
{
void Handle(int arg);
}
public class ConcreteStateA:IState
{
public void Handle(int arg)
{
private Conetxt mContext;
public ConcreteStateA(Conetext context)
{
mContext=context;
}
Debug.Log("ConcreteStateA.Handle"+arg)
if(arg>10)
{
mContext.SetState(new ConcreteStateB(context))
}
}
}
public class ConcreteStateB:IState
{
public void Handle(int arg)
{
private Conetxt mContext;
public ConcreteStateA(Conetext context)
{
mContext=context;
}
Debug.Log("ConcreteStateA.Handle"+arg)
if(arg<=10)
{
mContext.SetState(new ConcreteStateA(context))
}
}
}
依赖倒转原则(针对接口编程)
1.细节依赖于抽象
2.底层依赖于高层
3.实现与高层交互
1.里氏替换原则和单一职责原则
1.游戏脚本和游戏对象组件分离开发
SoldierAttackState
SoldierChaseState
SoldierIdleState
设计原则
单一职责
开闭原则
对扩展开放
对修改关闭
依赖倒转原则
高层模块不依赖底层模块,都依赖于接口
抽象不依赖于细节,细节依赖于抽象
针对接口编程,不针对实现编程
里氏替换原则
实现 开闭原则的方式之一
单一职责
只有一个引起它变化的原因
接口隔离原则
合成复用原则
迪米特原则