Wednesday, February 24, 2016

编程规范Coding standard

编程规范文字版:包含Comments, Environment, Functions, General, Java, Names, Tests,详细书籍Clean Code的285-314页。

Tool:
http://stackoverflow.com/questions/38635/what-static-analysis-tools-are-available-for-c

FxCop for c#:
http://www.cnblogs.com/zhuqil/archive/2010/12/07/FxCop.html
http://www.codeproject.com/Articles/30666/Steps-to-Write-Your-Own-Custom-Rule-using-FXCOP

base("clsCheck", "MyRules.connection", typeof(clsCheck).Assembly)
clsCheck: class name
MyRules.connection: (proj name).(xml file name)

Add MyRules DLL to FxCop














Now compile JustForTest to a exe and drag it to FxCop



Project MyRules:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.FxCop.Sdk;



namespace MyRules
{
    class clsCheck : BaseIntrospectionRule
    {
        public clsCheck()
            : base("clsCheck", "MyRules.connection", typeof(clsCheck).Assembly)
        {

        }

        public override ProblemCollection Check(Member member)
        {
            Method method = member as Method;
            bool boolFoundConnectionOpened = false;
            bool boolFoundConnectionClosed = false;
            Instruction objInstr = null;
            for (int i = 0; i < method.Instructions.Count; i++)
            {
                objInstr = method.Instructions[i];

                if (objInstr.Value != null)
                {
                    if (objInstr.Value.ToString().Contains("System.Data.SqlClient.SqlConnection"))
                    {
                        boolFoundConnectionOpened = true;
                    }
                    if (boolFoundConnectionOpened)
                    {
                        if (objInstr.Value.ToString().Contains("System.Data.Common.DbConnection.Close"))
                        {
                            boolFoundConnectionClosed = true;
                        }
                    }
                }
            }    
             if((boolFoundConnectionOpened)&&(boolFoundConnectionClosed ==false))
            {
               Resolution resolu = GetResolution(new string[] { method.ToString() });
               Problems.Add(new Problem(resolu));
            }
            return Problems;
        }
    }
}


connection.xml
<?xml version="1.0" encoding="utf-8" ?>
<Rules>
<Rule TypeName="clsCheck" Category="Database" CheckId="Shiv001">
<Name>Connection object Should be closed</Name>
<Description> Connection objects should be closed</Description>
<Owner> Shivprasad Koirala</Owner>
<Url>http://www.questpond.com</Url>
<Resolution> Call the connection close method </Resolution>
<Email></Email>
<MessageLevel Certainty="99"> Warning</MessageLevel>
<FixCategories> Breaking </FixCategories>
</Rule>
</Rules>


Project JustForTest:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using System.Data.SqlClient;

namespace JustForTest
{
    class Program
    {
        static void Main(string[] args)
        {

        }

        public static byte[] readFully(Stream input)
        {
            SqlConnection objConnection = new SqlConnection();
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }

    }



}


Set rules in VS 2013:
https://msdn.microsoft.com/en-us/library/dd264949.aspx
http://blogs.msdn.com/b/codeanalysis/archive/2010/03/26/how-to-write-custom-static-code-analysis-rules-and-integrate-them-into-visual-studio-2010.aspx



Monday, February 15, 2016

生产者消费者模式

生产者生产速度和消费者消费速度不平衡,利用一个阻塞队列实现缓冲区,比如,如果生产者速度较快,当队列已满,就不再生产。同理,队列空的时候,消费者不再消费进入睡眠等到生产者有生产的时候才开始消费。所以

1. 这个模式实现了平衡两者间处理能力
2. 实现生产者和消费者逻辑间解耦


import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 1个生产者 3个消费者 生产、消费10次
 *
 * @作者 pt
 *
 */

public class ProducerConsumer {
Stack<Integer> items = new Stack<Integer>();
final static int NO_ITEMS = 10;

public static void main(String args[]) {
ProducerConsumer pc = new ProducerConsumer();
                Thread t1 = new Thread(pc.new Producer());
                Consumer consumer  = pc.new Consumer();

Thread t2 = new Thread(consumer);
Thread t3 = new Thread(consumer);
Thread t4 = new Thread(consumer);
t1.start();
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
t2.start();
t3.start();
t4.start();
try {
t2.join();
t3.join();
t4.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

class Producer implements Runnable {
public void produce(int i) {
System.out.println("Producing " + i);
items.push(new Integer(i));
}

@Override
public void run() {
int i = 0;
// 生产10次
while (i++ < NO_ITEMS) {
synchronized (items) {
produce(i);
items.notifyAll();
}
try {
// 休眠一段时间
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}

class Consumer implements Runnable {
                // consumed计数器允许线程停止
AtomicInteger consumed = new AtomicInteger();

public void consume() {
if (!items.isEmpty()) {
System.out.println(Thread.currentThread().getId()+" Consuming " + items.pop());
consumed.incrementAndGet();
}
}

private boolean theEnd() {
return consumed.get() >= NO_ITEMS;
}

@Override
public void run() {
while (!theEnd()) {
synchronized (items) {
while (items.isEmpty() && (!theEnd())) {
try {
//wait same time as Producer, 主要目的是sleep,减少CPU资源消耗
items.wait(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
consume();

}
}
}
}
}

ref: https://zh.wikipedia.org/wiki/%E7%94%9F%E4%BA%A7%E8%80%85%E6%B6%88%E8%B4%B9%E8%80%85%E9%97%AE%E9%A2%98
http://www.infoq.com/cn/articles/producers-and-consumers-mode

Sunday, February 14, 2016

SOA实例:Dubbo

Dubbo是一个分布式服务框架,它作用有:
1. 远程方法调用,如调用本地方法
2. 服务自动查找,不需知道服务提供方地址,注册中心基于接口名查询服务提供者的IP地址
3. 负载均衡及容错机制

定义服务接口: (该接口需单独打包,在服务提供方和消费方共享)
DemoService.java

1
2
3
4
package com.alibaba.dubbo.demo;
public interface DemoService {
    String sayHello(String name);
}

 在服务提供方实现接口:(对服务消费方隐藏实现)
DemoServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
package com.alibaba.dubbo.demo.provider;
  
import com.alibaba.dubbo.demo.DemoService;
  
public class DemoServiceImpl implements DemoService {
  
    public String sayHello(String name) {
        return "Hello " + name;
    }
  
}
 用Spring配置声明暴露服务:

 provider.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="UTF-8"?>
  
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="hello-world-app"  />
  
    <!-- 使用multicast广播注册中心暴露服务地址 -->
    <dubbo:registry address="multicast://224.5.6.7:1234" />
  
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
  
    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" />
  
    <!-- 和本地bean一样实现服务 -->
    <bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />
  
</beans>
 加载Spring配置:
Provider.java
1
2
3
4
5
6
7
8
9
10
11
12
import org.springframework.context.support.ClassPathXmlApplicationContext;
  
public class Provider {
  
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"http://10.20.160.198/wiki/display/dubbo/provider.xml"});
        context.start();
  
        System.in.read(); // 按任意键退出
    }
  
}

服务消费者

通过Spring配置引用远程服务:
consumer.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
  
    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="consumer-of-helloworld-app"  />
  
 
  1.    <!-- 使用zookeeper注册中心暴露服务地址 -->  
  2.     <!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> -->  
  3.     <dubbo:registry address="zookeeper://127.0.0.1:2181" />
  
    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="demoService" interface="com.alibaba.dubbo.demo.DemoService" />
  
</beans>
 加载Spring配置,并调用远程服务:(也可以使用IoC注入)
Consumer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.alibaba.dubbo.demo.DemoService;
  
public class Consumer {
  
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"http://10.20.160.198/wiki/display/dubbo/consumer.xml"});
        context.start();
  
        DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
        String hello = demoService.sayHello("world"); // 执行远程方法
  
        System.out.println( hello ); // 显示调用结果
    }
  
}
ref: http://www.it610.com/article/2285944.htm