设计模式是面向对象设计中解决常见问题的一套最佳实践,它们为开发者提供了通用的解决方案。
1.单例模式(Singleton Pattern)
定义: 确保一个类只有一个实例,并提供一个全局访问点。
应用场景:
需要控制实例数量的类,如数据库连接池、线程池等。
需要共享的全局状态或资源的类。
实现方式:
饿汉式:在类加载时就创建实例,线程安全但可能会造成资源浪费。
懒汉式:在第一次调用时创建实例,需考虑线程安全问题。
双重检查锁定:结合懒汉式和饿汉式,确保线程安全和效率。
静态内部类:利用静态内部类实现延迟加载和线程安全。
代码示例(双重检查锁定):
java
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
2. 工厂模式(Factory Pattern)
定义: 提供一个创建对象的接口,而不指定具体的类。
应用场景:
需要在创建对象时进行某些配置或封装的情况。
系统需要根据不同条件创建不同对象时。
实现方式:
简单工厂:通过一个工厂类负责创建实例,根据传递的参数决定创建哪种实例。
工厂方法:将对象的创建延迟到子类中,实现类自己决定实例化哪个类。
抽象工厂:提供一个接口创建一系列相关或相互依赖的对象。
代码示例(简单工厂)
java
public interface Product {
void use();
}
public class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("Using Product A");
}
}
public class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("Using Product B");
}
}
public class Factory {
public static Product createProduct(String type) {
switch (type) {
case "A":
return new ConcreteProductA();
case "B":
return new ConcreteProductB();
default:
throw new IllegalArgumentException("Unknown product type");
}
}
}
// 使用
Product product = Factory.createProduct("A");
product.use();
3.策略模式(Strategy Pattern)
定义: 定义一系列算法,将每个算法封装起来,并且使它们可以互换。
应用场景:
需要在不同情况下使用不同算法,但这些算法可以替换使用。
避免使用大量条件语句选择算法的场景。
实现方式:
定义一个策略接口,各种算法实现该接口。
使用上下文类维护策略对象的引用,根据需要调用策略的方法。
代码示例:
java
public interface Strategy {
void execute();
}
public class ConcreteStrategyA implements Strategy {
@Override
public void execute() {
System.out.println("Strategy A executed");
}
}
public class ConcreteStrategyB implements Strategy {
@Override
public void execute() {
System.out.println("Strategy B executed");
}
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.execute();
}
}
// 使用
Context context = new Context(new ConcreteStrategyA());
context.executeStrategy();
4.观察者模式(Observer Pattern)
定义: 定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,其依赖者会收到通知并自动更新。
应用场景:
一个对象的改变需要通知其他对象,而这些对象不需要强耦合。
事件监听机制的实现,如GUI框架中的事件处理。
实现方式:
被观察者维护一组观察者列表,当状态变化时,遍历通知所有观察者。
代码示例:
java
import java.util.ArrayList;
import java.util.List;
public interface Observer {
void update();
}
public class ConcreteObserver implements Observer {
@Override
public void update() {
System.out.println("Observer notified");
}
}
public class Subject {
private List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
public void changeState() {
// 状态改变逻辑
notifyObservers();
}
}
// 使用
Subject subject = new Subject();
Observer observer = new ConcreteObserver();
subject.attach(observer);
subject.changeState();
5.代理模式(Proxy Pattern)
定义: 为其他对象提供一种代理,以控制对这个对象的访问。
应用场景:
需要在访问对象前后添加额外操作、如权限控制、缓存、日志等。
远程代理控制对远程对象的访问。
实现方式:
静态代理:通过在编译时创建代理类来控制访问。
动态代理:在运行时动态生成代理类,可以拦截方法调用。
代码示例(动态代理)
java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public interface Service {
void perform();
}
public class RealService implements Service {
@Override
public void perform() {
System.out.println("Performing real service");
}
}
public class ServiceProxy implements InvocationHandler {
private Object target;
public ServiceProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before invoking real service");
Object result = method.invoke(target, args);
System.out.println("After invoking real service");
return result;
}
public static Service createProxy(Service target) {
return (Service) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new ServiceProxy(target)
);
}
}
// 使用
Service service = new RealService();
Service proxyService = ServiceProxy.createProxy(service);
proxyService.perform();
6.装饰者模式(Decorator Pattern)
定义: 动态地给对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活。
应用场景
需要在不修改原类的情况下动态地给一个对象添加额外的功能。
需要扩展对象功能,且可能动态组合这些功能
实现方式:
装饰者和被装饰的类实现同一个接口。
在装饰者中持有被装饰对象的引用,并在方法中调用被装饰对象的方法,同时添加自己的逻辑。
代码示例:
java
public interface Component {
void operation();
}
public class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("Executing operation");
}
}
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
System.out.println("Decorator before operation");
component.operation();
System.out.println("Decorator after operation");
}
}
// 使用
Component component = new ConcreteComponent();
Component decorator = new Decorator(component);
decorator.operation();
7.责任链模式
责任链模式(Chain of Responsibility Pattern) 是一种行为设计模式,它允许将请求沿着处理链传递,直到有一个对象处理该请求为止。这种模式使多个对象都有机会处理请求,从而避免了请求的发送者与接收者之间的耦合。
应用场景:
需要动态地决定由哪个对象来处理请求的场景。
需要在不明确接收者的情况下,向多个对象中的一个提交请求。
需要将请求的处理逻辑与请求的发送者解耦时。
优点
降低耦合度:请求者和处理者解耦,请求者不需要知道哪个处理者会最终处理请求。
动态组合处理对象:可以在运行时动态地改变链中的处理者或调整顺序。
扩展灵活性:增加新的处理者类时,无需修改原有代码,符合开闭原则。
缺点
可能未处理请求:如果链过长或没有合理的终止条件,可能会导致请求未被处理。
调试困难:由于请求是在链上传递的,可能难以追踪请求的处理路径。
实现方式
在实现责任链模式时,通常有以下几个核心组件:
抽象处理者(Handler):定义处理请求的接口,并持有下一个处理者的引用。
具体处理者(ConcreteHandler):继承抽象处理者,实现处理请求的逻辑。
客户端(Client):创建责任链,并将请求传递给责任链的第一个处理者。
代码示例
java
// 抽象处理者类
abstract class Handler {
protected Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public void handleRequest(int request) {
if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// 具体处理者类A
class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request < 10) {
System.out.println("ConcreteHandlerA handled request " + request);
} else {
super.handleRequest(request);
}
}
}
// 具体处理者类B
class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("ConcreteHandlerB handled request " + request);
} else {
super.handleRequest(request);
}
}
}
// 具体处理者类C
class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 20) {
System.out.println("ConcreteHandlerC handled request " + request);
} else {
super.handleRequest(request);
}
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 创建处理者对象
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();
// 组装责任链
handlerA.setNextHandler(handlerB);
handlerB.setNextHandler(handlerC);
// 提交请求
int[] requests = {3, 14, 22, 7, 18};
for (int request : requests) {
handlerA.handleRequest(request);
}
}
}
运行结果
在上述代码中,客户端创建了三个处理者 ConcreteHandlerA
、ConcreteHandlerB
和 ConcreteHandlerC
,并将它们链接起来形成责任链。每个处理者根据请求的值决定是否处理请求,或者将请求传递给下一个处理者。运行结果如下:
java
ConcreteHandlerA handled request 3
ConcreteHandlerB handled request 14
ConcreteHandlerC handled request 22
ConcreteHandlerA handled request 7
ConcreteHandlerB handled request 18