public class quicksort:isort
{
private icompare m_compare;
public quicksort(icompare compare)
{
m_compare= compare;
}
public void sort(ref object[] besorted)
{
//實現略
for (int i = 0; i < besorted.length - 1; i++)
{
if (m_compare.compare(besorted[i],besorted[i+1))
{
//略;
}
}
//實現略
}
}
最后的類圖如下:

通過對比較策略的封裝,以應對它的變化,顯然是stategy模式的設計。事實上,這里的排序算法也可能是變化的,例如實現二叉樹排序。由于我們已經引入了“面向接口編程”的思想,我們完全可以輕易的添加一個新的類binarytreesort,來實現isort接口。對于調用方而言,isort接口的實現,同樣是一個strategy模式。此時的類結構,完全是一個對擴展開發的狀態,它完全能夠適應類庫調用者新需求的變化。
再以petshop為例,在這個項目中涉及到訂單的管理,例如插入訂單。考慮到訪問量的關系,petshop為訂單管理提供了同步和異步的方式。顯然,在實際應用中只能使用這兩種方式的其中一種,并由具體的應用環境所決定。那么為了應對這樣一種可能會很頻繁的變化,我們仍然需要利用“封裝變化”的原理,建立抽象級別的對象,也就是iorderstrategy接口:
public interface iorderstrategy
{
void insert(petshop.model.orderinfo order);
}
然后定義兩個類ordersynchronous和orderasynchronous。類結構如下:

在petshop中,由于用戶隨時都可能會改變插入訂單的策略,因此對于業務層的訂單領域對象而言,不能與具體的訂單策略對象產生耦合關系。也就是說,在領域對象order類中,不能new一個具體的訂單策略對象,如下面的代碼:
iorderstrategy orderinsertstrategy = new ordersynchronous();
在martin fowler的文章《ioc容器和dependency injection模式》中,提出了解決這類問題的辦法,他稱之為依賴注入。不過由于petshop并沒有使用諸如sping.net等ioc容器,因此解決依賴問題,通常是利用配置文件結合反射來完成的。在領域對象order類中,是這樣實現的:
public class order
{
private static readonly iorderstategy orderinsertstrategy = loadinsertstrategy();
private static iorderstrategy loadinsertstrategy()
{
// look up which strategy to use from config file
string path = configurationmanager.appsettings["orderstrategyassembly"];
string classname = configurationmanager.appsettings["orderstrategyclass"];
// load the appropriate assembly and class
return (iorderstrategy)assembly.load(path).createinstance(classname);
}
}
在配置文件web.config中,配置如下的section:
<add key="orderstrategyassembly" value="petshop.bll"/>
<add key="orderstrategyclass" value="petshop.bll.ordersynchronous"/>
這其實是一種折中的service locator模式。將定位并創建依賴對象的邏輯直接放到對象中,在petshop的例子中,不失為一種好方法。畢竟在這個例子中,需要依賴注入的對象并不太多。但我們也可以認為是一種無奈的妥協的辦法,一旦這種依賴注入的邏輯增多,為給程序者帶來一定的麻煩,這時就需要一個專門的輕量級ioc容器了。
寫到這里,似乎已經脫離了“封裝變化”的主題。但事實上我們需要明白,利用抽象的方式封裝變化,固然是應對需求變化的王道,但它也僅僅能解除調用者與被調用者相對的耦合關系,只要還涉及到具體對象的創建,即使引入了工廠模式,但具體的工廠對象的創建仍然是必不可少的。那么,對于這樣一些業已被封裝變化的對象,我們還應該充分利用“依賴注入”的方式來徹底解除兩者之間的耦合。