设计模式学习(一) 单例模式和代理模式
设计模式
这里总结一下我学习到的多种设计模式的实现
单例模式
public class Singleton {
private Singleton(){}
public static Singleton getInstance(){
return SingletonInstance.instance;
}
private static class SingletonInstance{
static Singleton instance = new Singleton();
}
}
这种形式保证了以下几点:
-
1.Singleton最多只有一个实例,在不考虑反射强行突破访问限制的情况下。
-
2.保证了并发访问的情况下,不会发生由于并发而产生多个实例。
-
3.保证了并发访问的情况下,不会由于初始化动作未完全完成而造成使用了尚未正确初始化的实例
代理模式
静态代理
例子: 数据库连接池。连接池的连接使用完一般是不用关闭,而是归还给连接池,这里我们用代理实现一下。
public interface Connection extends Wrapper {
Statement createStatement() throws SQLException;
void close() throws SQLException;
}
我们这里要把close方法代理,而创建方法不变
public class ConnectionProxy implements Connection{
private Connection connection;
public ConnectionProxy(Connection connection) {
super();
this.connection = connection;
}
public Statement createStatement() throws SQLException{
return connection.createStatement();
}
public void close() throws SQLException{
System.out.println("不真正关闭连接,归还给连接池");
}
}
静态代理的做法
-
1,代理类一般要持有一个被代理的对象的引用。
-
2,对于我们不关心的方法,全部委托给被代理的对象处理。
-
3,自己处理我们关心的方法。
动态代理
例子: 实现用户登录做缓存处理。
接口
public interface UserService {
User login(String username);
}
接口实现
public class UserServiceImpl implements UserService {
@Override
public User login(String username) {
System.out.println("读取数据库 - 查询用户 - " + username);
return new User(username);
}
}
代理实现缓存功能
public class UserServiceHandler implements InvocationHandler {
private Object obj;
private Map<String, User> cache = new HashMap<>();
public UserServiceHandler(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Class<?>[] types = method.getParameterTypes();
if(method.getName().equals("login") && types.length==1 && types[0]==String.class){
String username = (String) args[0];
if(cache.containsKey(username)){
System.out.println("读取缓存 - 查询用户 - " + username);
return cache.get(username);
}else{
User user = (User) method.invoke(obj, args);
cache.put(username, user);
return user;
}
}
return method.invoke(obj, args);
}
}
测试
public class DynamicDesignTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserServiceHandler userServiceHandler = new UserServiceHandler(userService);
UserService proxyUserService = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), new Class[]{UserService.class},
userServiceHandler);
proxyUserService.login("fengzp");
proxyUserService.login("fengzp");
}
}