在Java中,代理模式和装饰器模式是两种常用的设计模式。这两种模式都可以用来增强某个类的功能,实现对象的动态扩展。本文将详细介绍这两种模式的区别和应用。
代理模式是一种常用的设计模式,它的目的是为其他对象提供一种代理以控制对这个对象的访问。
代理模式的常见应用场景有:
代理模式的实现方式有两种:静态代理和动态代理。
静态代理是在代码编译期间就已经确定好了代理对象,代理对象和目标对象是在编译期间就确定了的。静态代理需要自己编写代理类,对于每个需要代理的类都需要编写一个代理类。
下面是一个静态代理的例子:
public interface UserService {
void addUser(String userName, String password);
}
public class UserServiceImpl implements UserService {
public void addUser(String userName, String password) {
System.out.println("添加用户:" + userName);
}
}
public class UserServiceProxy implements UserService {
private UserService userService;
public UserServiceProxy(UserService userService) {
this.userService = userService;
}
public void addUser(String userName, String password) {
System.out.println("开始添加用户...");
userService.addUser(userName, password);
System.out.println("添加用户成功!");
}
}
在上面的例子中,我们定义了一个UserService接口和一个UserServiceImpl实现类,UserServiceProxy是代理类。当需要调用addUser方法时,我们就可以通过UserServiceProxy来实现代理。
动态代理是在代码运行期间动态生成代理对象,不需要自己编写代理类。在Java中,动态代理主要通过Proxy类和InvocationHandler接口来实现。
下面是一个动态代理的例子:
public interface UserService {
void addUser(String userName, String password);
}
public class UserServiceImpl implements UserService {
public void addUser(String userName, String password) {
System.out.println("添加用户:" + userName);
}
}
public class LogInvocationHandler implements InvocationHandler {
private Object target;
public LogInvocationHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始调用方法:" + method.getName());
Object result = method.invoke(target, args);
System.out.println("方法调用结束。");
return result;
}
}
public class Main {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
InvocationHandler invocationHandler = new LogInvocationHandler(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(),
new Class[]{UserService.class},
invocationHandler);
proxy.addUser("Tom", "123456");
}
}
在上面的例子中,我们定义了一个UserService接口和一个UserServiceImpl实现类,LogInvocationHandler是代理类。当需要调用addUser方法时,我们就可以通过动态代理来实现代理。
装饰器模式是一种常用的设计模式,它的目的是动态地给一个对象添加一些额外的职责。就增加功能而言,装饰器模式比生成子类更为灵活。
装饰器模式的常见应用场景有:
装饰器模式的实现方式有两种:继承方式和组合方式。
继承方式是通过继承原始类来实现装饰器模式。下面是一个继承方式的例子:
public interface Shape {
void draw();
}
public class Circle implements Shape {
public void draw() {
System.out.println("画一个圆形。");
}
}
public class CircleWithBorder extends Circle {
public void draw() {
super.draw();
System.out.println("画一个边框。");
}
}
public class Main {
public static void main(String[] args) {
Shape circle = new CircleWithBorder();
circle.draw();
}
}
在上面的例子中,我们定义了一个Shape接口和一个Circle实现类,CircleWithBorder是装饰器类。当需要画一个有边框的圆形时,我们可以通过CircleWithBorder来实现装饰器。
组合方式是通过将原始类作为参数传递给装饰器类来实现装饰器模式。下面是一个组合方式的例子:
public interface Shape {
void draw();
}
public class Circle implements Shape {
public void draw() {
System.out.println("画一个圆形。");
}
}
public class CircleWithBorder implements Shape {
private Shape shape;
public CircleWithBorder(Shape shape) {
this.shape = shape;
}
public void draw() {
shape.draw();
System.out.println("画一个边框。");
}
}
public class Main {
public static void main(String[] args) {
Shape circle = new Circle();
Shape circleWithBorder = new CircleWithBorder(circle);
circleWithBorder.draw();
}
}
在上面的例子中,我们定义了一个Shape接口和一个Circle实现类,CircleWithBorder是装饰器类。当需要画一个有边框的圆形时,我们可以通过CircleWithBorder来实现装饰器。
通过对代理模式和装饰器模式的比较和应用,我们可以更好地理解和运用这两种设计模式。在实际开发中,我们可以根据具体的需求来选择使用哪种模式。
本文为翻滚的胖子原创文章,转载无需和我联系,但请注明来自猿教程iskeys.com
