日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.Net 应用框架设计系列(二)

發布時間:2024/6/14 asp.net 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .Net 应用框架设计系列(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是一個好的設計?我想要做一個好的設計,有這么幾個挑戰。

1。對象的職責的定義和劃分

2。可擴展性

3。可重用性

1.?明確定義和劃分對象的職責。也就是說一個class,他應該專注于做很少的功能,而不是面面具到,無所不能。通過class的名稱和方法,我們可以很清楚這個class到底提供什么樣的功能和職責。說起來很簡單,可是實際做起來,還是很困難的。

2.?可擴展性。我的設計如何才可以做到,在需求發生變化后,在新的組件和服務產生后,我可以在不改動原有設計而把新的東西集成進來。在我替換和修改了已有組件的實現后,依賴他的上層的代碼不需要做任何的改動。

3.?可重用性。對象之間的依賴關系復雜。如和在一個新的項目里重用以前已經實現的class,在我們現在的開發過程里,通常都是一個復雜的過程。

?

如果解決這三個難題呢。我認為,IOC為我們提供了解決這3個難題的途徑。

IOC,英文是Inversion of Control,中文翻譯為“控制反轉”。用于對調用和被調用者之間進行解耦。

首先我們從解耦這個方面來討論。

對組件之間的關系進行解耦,通常我們需要處理的情況有2種:1。獲取外部的配置信息 2。獲取一個組件對象的引用。舉個例子來說明一下:

using?System;
using?System.Configuration;

public?class?MyAwfulEmailClass
{
??
public?MyAwfulEmailClass()
??
{
??}

??
??
public?void?SendEmail(?String?from,?String?to,?String?message,?String?templateName?)
??
{
????String?host?
=?ConfigurationSettings.AppSettings["smtphost"];
????
int?port?=?Convert.ToInt(?ConfigurationSettings.AppSettings["smtpport"]?);

????NVelocityTemplateEngine?engine?
=?new?NVelocityTemplateEngine();
????String?newMessage?
=?engine.Process(?message,?templateName?);

????
//?Finally?send?message
??}

}

這是一個很簡單的類,只有寥寥數行的代碼。也許我們在自己的開發過程中,會經常看到類似的代碼。可是就這寥寥數行代碼里面,仍然有一些問題存在。

1.?代碼里是通過ConfigurationSettings來獲得配置信息。如果我們變更Configuration的存儲形式,或者用其他的xml文件存儲,或者是存儲在數據庫,或者是從遠端的webservice里獲得配置信息,代碼就不得不做出修改,重新編譯。

2.?class所擔負的職責要比他的名字所描述的要多。這個類提供發送郵件的功能,但是,不僅僅與此,這個類還會調用一個template 引擎對郵件的文本進行處理。由此帶來的另外一個問題就是,這個類必須具備對這個template 引擎的知識,知道如何調用這個引擎的方法。

這樣的2個主要問題帶來的影響就是,給這個類增加了兩個比較強的依賴關系。就是對外部config模塊和郵件template 引擎的依賴。也許有人會覺得,這沒有什么問題呀,我們平時寫代碼也是這樣的,沒有什么不好呀。可是仔細考慮一下,如果需求變動,config部分變更,配置的Key發生變化,或者配置從另外的xml獲取,或者配置從Database獲取,或者配置是從一個webService獲取,那么上面的這段代碼無疑就要進行修改。如果這樣的地方多了,那修改起來既容易錯,又容易發生漏改。再說template引擎,如果我們換了另外一個模板引擎,我們也需要類似的做修改。

從另外一個角度說,如果我們又有了一個類似的項目,里面也有發郵件的功能。通常,最快的方法就是把這些代碼copy過來,做少量的修改。但是,這個并不是一個好的,高效的做飯。同時,代碼的維護也變得多出了一倍。這里,又引入了一個我們在框架設計是的一個思想,就是組件化,服務化。而IOC容器就提供了一種手段和工具來幫助我們管理這些組件和服務。

?

什么是組件呢?我個人認為,組件就是一小段可重用的代碼單元。對外部,他應該提供一個職責明確的服務接口,也就是說,這個組件只處理他職責范圍內的事情,并且要處理得很好。通常來說,一個組件就是一個Class,實現了一個Service,也就是實現了一個interface。而這個interface就為我們引入了一個抽象層,把接口服務和實現分開。即我們常說的面向接口的開發。

再回到剛才的例子。

我們先定義Emailservice

//?The?contract
public?interface?IEmailSender
{
??
void?Send(String?from,?String?to,?String?message)
}

這個接口描述了發送Email這個Service的契約,只要實現了這個契約所規定的,不管是用smtp,還是IMAP或者其他的什么的,我們都認為是合法的。

OK,接下來我們給契約增加一個實現,使用smpt來訪發送郵件。

//?The?implementation
public?class?SmtpEmailSender?:?IEmailSender
{
??
private?String?_host;
??
private?int?_port;

??
public?SmtpEmailSender(String?host,?int?port)
??
{
????_host?
=?host;
????_port?
=?port;
??}


??
public?void?Send(String?from,?String?to,?String?message)
??
{
????
//?Configures?the?Smtp?class?and?sends?the?e-mail
??}

}

看起來,是不是感覺這樣做好了一些。現在這個類就只負責把郵件發送出去,并不負責對郵件的文本進行模板處理。

OK,我們再定義一個郵件Template的接口:

public?interface?ITemplateEngine
{
??String?Process(String?templateName)
}
光這樣一個ITemplateEngine還不夠,我們還需要一個組件來負責執行模板轉換和分發郵件的功能。
public?interface?INewsletterService
{
??
void?Dispatch(String?from,?String[]?targets,?String?messageTypeName)
}

OK,現在讓我們來考慮一下INewsletterService接口服務應該如何實現。很顯然,需要使用IEmailSender 服務 ITemplateEngine 服務,而不用關系IEmailSenderITemplateEngine的具體實現是如何。

public?class?SimpleNewsletterService?:?INewsletterService
{
??
private?IEmailSender?_sender;
??
private?ITemplateEngine?_templateEngine;
??
??
public?SimpleNewsletterService(IEmailSender?sender,?
??????????????????????ITemplateEngine?templateEngine)
??
{
????_sender?
=?sender;
????_templateEngine?
=?templateEngine;
??}


??
public?void?Dispatch(String?from,?String[]?targets,?String?messageTypeName)
??
{
????String?message?
=?_templateEngine.Process(messageTypeName);

????
foreach(String?target?in?targets)
????
{
??????_sender.Send(from,?target,?message);
????}

??}

}

現在看上去,是不是感覺好了很多。通過設計上的重構,良好定義對象的職責,這段代碼已經變得比以前更加靈活和易于擴展了。但是,仍然有個問題存在。我們需要自己把所有有關的東西聯系起來,包括IEmailSender, ITemplateEngine, 然后把他們傳遞到INewsletterService

這些我們是可以手工通過代碼來完成,但是,借助于IOC容器,我們可以使用另外一種方式來完成同樣的功能。

接下來,我以.net下的開源IOC框架Castle為例子來說明IOC容器的神奇之處。

下面這段代碼,就可以完成我們上面的功能

IWindsorContainer?container?=?new?WindsorContainer();
container.AddComponent(?
"newsletter",?typeof(INewsletterService),?
????????????????????????
typeof(SimpleNewsletterService)?);
container.AddComponent(?
"smtpemailsender",?typeof(IEmailSender),?
????????????????????????
typeof(SmtpEmailSender)?);
container.AddComponent(?
"templateengine",?typeof(ITemplateEngine),?
????????????????????????
typeof(NVelocityTemplateEngine)?);

//?Ok,?start?the?show
INewsletterService?service?=?(INewsletterService)?container["newsletter"];
service.Dispatch(
"hammett?at?gmail?dot?com",?friendsList,?"merryxmas");

OK,讓我來解釋一下,上面的這段代碼里到底是如何發揮這神奇功效的。

1.???? 首先,在容器里注冊INewsletterService 服務,并指定服務的實現是SimpleNewsletterService,服務在容器內的索引Keynewsletter

2.???? 在容器里注冊IEmailSender服務,并指定IEmailSender的實現是SmtpEmailSender,服務在容器內的索引Keysmtpemailsender。容器會檢查SmtpEmailSender類,發現他只有一個帶參數的構造函數SmtpEmailSender(String host, int port),而hostport目前還無法獲得,這個我們在后面會對SmtpEmailSender修改一下,來修正這個問題。

3.???? 在容器里注冊ITemplateEngine服務,并指定ITemplateEngine的實現是NVelocityTemplateEngine,服務在容器內的索引Keytemplateengine

4.???? 容器檢測SimpleNewsletterService,發現他的構造函數需要IEmailSenderITemplateEngine,容器會先創建 IEmailSenderITemplateEngine的實例,然后再創建出SimpleNewsletterService實例。

首先我們修改SmtpEmailSender的實現,以適應容器。

public?class?SmtpEmailSender?:?IEmailSender
{
??
private?String?_host;
??
private?int?_port;

??
public?SmtpEmailSender()
??
{
????_host?
=?"mydefaulthost";
????_port?
=?110;?//?default?port
??}


??
public?String?Host
??
{
????
get?{?return?_host;?}
????
set?{?_host?=?value;?}
??}

??
??
public?int?Port
??
{
????
get?{?return?_port;?}
????
set?{?_port?=?value;?}
??}


??
//
}

如上所示,我們提供了一個無參數的構造函數,并且提供了兩個屬性HostPort。這樣容器可以創建一個SmtpEmailSender,并且通過讀取配置,來設置HostPort

一個簡單的配置文件的例子如下:

<?xml?version="1.0"?encoding="utf-8"??>??

<configuration>?

????
<configSections>

????????
<section?name="castle"

??????????type
="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,?

????????????????Castle.Windsor"
?/>

????
</configSections>

?

????
<castle>

????????
<components>

????????????
<component?id="smtpemailsender">

????????????????
<parameters>

????????????????????
<host>localhost</host>

????????????????????
<port>110</port>

????????????????
</parameters>

????????????
</component>

????????
</components>

????
</castle>?

</configuration>

這樣,容器替我們完成了創建組件的任務。容器可以檢測容器內的組件的相互依賴性,并且可以通過外部的配置文件來配置容器的實現,設置其屬性。

本質上來說,容器幫我們把組件之前的耦合性轉移到容器外的配置文件里。但是組件之間的依賴性是通過接口來弱化的,就只是一個松耦合的關系。

當然,容器的作用不僅僅與此,我們還可以為同一個服務指定多個實現,通過配置,可以指定被依賴的服務采用何種實現,可以為指定的組件定制自己ComponentActivator來控制其創建過程。還可以通過動態代理的方式,完成一些面向方面的特殊功能。

總之,IOC容器是非常強大的工具,是我們框架的基礎與核心,為框架的可擴充提供了必備的條件

轉載于:https://www.cnblogs.com/BlogNetSpace/archive/2012/03/20/1334174.html

總結

以上是生活随笔為你收集整理的.Net 应用框架设计系列(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。