java与常用设计模式

    程序设计最终将归结为"算法"和"设计模式",其中设计模式是我们进行良好程序设计的思想和"纲要";接下来本人将以通俗的实例来展示几种常用的设计模式,以及它们在java程序设计中需要注意的问题.

    在此需要提醒一下,很多设计模式,只是思想上有稍微的区别,但是在程序设计(模板)中这种区别可能无法显著的表达出来,对于一个"靠天吃饭"的码农,我们了解它们的思想就已经足够了.

 

一.Singleton(单例模式):

    单例模式,是一个神奇的模式,从狭隘的角度考虑,这种模式的实现,极度依赖于程序运行"容器"以及实例的生命周期,简单的归纳为:在指定"运行环境"中,任何时刻只能有一个实例存在.在java层面,单例和Classloader有必然关联关系,严格意义上说,一个classloader只能有一个单例的实例.

    java序列化和反序列化、反射机制将有可能"打破"单例的设计,需要注意.

public class SingleTon implements Serializable{  
 
    private static final long serialVersionUID = 768457893059530646L;  
  
    /**
     * 私有构造器,将可以避免通过"new Object()"方式创建对象
     */
    private SingleTon(){   
        //检测instance是否已经初始化
    	//避免反射机制,导致的多例问题,通过反射机制仍然可以对私有构造函数进行操作  
    	//---------------反射机制打破单例---
    	//Constructor[] constructors = SingleTon.class.getDeclaredConstructors();  
        //Constructor<SingleTon> c = constructors[0];  
        //c.setAccessible(true);  
        //SingleTon s2 = c.newInstance(null);
    	//-----------------------------------
        if(instance != null){  
            return;  
        }  
    }  
      
    private static final SingleTon instance = new SingleTon(); 
      
    public static SingleTon getInstance(){  
        return instance;  
    }  
      
    private void readObject(java.io.ObjectInputStream in) throws IOException{  
    	//与writeObject对应,根据writeObject中write的顺序,进行read
    	//你可以决定,是否在此方法中,进行重置instance的属性值.
    	//this.age = in.readInt();
    }  
    private void writeObject(ObjectOutputStream out) throws IOException{
    	//out.writeInt(this.age);
    }
    /** 
     * 严格单例,确保remote instance不会干扰单例模式,避免在反序列化过程中对单例的影响. 
     * @return 
     * @throws ObjectStreamException 
     */  
    public Object readResolve() throws ObjectStreamException{  
        return instance;  
    }  
}  

 

二.Factory(工厂模式):

    工厂模式,根据其实施手段的不同,分为"抽象工厂""静态工厂"等等,这些变种也是"万变不离其宗";工厂模式的精髓在于,让对象的创建过程和对象的消费者分离,生成的对象具有的特性与其交付给工厂方法的API参与而定..你可以把工厂模式,想象成现实生活中的工厂,你提交给工厂的订单参数,直接决定工厂为你生成的商品特性;再者,工厂就是为生产商品而生.

    工厂模式,在我们的日常开发中,经常被使用到,或许这种模式已经被你踩在脚下,你却不能看清它的面目.

public class ConnectionFactory {

	private String hostname;
	private int port;
	private List<Connection> pool = new LinkedList<Connection>();
	private int corePoolSize;
	private static final int DEFAULT_SIZE = 8;
	
	public ConnectionFactory(String hostname,int port){
		this(hostname,port,DEFAULT_SIZE);
	}
	public ConnectionFactory(String hostname,int port,int corePoolSize){
		this.hostname = hostname;
		this.port = port;
		if(corePoolSize > 0){
			this.corePoolSize = corePoolSize;
		}
	}
	public synchronized Connection createConnection(){
		if(pool.isEmpty()){
			return new Connection(hostname, port);
		}
		return pool.remove(0);
	}
	/**
	 * static factory method
	 */
	public static Connection createConnection(String hostname,int port){
		return new Connection(hostname, port);
	}
	
	public void returnSource(Connection connection){
		if(pool.size() > corePoolSize){
			return;
		}
		pool.add(0, connection);
	}
	
	static class Connection{
		private String hostname;
		private int port;
		private Socket socket;
		private boolean init;
		
		public Connection(String hostname,int port){
			this.hostname = hostname;
			this.port = port;
		}
		
		public synchronized void connect() throws IOException{
			if(init){
				return;
			}
			socket = new Socket(hostname,port);
			init = true;
		}
		
		public byte[] read(){return null;}
		public void write(byte[] bytes){}
		
	}
}

 

三.Builder(构建模式):

    构建模式:如果创建一个对象需要多个环节,只有按照一定的"步骤"才能正确创建一个对象实例,那么这个过程就是构建.对此过程的封装,就是"构建模式".不过我怎么感觉“StringBuilder”是构建模式的体现呢?!

/**
 * 构建一个sql语句
 */
public class QueryBuilder {

	private Query query;
	
	/**
	 * build模式,意味着一个"起始点"和"结束点"
	 * build过程起始点
	 * @param tableName
	 */
	private QueryBuilder(String tableName){
		this.query = new Query(tableName);
	}
	
	public static QueryBuilder from(String tableName){
		return new QueryBuilder(tableName);
	}
	/**
	 * 过程
	 * @param orderType
	 * @return
	 */
	public QueryBuilder order(String orderType){
		query.setOrderType(orderType);
		return this;
	}
	/**
	 * 过程
	 * @param key
	 * @param value
	 * @return
	 */
	public QueryBuilder addParam(String key,String value){
		query.getParams().put(key, value);
		return this;
	}
	
	/**
	 * "结束点",获得"构建"的结果
	 * @return
	 */
	public String build(){
		StringBuilder sb = new StringBuilder();
		sb.append("select * from ");
		sb.append(query.getTableName());
		Map<String,String> params = query.getParams();
		for(Entry<String,String> entry : params.entrySet()){
			sb.append(" ");
			sb.append(entry.getKey());
			sb.append("=");
			sb.append(entry.getValue());
		}
		return sb.toString();
	}
	
	private class Query{
		private String orderType;
		private Map<String, String> params;
		private String tableName;
		public Query(String tableName){
			this.tableName = tableName;
		}
		public String getOrderType() {
			return orderType;
		}
		public void setOrderType(String orderType) {
			this.orderType = orderType;
		}
		public String getTableName() {
			return tableName;
		}
		public void setTableName(String tableName) {
			this.tableName = tableName;
		}
		public Map<String, String> getParams() {
			return params;
		}
		
	}
	
	public static void main(String[] args){
		QueryBuilder builder = QueryBuilder.from("user");
		builder.order("desc")
		       .addParam("name", "zhangsan")
		       .addParam("status", "1");
		String statement = builder.build();
	}
}

 

四.Observer(观察者模式):

    当一个对象的某个操作,会对其他对象带来"关联性"影响时,如果被影响者能够"获得通知",那么这种模式就为"观察者模式".在java中,已经提供了"观察者"模式的API,我们看看改如何使用它们.

    观察者模式中需要"观察者"和"被观察者"2个角色.

public class ObserverSample {

	
	static class TestObserable extends Observable{
		private String name;
		public TestObserable(){
			super();
		}
		
		public TestObserable(String name){
			super();
			this.name = name;
		}
		
		public void update(String data){
			//..
			super.setChanged();
			super.notifyObservers(data);//通知
			super.clearChanged();
			
		}
		
		@Override
		public String toString(){
			return this.name == null ? super.toString() : this.name;
		}
	}
	
	/**
	 * 观察者
	 *
	 */
	static class TestObserver implements Observer{
		private String name;
		
		public TestObserver(String name){
			this.name = name;
		}
		
		@Override
		public void update(Observable o, Object arg) {
			System.out.println(name + " find " + o.toString() + " changed");
			System.out.println("changed data:" + arg.toString());
			
		}
		
	}
	
	public static void main(String[] args){
		TestObserver t1 = new TestObserver("t1");
		TestObserver t2 = new TestObserver("t2");
		TestObserable obserable = new TestObserable("observer");
		//顺序很重要
		obserable.addObserver(t1);
		obserable.addObserver(t2);
		obserable.update("update-test");
	}
}

五.Chain(责任链模式)

    chain,就是链,代码写起来也像"链条":如果一个"操作"需要被多个"处理器(processor)"依次顺序执行时,那么"责任链"模式,将会是最好的选择.不过,貌似 servlet中Filter是不是一种“责任链”的体现?!

public class PrinterSample {
	private Printer printer;
	
	public PrinterSample(Printer printer){
		this.printer = printer;
	}
	
	public void printer(String data){
		printer.execute(data);
	}
   
    static interface Printer {

        public void execute(String data);
    }
    
    static abstract class AbstractPrinter implements Printer{
    	protected Printer nextPrinter;
    	protected AbstractPrinter(Printer next){
    		this.nextPrinter = next;
    	}
    }
   
    static class LengthPrinter extends AbstractPrinter{

        protected LengthPrinter(Printer next) {
			super(next);
		}

		@Override
        public void execute(String data) {
            System.out.println("length:" + data.length());
            if(nextPrinter != null){
            	this.nextPrinter.execute(data);
            }
        }
    }
    
    static class HashcodePrinter extends AbstractPrinter{

		protected HashcodePrinter(Printer next) {
			super(next);
			// TODO Auto-generated constructor stub
		}

		@Override
		public void execute(String data) {
			System.out.println("Hashcode:" + data.hashCode());
			if(nextPrinter != null){
				nextPrinter.execute(data);
			}
		}
    	
    }
    
    static class ChecksumPrinter extends AbstractPrinter{
    	private static final Charset charset = Charset.forName("utf-8");
		protected ChecksumPrinter(Printer next) {
			super(next);
		}

		@Override
		public void execute(String data) {
			Adler32 checksum = new Adler32();
			checksum.update(data.getBytes(charset));
			System.out.println("Checksum:" + checksum.getValue());
			if(nextPrinter != null){
				nextPrinter.execute(data);
			}
		}
    	
    }
    
    
    public static void main(String[] args){
    	//build chain:
    	ChecksumPrinter csp = new ChecksumPrinter(null);
    	HashcodePrinter hp = new HashcodePrinter(csp);
    	LengthPrinter lp = new LengthPrinter(hp);
    	//
    	PrinterSample sample = new PrinterSample(lp);
    	sample.printer("This is chain-model sample!");
    }
}



六.Strategy(策略模式):

    针对输入的数据,而采取相应的“算法”输出结果的方式。如下例子为,根据输入的key而输出相应的hash模的值。

public class HashStrategy {

	public static long hashMode(Object key,int mod){
		if(key == null){
			throw new NullPointerException("key cant be null!");
		}
		if(key instanceof Number){
			return NumberHashcode.hashcode(key) % mod;
		}else{
			return ObjectHashcode.hashcode(key) % mod;
		}
	}
	
	
	static class NumberHashcode{
		public static long hashcode(Object key) {
			return ((Number)key).longValue();
		}
	}
	
	static class ObjectHashcode{
		public static long hashcode(Object key) {
			return key.toString().hashCode() & 0x7FFFFFFF;
		}
		
	}
	
	public static void main(String[] args){
		System.out.println(HashStrategy.hashMode("test hashStrategy", 3));
		System.out.println(HashStrategy.hashMode(12312412L, 3));
	}
}

 

七.Proxy(代理模式):

     代理模式,避免对实例方法的直接访问,而是使用代理对象来间接的去访问,这样一面可以在“实际调用”之前或者之后做一些补充性操作(比如参数变更,权限检测),另一面代理对象可以屏蔽掉实际实例的部分操作(让一些方法不可用)等。

public class ProxySample {

	static interface Printer{
		
		public void print(String value);
	}
	
	static class TimestampPrinter implements Printer{

		@Override
		public void print(String value) {
			System.out.println("Value:" + value);
			System.out.println("Timestamp:" + System.currentTimeMillis());
		}
		
	}
	
	/**
	 * 静态代理类,通常和“被代理者”有着相同的接口列表,通常子类通过扩展接口的方式实现
	 *
	 */
	static class StaticProxy implements Printer {
		//must "new Object"
		private Printer printer = new TimestampPrinter();
		
		public void print(String value){
			System.out.println("Static proxy: before invoke...");
			printer.print(value);
			System.out.println("Static proxy: after invoke...");
		}
	}
	
	static class DynamicProxy{
		private Printer printer = new TimestampPrinter();//被代理者

		private Printer proxy;//代理者
		public DynamicProxy(){
			proxy = (Printer)Proxy.newProxyInstance(DynamicProxy.class.getClassLoader(), new Class[]{Printer.class}, new Invocation(printer));
		}
		
		public void print(String value) {
			proxy.print(value);
		}
		
		
	}
	
	static class Invocation implements InvocationHandler{  
        private Object obj;//被代理实例  
        public Invocation(Object obj){  
            this.obj = obj;  
        }  
        @Override  
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
        	System.out.println("Dynamic proxy: before invoke");
            Object result = method.invoke(obj, args);  
            System.out.println("Dynamic proxy: after invoke");
            return result;
        }  
          
    }  
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		DynamicProxy dproxy = new DynamicProxy();
		dproxy.print("I am dynamic...");
		StaticProxy sproxy = new StaticProxy();
		sproxy.print("I am static...");
	}

}

 

---先到此结束..

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值