Java设计模式
单例模式的使用场景:
1、缓存资源,控制资源的并发读、写。(资源即类的属性)
例如:有一把锁,需要两把钥匙才能打开。在更换钥匙期间,是不允许开锁的。
而且,两把钥匙必须更换完才允许开锁,即,只更换完一把时,是不允许开锁的。
假设一个线程修改完了一把钥匙,正准备修改第二把钥匙,而此时另外一个线程又试图开锁。
有两种做法:
1)此时不允许开锁,必须等第二把钥匙更改完成后才允许。
2)允许开锁,仍然用未更改的旧钥匙。
读的时候,为提高效率,最好能避免使用synchronized同步。
设计模式:
Proxy
Adapter
Decorator
Wrapper
Delegate
区别:
Proxy:某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动。
Proxy就象一道墙,其他程序只能和Proxy交互操作。
用法1: 授权、检查机制。
比如,通过ForumProxy代理,控制用户对论坛的访问权限。代码如下:
public class ForumProxy implements Forum { private ForumPermissions permissions; private Forum forum; public ForumProxy(Forum forum, ForumPermissions permissions){ this.forum = forum; this.permissions = permissions; } public void setName(String name) { //只有是系统或论坛管理者才可以修改名称 if (permissions.isSystemOrForumAdmin()) { forum.setName(name); } } }
只能通过ForumProxy来创建Forum,并且要求传入ForumPermissions。在setName的时候,会首先检查权限。
动态代理就是这个系列的一种高级实现方式。
用法2:延迟初始化。先要获得某种资源,但是不急着去使用它。
例如,如果直接用
ABC obj= new ABC(); // 或者 ABC obj = getABC();
obj.doXXX();
假设获得obj的过程很漫长,而且不会立即用到,那么就建立一个ABCProxy对象,然后再调用代理对象的doXXX()方法:
void doXXX(){
ABC obj= new ABC(); // 或者 ABC obj = getABC();
obj.doXXX();
}
Decorator模式:
不改变原来定义的类,但是又想给他增加功能。而且又不想继承它。
那就用Decorator模式,例如BufferedReader:
FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
将原来的对象作为参数传到Decorator中,注意
Decorator和原来的对象,都implements了同一个接口,比如Reader。
调用Decorator时,可以在原对象的方法前后,加上Decorator自定义的方法。
Decorator模式和Proxy模式的区别在于,Decorator着重于“增加功能”,而Proxy着重于“改造”。
通常来说,Proxy的使用频率比Decorator要高。
Adapter模式:将两个类组合在一起使用,建立一种统一的使用方法。
例如,假设我们有两种打桩方式:方形桩、圆形桩。现在有一个应用,需要既打方形桩,又打圆形桩。
实现方式如下:
public class PegAdapter extends SquarePeg { private RoundPeg roundPeg; public PegAdapter(RoundPeg peg) { this.roundPeg=peg; } // 打桩-同时打两个 public void insert(String str) { super.insert(str); roundPeg.insertIntoHole(str); } }
加入:需要打桩,但是打什么类型的桩是动态确定的。
实现方式如下:
public class PegAdapter implements IRoundPeg, ISquarePeg{ private RoundPeg roundPeg; private SquarePeg squarePeg; // 构造方法 - RoundPeg public PegAdapter(RoundPeg peg){ this.roundPeg=peg; } // 构造方法 - SquarePeg public PegAdapter(SquarePeg peg){ this.squarePeg=peg; } // 打桩-选择一个打桩 public void insert(String str){ if(roundPeg!=null) roundPeg.insertIntoHole(str); else squarePeg.insertIntoHole(str);} } }
Strategy(策略模式)
跟Adapter模式类似,比Adapter模式狭隘。用于动态确定调用的对象。
例如:
我们要建立一个算法解决类,用来提供客户端可以自由选择算法。
public class RepTempRuleSolve { // 实际的算法对象 private RepTempRule strategy; // 指定算法 public RepTempRuleSolve(RepTempRule rule){ this.strategy=rule; } // 切换算法 public void changeAlgorithm(RepTempRule newAlgorithm) { strategy = newAlgorithm; } public String doService(Site site,String oldString) { return strategy.replace(site,oldString); } }