标签:组合 数据库 change 迭代 user XML 填充 事件 存在
即不能存在多于一个导致类变更的原因。简单的说就是一个类只负责一项职责。
让一个类仅负责一项职责,如果一个类有多于一项的职责,这是比较脆弱的设计。因为一旦某一项职责发生了改变,需要去更改代码,那么有可能会引起其他职责改变。所谓牵一发而动全身,这显然是我们所不愿意看到的,所以我们会把这个类分拆开来,由两个类来分别维护这两个职责,这样当一个职责发生改变,需要修改时,不会影响到另一个职责。
public class CommonUtil
{
#region Canvas Helpers
public void M1() { }
//...
#endregion
#region Screen Helpers
public void M2() { }
//...
#endregion
#region Size Helpers
public void M3() { }
//...
#endregion
#region Data Helpers
public void M4() { }
//...
#endregion
}
各位,你觉得这个类写的怎么样?
软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。
这条原则是所有面向对象原则的核心。
public class Component
{
public enum Status
{
None,
Installed,
Uninstalled
}
Status m_status = Status.None;
void Do()
{
switch (m_status)
{
case Status.None:
Console.WriteLine("Error...");
break;
case Status.Installed:
Console.WriteLine("Hello!");
break;
case Status.Uninstalled:
Console.WriteLine("Error...");
break;
default:
break;
}
}
}
我们这里定义了一个组件,用户动态加载,加载完了以后程序就可以用了,为了处理方便,我们给组件定义了一些状态,在不同的状态下,这个组件有不同的行为,于是就有了上面的代码:enum定义状态,函数中使用switch实现路由。
public class ComponentStaus
{
public virtual void Do() { }
}
public class ComponentNone : ComponentStaus
{
public override void Do() { Console.WriteLine("Error..."); }
}
public class ComponentInitialized : ComponentStaus
{
public virtual void Do() { Console.WriteLine("Hello!"); }
}
public class Component
{
ComponentStaus m_status = new ComponentNone();
public void ChangeStatus(ComponentStaus newStatus)
{
m_status = newStatus;
}
public void Do()
{
m_status.Do();
}
}
在上面的例子中,我们发现了变化点,然后抽象出一个基类放在那,然后使用继承机制,让子类去演绎变化。当我们需要添加新的状态Configured的时候,我们只要添加一个新的子类ComponentConfigured,让它从ComponentStaus继承,并重写Do方法即可。使用的时候,在合适的时机(如事件处理中)把该子类的实例传给Component就可以了,当然也有可能是Component自己处理事件或方法时自己修改该状态实例。
任何基类可以出现的地方,子类一定可以出现。
LSP原则是继承复用的基石,只有当派生类可以替换掉基类,软件的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。
public class Program
{
static void Main(string[] args)
{
Rectangle rect = new Rectangle();
rect.setWidth(100);
rect.setHeight(20);
Console.WriteLine(rect.Area == 100 * 20);
Rectangle squ = new Square();
rect.setWidth(100);
rect.setHeight(20);
Console.WriteLine(squ.Area == 100 * 20);
}
}
class Rectangle
{
public double m_width;
public double m_height;
public virtual void setWidth(double width) { m_width = width; }
public virtual void setHeight(double height) { m_height = height; }
public double Area
{
get { return m_width * m_height; }
}
}
class Square : Rectangle
{
public override void setWidth(double width)
{
m_width = width;
m_height = width;
}
public override void setHeight(double height)
{
m_width = height;
m_height = height;
}
}
很显然输入的不是两个True,根本原因就在于正方形只有长的概念,而没有长方形所期望的宽的概念,所以长方形中定义了正方形根本没有的东西,也就是说长方形不应该是正方形的基类。
不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一的总接口总要好。
这一原则与单一职责原则息息相关,它们对于高内聚的追求是一致的,但是它更加强调了接口的高内聚性。
interface IService
{
void GetUser();
void RegisterUser();
void LoadProducts();
void AddProduct();
void AcceptRequest();
void SendResponse();
}
因为是面向所有Client的,所以这个接口提供了所有Client需要的方法,比如用户的操纵,产品的操作,数据传输的一些操作,每个Client都可能用到其中的一部分服务。
interface IUser
{
void GetUser();
void RegisterUser();
}
interface IProduct
{
void LoadProducts();
void AddProduct();
}
interface IPeer
{
void AcceptRequest();
void SendResponse();
}
class Service : IUser, IProduct, IPeer {}
这样拿到代理对象后,想处理用户的Client,将该对象转换成IUser即可,想处理产品的转换成IProduct即可。
1、高层模块不应该依赖低层模块,两者都应该依赖于抽象(抽象类或接口) 2、抽象(抽象类或接口)不应该依赖于细节(具体实现类) 3、细节(具体实现类)应该依赖抽象
总结起来,这个原则说的就是每个类与别的类交互时,尽量只使用满足接口规范的抽象类。为啥?因为抽象类实现细节几乎没有,没什么需要变化的。这一条深刻揭示了抽象的生命力,抽象的对象才是最有表达能力的对象,因为它通常是“无形”的,可以随时填充相关的细节。
public class Program
{
static void Main(string[] args)
{
UI layer = new UI();
layer.SetDataAccessor(new XmlDataAccessor());
layer.Do();
}
}
class UI
{
DataAccessor m_accessor;
public void SetDataAccessor(DataAccessor accessor) { m_accessor = accessor; }
public void Do()
{
m_accessor.GetUser();
}
}
interface DataAccessor
{
void GetUser();
void RegisterUser();
}
class XmlDataAccessor : DataAccessor
{
public void GetUser() { }
public void RegisterUser() { }
}
这里上游的组件UI依赖的是DataAccessor这样的接口,而不是依赖各种具体的子类,如XmlDataAccessor,这样当想使用其他的数据库存储数据的时候,只要增加新的DatabaseDataAccessor之类的新类,然后在设置的时候设置一下就可以了。这种手段,很多人也称为"依赖注入"。
标签:组合 数据库 change 迭代 user XML 填充 事件 存在
原文地址:http://www.cnblogs.com/chenxibobo/p/6092854.html