多情况下,在设计初期我们类之间的关系不是很明确,LSP则给了我们一个判断和设计类之间关系的基准:需不需 要继承,以及怎样设计继承关系。 当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有is-A关系。继承对于OCP,就相当于多态性对于里氏替换原则。子类可以代替基类,客户使用基类,他们不需要知道派生类所做的事情。这是一个针对行为职责可替代的原则,如果S是T的子类型,那么S对象就应该在不改变任何抽象属性情况下替换所有T对象。
class Rectangle
{
protected int width = 0;
protected int height = 0;
public virtual void SetWidth(int width)
{
this.width = width;
}
public virtual void SetHeight(int height)
{
this.height = height;
}
public virtual int GetArea()
{
return this.width * this.height;
}
}
class Square : Rectangle
{
public override void SetHeight(int height)
{
this.height = height;
this.width = height;
}
public override void SetWidth(int width)
{
this.height = width;
this.width = width;
}
}
[I] Interface Segregation Principle(接口隔离原则)
接口隔离原则 :接口隔离原则 认为“多个特定客户端接口要好于一个宽泛用途的接口”的概念。
不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一的总接口总要好。注意:在代码中应用ISP并不一定意味着服务就是绝对安全的。仍然需要采用良好的编码实践,以确保正确的验证与授权。 这个原则起源于施乐公司,他们需要建立了一个新的打印机系统,可以执行诸如装订的印刷品一套,传真多种任务。此系统软件创建从底层开始编制,并实现了这些 任务功能,但是不断增长的软件功能却使软件本身越来越难适应变化和维护。每一次改变,即使是最小的变化,有人可能需要近一个小时的重新编译和重新部署。这 是几乎不可能再继续发展,所以他们聘请罗伯特Robert帮助他们。他们首先设计了一个主要类Job,几乎能够用于实现所有任务功能。只要调用Job类的 一个方法就可以实现一个功能,Job类就变动非常大,是一个胖模型啊,对于客户端如果只需要一个打印功能,但是其他无关打印的方法功能也和其耦合,ISP 原则建议在客户端和Job类之间增加一个接口层,对于不同功能有不同接口,比如打印功能就是Print接口,然后将大的Job类切分为继承不同接口的子 类,这样有一个Print Job类,等等。
interface IDataAccess
{
void OpenConnection();
void CloseConnection();
}
interface ISqlDataAccess : IDataAccess
{
void ExecuteSqlCommand();
}
interface IOracleDataAccess : IDataAccess
{
void ExecuteOracleCommand();
}
class SqlDataAccess : ISqlDataAccess
{
/// <summary>
/// 执行Sql数据命令
/// </summary>
public void ExecuteSqlCommand(){}
/// <summary>
/// 打开Sql数据连接
/// </summary>
public void OpenConnection(){}
/// <summary>
/// 关闭Sql数据连接
/// </summary>
public void CloseConnection(){}
}
class OracleDataAccess : IOracleDataAccess
{
/// <summary>
/// 执行Oracle数据命令
/// </summary>
public void ExecuteOracleCommand(){}
/// <summary>
/// 打开Oracle数据连接
/// </summary>
public void OpenConnection(){}
/// <summary>
/// 关闭Oracle数据连接
/// </summary>
public void CloseConnection(){}
}
[D] Dependency Inversion Principle(依赖反转原则)
依赖反转原则: 依赖反转原则 认为一个方法应该遵从“依赖于抽象而不是一个实例” 的概念。依赖注入是该原则的一种实现方式。
依赖倒置原则(Dependency Inversion Principle,DIP)规定:代码应当取决于抽象概念,而不是具体实现。 高层模块不应该依赖于低层模块,二者都应该依赖于抽象 抽象不应该依赖于细节,细节应该依赖于抽象 类可能依赖于其他类来执行其工作。但是,它们不应当依赖于该类的特定具体实现,而应当是它的抽象。这个原则实在是太重要了,社会的分工化,标准化都 是这个设计原则的体现。显然,这一概念会大大提高系统的灵活性。如果类只关心它们用于支持特定契约而不是特定类型的组件,就可以快速而轻松地修改这些低级 服务的功能,同时最大限度地降低对系统其余部分的影响。
interface IBankAccount
{
long BankNumber { get; set; } // 卡号
decimal Balance { get; set; } // 余额
}
// 转账人
inter |