技术篇(1)--QPG容器的基本用法

如果你是学生,最好先到毕业生之歌看一下几个基本概念.
http://www.cnblogs.com/QPG2006/articles/246105.html

如果你已经对Castle有一定了解,可以参看:
http://www.cnblogs.com/QPG2006/articles/245667.html

或者直接看下文:


 静静的夜晚并非一切都已睡去……

    QPG希望借助大家已有的成果,来达到快速开发高质量软件的目的。当然我们也不相信有银弹存在,因为软件开发中最困难的是要面对人的无形的期望,而将说不清楚的事情表达出来,也许才是软件开发的真正困难所在。尤其是在什么所谓的管理系统上,也许没有多少人能看到目标前就已经耗尽了体力!

   废话少说,那么QPG平台到底为程序员提供了什么呢?回答是QPG不是包罗万象的框架,他借助castleIoC\AOPlog4netNHibernate等提供的强大功能来帮助程序员简化开发任务。QPG本身提供了端到端的服务负载均衡,任何程序在这个世界里都可以提供服务,当然也可以消费服务!当然这肯定对某些人来说还不够,随着今后的需求增加,我们会再集成一些轻量级的有用组件。

  下面以一个简单的例子来介绍QPG平台的基本功能:正确高效使用组件、日志、加密压
 

首先请下载开发演示文件,把它解压到一个目录,你可以看到如下的Basic项目。

 们编写了一个产品组件,还有一个销售管理组件。不过那个组件会在今后的AOP里再演示了。现看看产品组件,是否很简单:

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<0throw 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会存在至少两个实例,当内存池不够时容器会创建时新的并且加入到实例池,但是最多只有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");
        }

 

让我们来看看执行的结果如何吧:

先运行tesSingleton

 

call Product()

call Product()

Product(P1,333,33)

1--333

2—10    //哈哈第二次使用的还是那个对象我们在前次给他的价格已经设置为10元了

3--20

4--30

1--40

2--10

3—20

。。。。。。

您可以看到系统先产生了2Product,那是因为p2最少有两个,平台已经知道我们的期望,自动帮我们做了!

P1只被产生一次: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

。。。。。。

您可以看到虽然系统先产生了2Product,但是在访问并且不释放情况下第三、四次访问时,系统调用了缺省构造函数来产生一个新的实例。以后使用访问并释放的方法,这四个实例满足了我们一万次的访问。在我的机器上,这个TestCase用了1687ms,也证明尽管有缓存,但是毕竟构造两次也花了些时间。所以没有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()

。。。。。。

您可以看到确是每次都会产生新的,这样肯定最慢了,在我机器上用了4031ms

 

测试程序里还演示了两个常用的功能,写日志和加密压缩。演示结果您可以在LOG\下发现一个log.txt,打开看看应该如下:

[DEBUG][2005-09-27 21:23:09,484]--hello world! SO SIMPLE!

 

是否太过简单?如果您了解log4net ,您可以配置成您想要的日志方式,比如写系统日志、谢数据库、远程对象、UDP广播等。

 

在看看加密压缩吧:

Zip:UEsDBBQAAAAIAEi0OzMnz+xKCgAAAAgAAAAHAAAARFRPLnhtbAsMcNcrSS0uAQBQSwECFAAUAAgACABItDszJ8/sSgoAAAAIAAAABwAAAAAAAAAAAAAAAAAAAAAARFRPLnhtbFBLBQYAAAAAAQABADUAAAAvAAAAAAA=

Encrypt:cvvPjAY7PxOBywAak7KOw6b5J157cRpVLm4pUWDJIc+i3ihSvn5OMahF1sFDrkckMxvLod78maAQppESMCKa0x9pJxvrZbN5i/rMMNSTfF6ffA57JhyhZSgNMrufC0daVX4g9eEJ8sQD5MTo+OPZAOjjZW+kVs4TvHa8gc5QA/4y9HAaEk7v/8kBV7ENGnHvSQii8sR9bTDjIF6k8YNZpXjISMH7iVfY

Decrypt:UEsDBBQAAAAIAEi0OzMnz+xKCgAAAAgAAAAHAAAARFRPLnhtbAsMcNcrSS0uAQBQSwECFAAUAAgACABItDszJ8/sSgoAAAAIAAAABwAAAAAAAAAAAAAAAAAAAAAARFRPLnhtbFBLBQYAAAAAAQABADUAAAAvAAAAAAA=

UnZip:QPG.test

这就是我们要的,是很简单,基本够用就好!

另外心细的读者会发现SimpleContainer.MessageQueue,这是干什么的呢?那是我们分布式处理的消息队列代理,且听下回分解......
(在没有正确配置时使用会报错喔!)

posted @ 2005-10-06 21:37  成为-行动-拥有(BeDoHave)  阅读(1551)  评论(0编辑  收藏  举报