`
QING____
  • 浏览: 2245859 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java与常用设计模式

    博客分类:
  • 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...");
	}

}

 

---先到此结束..

 

分享到:
评论

相关推荐

    JAVA常用设计模式

    JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式JAVA常用设计模式

    java中常用设计模式总结心得

    以下是对Java中常用设计模式的详细解释: 1. **单例模式**:单例模式确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于配置管理、线程池或者数据库连接池等场景。实现方式有懒汉式(线程不安全)、...

    Java常用设计模式

    以下是关于标题和描述中提到的Java常用设计模式的详细解释: 1. **单例模式**:确保一个类只有一个实例,并提供一个全局访问点。在Java中,通常通过私有构造器和静态工厂方法实现。双检锁(Double-Check Locking)...

    java常用设计模式集锦

    java常用的设计模式一个简单总结,如工厂模式、单例模式、代理模式等等。(楼主也是未入门的菜鸟,如有错误请及时联系楼主更正,谢谢!)

    java常用23中设计模式

    总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元...

    JAVA常用设计模式详解大全

    该文件里面包含JAVA开发常用的设计模式,通过举例、分析、代码示意的方式让读者很容易理解

    常用设计模式及Java程序 pdf

    ### 常用设计模式及Java程序设计 #### 设计模式概述 设计模式是一种软件设计领域中的通用解决方案,用于描述解决常见设计问题的最佳实践。它不仅有助于提高代码的复用性和可读性,还能增强软件架构的灵活性和扩展...

    JAVA程序常用设计模式

    本资料包聚焦于“JAVA程序常用设计模式”,旨在帮助中高级JAVA程序员进一步提升编程能力。 1. 单例模式:确保一个类只有一个实例,并提供一个全局访问点。在Java中,单例模式通常通过双重检查锁定、静态内部类或...

    JAVA常用设计模式.ppt

    在Java中,设计模式尤其重要,因为它们可以帮助我们编写出更灵活、可维护和易于扩展的代码。以下是对给定文件中提到的几种设计模式的详细解释: 1. **简单工厂模式(Simple Factory)**: - 简单工厂模式是一种...

    java常用设计模式 ppt

    java 常用设计模式 ppt格式 分类 创建模式 结构模式 行为模式 优点 面向界面编程 降低耦合性 增加灵活性

    五种常用的Java设计模式

    五种常用的Java设计模式 Java设计模式是软件开发中的一种重要概念,主要用来解决软件设计中的一些问题。下面将总结五种常用的Java设计模式,分别是单例模式、工厂模式、建造模式、_observer模式和迭代器模式。 ...

    Java常用设计模式例子

    以JAVA为例,汇总了十几种常用的设计模式,包括了:单例模式、工厂模式、建造者模式、适配器模式、装饰器模式、外观模式、命令模式、观察者模式、状态模式、策略模式、模板方法模式等。仅供学习使用。 相关文章请看...

    Java常用设计模式(SingleTon、FactoryMethod、AbstractFactory)

    Java设计模式是面向对象编程...在阅读《Chapter1___Java常用设计模式(SingleTon、FactoryMethod、AbstractFactory)》的相关资料时,你可以更深入地学习这些模式的细节,包括适用场景、优缺点以及如何在实际项目中实现。

    常用设计模式java实现

    设计模式是软件工程中经过长期实践总结出的通用解决方案,它们描述了在特定情况下如何解决...通过阅读和学习提供的"常用设计模式java实现"压缩包中的例子,可以更好地理解和实践这些设计模式,从而提升Java编程技能。

    java几种常用的设计模式

    -------------------------------java几种常用的设计模式--------------------------------------------------------------------------------------------------------------------------

    java模式,设计模式,多种设计模式

    ### Java设计模式详解 #### 一、引言 ...本文介绍了几种常用的设计模式,包括J2EE设计模式和软件开发设计模式,并详细探讨了它们的应用场景。希望这些知识能够帮助你在开发过程中更加高效地解决问题。

    Java多线程设计模式_清晰完整PDF版 Java多线程设计模式源代码

    Java多线程设计模式是Java开发中的重要领域,它涉及到如何在并发环境下高效、安全地管理资源和控制程序执行流程。本资料集包含了清晰完整的PDF版书籍和源代码,为学习和理解Java多线程设计模式提供了丰富的素材。 ...

Global site tag (gtag.js) - Google Analytics