设计模式之不变设计模式
不变设计模式(immutable pattern)1 定义这些对象共享相同对象的引用,为此,在对象构造好之后,不允许改变共享对象的内容2 例子在jdk中String被设计为不可变类,一旦生成一个String对象,它的所有属性就不会被变,任何方法要么返回这个对象本身的原始状态,要么抛弃原来的字符串返回一个新字符串,而绝对不会返回被修改了的字符串对象.StringBuffer是可变类3 如何设计不可变类不变类,即类中的方法和属性不能被外界修改,包括其子类1.类本身声明为final,可以保证它本身的状态不会被子类扩展方法所改变,即没有子类。2.类的所有成员变量都是final的,保证它在构造后不会被重新赋值.而且类所有属性是private的,只提供getter访问.3.类的能传入的参数是Immutable的,且返回的属性也是不可变的.如果方法返回的属性是基本类型,则在类中将该属性声明为final即可。如果是引用类型,该属性的final只能保证引用类型的引用地址不可变,无法保证外界对该引用类型内容的修改,所以一般返回该引用类型的一份拷贝。注意:在将可变类封装到不变类的时候要特别小心.因为你传入的引用在外面是可以被修改的.所以即使你不变类本身不能去改变属性,但属性有一个外部引用.可以在外面修改。4 优缺点1)不变类优点:多个线程共享一个不变类的实例时,这个实例的状态不会发生改变.事实上它没有地方让你去改变.所以多线程共享一个不变类的实例时,不需要进行临界区保护(即同步)。2)不变类缺点:不灵活5 应用5.1设计一个缓存例子:设计一个单例,属性HashMap已被赋值,外部只能使用属性HashMap的值,不能对其进行修改,所以只返回HashMap中的值,不返回该HashMap的引用地址。[java]<span style="font-size:18px">/*** Fuction:* 输入参数是不可变的,返回的HashMap不是hm,即其引用地址,每次返回它的副本,所以外界也无法修改hm* @author E-mail:yangzhonglive@gmail.com* @version 2013-10-7 下午9:57:16* @since 1.0*/public final class ImmutableBuffer {private volatile static ImmutableBuffer uniqueInstance=null;private final HashMap hm=new HashMap();private ImmutableBuffer(){//设置缓存值hm.put("a", 1);hm.put("b", 2);}public static ImmutableBuffer getInstance(){if(uniqueInstance==null){synchronized (ImmutableBuffer.class){ //note we only synchronize the first time through!if(uniqueInstance == null) //once in the block,check again and if still null, create an instanceuniqueInstance=new ImmutableBuffer();}//end synchronized}//end ifreturn uniqueInstance;}//end geInstance()public HashMap getHashMap(){HashMap copy=new HashMap();copy.putAll(hm);return copy;}//end getHashMap()/*** @param args*/public static void main(String[] args) {ImmutableBuffer ib=ImmutableBuffer.getInstance();//尝试改变缓存值HashMap hm=ib.getHashMap();hm.put("c", 3);//测试是否改变HashMap hm2=ib.getHashMap();Set entry=hm2.entrySet();Iterator it=entry.iterator();while(it.hasNext()){Map.Entry me=(Map.Entry)it.next();//获得关键字getKey(),获得值getValue()System.out.println(me.getKey()+":"+me.getValue());}//end while}//end main()}</span>5.2 实现Immutable的FIFO队列,要求时间复杂度为O(1)The Queue class represents an immutable first-in-first-out (FIFO) queue of objects. Use two @see PersistentStack to implement the persistent queue.Every element is pushed on the incoming stack once, popped off the incoming stack once, pushed on the outgoing stack once and popped off the outgoing stack once. enqueue(E) is O(1). Dequeuing is on average O(1), though it is * O(n) for a single case which only few happens when reverse incoming stack elements into outgoing stack.不变队列实现用2个不变栈来实现,不变栈类如下[java]<span style="font-size:18px">/*** Implement an persistent stack, here persistent stacks with the same tail can* share state, saving on memory.** @author E-mail:yangzhonglive@gmail.com* @version 2013-10-12* @since 1.0*/public final class PersistentStack<E> implements Iterable<E> {// ----------------------------------------------------// ---private properties// ----------------------------------------------------/*** The head value of this persistent stack.*/private final E head;/*** The head of this persistent stack, and it is the tail reference of the* stack which add element into this persistent stack*/private final PersistentStack<E> tail;/*** The number of elements in this persistent stack.*/private final int size;// ----------------------------------------------------// ---constructor// ----------------------------------------------------/**补充:软件开发 , Java ,
上一个:杭电ACM 1003 题
下一个:java 随机数 随机打乱数组 随机抽取
- 更多JAVA疑问解答:
- java怎么在线读取ftp服务器上的文件内容
- 关于程序员的职业规划
- HTML和JSP矛盾吗?
- java小程序如何打包?
- java怎么split路径文件名?
- jsp+javaBean中Column 'ordersPrice' specified twice的错误
- Java TCP/IP Socket网络编程系列
- 大家来讨论一下我到底该用什么好?Swing 还是 JavaFX
- 关于Hibernate实体自身多对一的抓取问题
- 关于apache2+tomcat群集出现的问题
- spring 获取上下文问题
- SSH 导入导出excel 谁有这块的资料吗?
- Ext TreePanel 刷新问题
- springmvc 加载一个jsp页面执行多个方法 报404
- checkbox数组action怎么向页面传值