Inverse Of Control(Dependency Injection) 学习总结

前言

最近在学习Silverlight的时候, 了解到概念”Inverse Of Control” 和 “Dependency Injection”, 但是很遗憾书中并没有进行详细的说明, 所以自己花了点时间
来弄懂这些概念和实际中的运用, 希望能和大家分享下。能力有限,希望指正。

内聚(Cohesion) 耦合(Coupling)

我们经常说到程序设计的规则是”高内聚,低耦合”, 那么什么是”高内聚”?什么又是”低耦合” 呢? 通过看了一些帖子和问题,自己总结了一下:

内聚(cohesion): 通常是指一个模块(或者是类)内部相互依赖的程度,通俗的来讲就是一个类功能的多少,如果这个模块干得事情越少,功能越单一,
内聚越高,即单一职责原则(Single Responsibility Principe)。
耦合(Coupling): 通常是指多个模块之间的相互依赖程度,如果模块间的依赖程度越低,那么耦合就小。

下面有两个个简单的例子具体来说明它们:

1. 耦合

假设我们需要完成一个购物车结算的功能,这里有三个类CartEntry,CartContents,Order。CartEntry用于记录购物车中某一样商品的价格和购买的数量,
CarContent用于记录购物车中所有CartEntry的集合,Order类实现结算的功能,下面是高耦合的代码:

public class CartEntry
{
public decimal Price { get; set; }
public int Quantity { get; set; }
}

public class CartContents
{
public CartEntry[] Items { get; set; }
}

public class Order
{
private CartContents cart;
private decimal salesTax;

public Order(CartContents cart, decimal salesTax)
{
this.cart = cart;
this.salesTax = salesTax;
}

public decimal OrderTotal()
{
decimal cartTotal = 0;
for (int i = 0; i < cart.Items.Length; i++)
{
cartTotal += cart.Items[i].Price * cart.Items[i].Quantity;
}
cartTotal += cartTotal * salesTax;
return cartTotal;
}
}

代码分析:注意Order类中的OrderTotal方法,它依赖于CartContents和CartEntry的具体实现而且它违背了单一职责原则,因为OrderTotal一共做了三件事情:

1. 对每一个CartEntry 总价的计算
2. 还对购物车进行了税前的结算
3. 计算了税后的结算

然后让我们试想下面两种情况:

1. 如果我们需要添加打折的功能,那么很有可能三个类都需要被修改
2. 如果将CartContents类中的数组类型改为ArrayList类型,那么OrderTotal方法也需要更改

下面给出比上面耦合度低的代码(并不是低耦合):

public class CartEntry
{
public decimal Price;
public int Quantity;

public decimal GetLineItemTotal()
{
return Price * Quantity;
}
}

public class CartContents
{
public CartEntry[] items;

public decimal GetCartItemsTotal()
{
decimal cartTotal = 0;
foreach (CartEntry item in items)
{
cartTotal += item.GetLineItemTotal();
}
return cartTotal;
}
}

public class Order
{
private CartContents cart;
private decimal salesTax;

public Order(CartContents cart, decimal salesTax)
{
this.cart = cart;
this.salesTax = salesTax;
}

public decimal OrderTotal()
{
return cart.GetCartItemsTotal() * (1.0f + salesTax);
}
}

代码分析:上面的代码满足了单一职责原则,它将之前的OrderTotal方法实现的功能进行了分解,CartEntry类中的GetLineItemTotal方法实现对每一项商品
总价的计算,CartContents类的GetCartItemsTotal方法对购物车的所有商品进行了税前的结算,Order类中的OrderTotal方法对购物车进行了税后的结算。而且OrderTotal方法
也不会因为CartContents 中集合类型的变化而修改代码,那么这样是正确的解耦方式了么? 答案是否定的,因为在Order 类中直接引用了CartContents类型,所以
Order类的实现还是依赖于CartContents类,试想一下如果商场到一个固定时间都会打折,比如说是6点之后都打九折,那么程序员可能直接修改GetLineItemTotal()方法
为GetLineItemTotal(int discount)进行实现那么调用他的Order类也需要修改。

posted on 2011-11-30 02:18  Dely  阅读(551)  评论(0编辑  收藏  举报

导航