/// <returns>返回影响的行数</returns>
int Delete();
}
public interface Logger
{
/// <summary>
/// 写入日志信息
/// </summary>
/// <param name="message">写入信息</param>
/// <returns>返回影响的行数</returns>
int WriteLog(string message);
}
(2)、(OCP)开发封闭原则:简单来说就是不能修改现有的类,而需要在这个类的功能之上扩展新的功能,这时通过开放封闭原则来实现这样的要求。该原则使我
们不但能够拥抱变化,同时又不会修改现有的代码。而这个原则的实现可以简单来说就是我们将一系列发生变化的类的行为抽象为接口,然后让这些类去实现我们定义
的接口,调用者通过接口进行操作。例如我们以MP3播放器来说。
public interface IMP3
{
/// <summary>
/// 播放
/// </summary>
/// <returns>返回操作是否成功</returns>
bool Play();
/// <summary>
/// 停止
/// </summary>
/// <returns>返回操作是否成功</returns>
bool Stop();
}
定义2个不同的实现
/// <summary>
/// 台电播放器
/// </summary>
public class TD : IMP3
{
#region IMP3 成员
public bool Play()
{
return true;
}
public bool Stop()
{
return true;
}
#endregion
}
/// <summary>
/// 惠普播放器
/// </summary>
public class HP : IMP3
{
#region IMP3 成员
public bool Play()
{
return true;
}
public bool Stop()
{
return true;
}
#endregion
}
通过一个测试类来模拟接口调用,通过依赖注入的方式实现。
public class Test
{
IMP3 mp3 = null;
public Test(IMP3 mp)
{
mp3 = mp;
}
public bool Play()
{
return mp3.Play();
}
public bool Stop()
{
return mp3.Stop();
}
}
具体的测试代码我就不书写了,我想大家都知道了。
(3)、(LSP)替换原则:简单的来说就是基类出现的地方,扩展类都能够进行替换,那么前提就是我们不能修改基类的行为。也就是说基类与扩展类可以互相相
容。在面向对象中可能会认为很容易实现,不过我们要注意有时候我们从父类中继承的行为有可能因为子类的重写而发生变化,那么此时可能就不满足前面说的不改变
基类本身的行为。我们最熟悉的多态其实这样的情况就不满足这个原则。需要注意的时,对调用者来说基类与派生类并不相同,我们简单来说明。
public class Test
{
private int tempValue=0;
public void TestA()
{
tempValue = 2;
}
public virtual void TestB()
{
tempValue = 9;
}
}
public class Test1 : Test
{
public override void TestB()
{
//如果调用该方法,那么tempValue的值可以和基类中的得到的值是相同的,如果不显示的调用几类方法,那么这个值将丢失
//则不满足替换原则。
base.TestB();
}
}
通过上面的简单代码可知,里氏替换原则中需要注意的地方:当对具有virtual关键字和saled关键字的类或者方法需要特别注意,因为这些关键字会对继承类的
行为造成一定的影响,当然上面的例子中只是说了重写的情况,还有new的情况,就是把父类中的方法隐藏,同样都是不满足里氏替换原则的。本例中我们的
tempValue是私有类型的变量,那么在基类中可以访问到,派生类中却无法访问,所以我们要注意,在处基类替换时需要注意继承的成员函数的访问域,建议的方式是
虚方法访问的类的成员变量尽量使用保护类型,这样可以防止丢失的情况。当然基类中有虚方法访问了基类中定义的私有变量,那么如果在继承类中如果想不丢失该基
类中该虚方法对其内部的私有变量的访问,那么可以在继承类中通过“base.(函数名)”的形式来显示调用基类方法,可以保持基类的行为。
(4)、(DIP)依赖倒置原则:简单来说就是依赖于抽象而不应该依赖于实现,这样的目的就是降低耦合性。简单