如果你是學(xué)生,最好先到畢業(yè)生之歌看一下幾個基本概念.
http://www.cnblogs.com/QPG2006/articles/246105.html 如果你已經(jīng)對Castle有一定了解,可以參看: http://www.cnblogs.com/QPG2006/articles/245667.html 或者直接看下文: 靜靜的夜晚并非一切都已睡去…… QPG希望借助大家已有的成果,,來達到快速開發(fā)高質(zhì)量軟件的目的。當(dāng)然我們也不相信有銀彈存在,,因為軟件開發(fā)中最困難的是要面對人的無形的期望,,而將說不清楚的事情表達出來,也許才是軟件開發(fā)的真正困難所在,。尤其是在什么所謂的管理系統(tǒng)上,,也許沒有多少人能看到目標前就已經(jīng)耗盡了體力! 廢話少說,,那么QPG平臺到底為程序員提供了什么呢,?回答是QPG不是包羅萬象的框架,他借助castle的IoC\AOP,、log4net,、NHibernate等提供的強大功能來幫助程序員簡化開發(fā)任務(wù)。QPG本身提供了端到端的服務(wù)負載均衡,,任何程序在這個世界里都可以提供服務(wù),,當(dāng)然也可以消費服務(wù)!當(dāng)然這肯定對某些人來說還不夠,,隨著今后的需求增加,,我們會再集成一些輕量級的有用組件。 下面以一個簡單的例子來介紹QPG平臺的基本功能:正確高效使用組件,、日志,、加密壓縮。
首先請下載開發(fā)演示文件,,把它解壓到一個目錄,,你可以看到如下的Basic項目。 們編寫了一個產(chǎn)品組件,,還有一個銷售管理組件,。不過那個組件會在今后的AOP里再演示了?,F(xiàn)看看產(chǎn)品組件,,是否很簡單: namespace QPG.Demo.Components { using System; public class Product { private int _price; private int _stocks; private string _name; public Product() { _name=""; _price=0; _stocks=0; Console.WriteLine("call Product()");//用來查看容器是否自動初始化對象 } public Product(string name,int price,int num) { _name=name; _price=price; _stocks=num; Console.WriteLine(string.Format("Product({0},{1},{2})",name,price,num)); } public virtual string Name{ get{return _name;} } public virtual int Price{ get{return _price;} } public virtual int Stocks{ get{return _stocks;} } public virtual void setPrice(int newPrice) { _price=newPrice; } public virtual void outStock(int num) { int temp=_stocks-num; if(temp<0) throw new Exception("stock lack!"); _stocks=temp; } } } 打開bin\Debug\config\app_config.xml,這個文件用來配置您自己編寫的組件。本例中的配置如下: <?xml version="1.0" encoding="utf-8" ?>
<configuration> <components> <component id="p1" type="QPG.Demo.Components.Product,Basic" lifestyle="Singleton" > <parameters> <name>P1</name> <price>333</price> <num>33</num> </parameters> </component> <component id="p2" type="QPG.Demo.Components.Product,Basic" lifestyle="Pooled" initialPoolSize="2" maxPoolSize="4" /> <component id="p3" type="QPG.Demo.Components.Product,Basic" lifestyle="Transient" /> </components> </configuration> 我們配置了三個Product對象: p1就只會存在一個,,并且不會被容器釋放,; p2會存在至少兩個實例,當(dāng)內(nèi)存池不夠時容器會創(chuàng)建時新的并且加入到實例池,但是最多只有4個,。是否比較難理解,?我們拿孫悟空為例,雖然可以變出許多猴子,,但是都是他的替身罷了,。 p 3則總是新人,但愿談戀愛的弟弟妹妹不要這樣:-) 看看我們的測試片斷: [TestFixture]
public class LisfCycleTester { private SimpleContainer container; [SetUp] public void Init() { Hashtable ht=new Hashtable(); //ht.Add("qpg.email_sender",typeof(EmailSender)); container = new SimpleContainer(ht); } [TearDown] public void Finish() { container.Dispose(); } private void visitProduct(string key,int num) { Product p; ArrayList ps=new ArrayList(); int i; for( i=0;i<num;i++) { p=container[key] as Product; Console.WriteLine("{0}--{1}",i+1,p.Price); p.setPrice((i+1)*10);//看看是否實用了新對象 ps.Add(p); } for(i=0;i<ps.Count;i++) { container.Release(ps[i]); } ps.Clear(); } private void visitPooledProduct(string key,int num) { Product p; int i; for( i=0;i<num;i++) { p=container[key] as Product; Console.WriteLine("{0}--{1}",i+1,p.Price); p.setPrice((i+1)*10); container.Release(p); } } private void runTest(string key) { long t1=System.Environment.TickCount; visitProduct(key,4); if(key!="p2") visitProduct(key,10000); else visitPooledProduct(key,10000); long t2=System.Environment.TickCount-t1; Console.WriteLine("{0}ms",t2); } [Test] public void tesSingleton() { runTest("p1"); } [Test] public void testPool() { runTest("p2"); } [Test] public void testMany() { runTest("p3"); } 讓我們來看看執(zhí)行的結(jié)果如何吧: 先運行tesSingleton
call Product() call Product() Product(P1,333,33) 1--333 2—10 //哈哈:第二次使用的還是那個對象,,我們在前次給他的價格已經(jīng)設(shè)置為10元了 3--20 4--30 1--40 2--10 3—20 ,。。,。,。。,。 您可以看到系統(tǒng)先產(chǎn)生了2個Product,,那是因為p2最少有兩個,平臺已經(jīng)知道我們的期望,,自動幫我們做了,! P1只被產(chǎn)生一次:Product(P1,333,33),這些初始值就是我們在配置文件里寫的,,不是嗎,?
在我的機器上運行10004次訪問花費了1610ms
再看看testPool() call Product() 1--0 2--0 call Product() 3--0 call Product() 4--0 1--40 2--10 3--20 4--30 5--40 6--50 7--60 8--70 9--80 。,。,。。,。,。 您可以看到雖然系統(tǒng)先產(chǎn)生了2個Product,但是在訪問并且不釋放情況下第三,、四次訪問時,,系統(tǒng)調(diào)用了缺省構(gòu)造函數(shù)來產(chǎn)生一個新的實例。以后使用訪問并釋放的方法,,這四個實例滿足了我們一萬次的訪問,。在我的機器上,這個TestCase用了1687ms,,也證明盡管有緩存,,但是畢竟構(gòu)造兩次也花了些時間。所以沒有Singleton快,。
最后再看看每次都來個新的: call Product() call Product() call Product() 1--0 call Product() 2--0 call Product() 3--0 call Product() 4--0 call Product() 1--0 call Product() 2--0 call Product() 3--0 call Product() 4--0 call Product() ,。,。。,。,。。 您可以看到確是每次都會產(chǎn)生新的,,這樣肯定最慢了,,在我機器上用了4031ms。
測試程序里還演示了兩個常用的功能,,寫日志和加密壓縮,。演示結(jié)果您可以在LOG\下發(fā)現(xiàn)一個log.txt,打開看看應(yīng)該如下: [DEBUG][2005-09-27 21:23:09,484]--hello world! SO SIMPLE!
是否太過簡單?如果您了解log4net ,您可以配置成您想要的日志方式,,比如寫系統(tǒng)日志,、謝數(shù)據(jù)庫、遠程對象,、UDP廣播等,。
在看看加密壓縮吧: Zip:UEsDBBQAAAAIAEi0OzMnz+xKCgAAAAgAAAAHAAAARFRPLnhtbAsMcNcrSS0uAQBQSwECFAAUAAgACABItDszJ8/sSgoAAAAIAAAABwAAAAAAAAAAAAAAAAAAAAAARFRPLnhtbFBLBQYAAAAAAQABADUAAAAvAAAAAAA= Encrypt:cvvPjAY7PxOBywAak7KOw6b5J157cRpVLm4pUWDJIc+i3ihSvn5OMahF1sFDrkckMxvLod78maAQppESMCKa0x9pJxvrZbN5i/rMMNSTfF6ffA57JhyhZSgNMrufC0daVX Decrypt:UEsDBBQAAAAIAEi0OzMnz+xKCgAAAAgAAAAHAAAARFRPLnhtbAsMcNcrSS0uAQBQSwECFAAUAAgACABItDszJ8/sSgoAAAAIAAAABwAAAAAAAAAAAAAAAAAAAAAARFRPLnhtbFBLBQYAAAAAAQABADUAAAAvAAAAAAA= UnZip:QPG.test 這就是我們要的,是很簡單,,基本夠用就好,! 另外心細的讀者會發(fā)現(xiàn)SimpleContainer.MessageQueue,這是干什么的呢,?那是我們分布式處理的消息隊列代理,,且聽下回分解...... |
|