# 设计模式
# 单例模式(Singleton Pattern)
单例模式是一种创建型设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式通常用于需要共享资源或控制对资源的访问的情况。
饿汉加载
在饿汉式单例模式中,实例在类加载时就被创建并初始化。因此,无需在
getInstance()
方法中进行延迟实例化。该实例在整个应用程序的生命周期中都是可用的。这种实现方式基于类加载机制的特性,天然线程安全,但可能会造成资源浪费,因为即使在某些情况下没有使用该实例,它仍然被创建。public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; } }
懒汉加载
在懒汉加载模式中,
getInstance()
方法是获取Singleton
实例的静态方法。在该方法中,首先检查instance
是否为null
,如果是,则创建一个新的Singleton
实例;如果不是,则直接返回现有的实例,适用于单线程环境。在多线程环境下,需要考虑线程安全性。public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
# 工厂模式(Factory Pattern)
工厂模式是一种创建型设计模式,它将对象的创建逻辑封装在一个工厂类中,从而隐藏了具体对象的创建细节,并提供了统一的接口来创建对象。
主要参与工厂模式的角色有:
- 抽象产品(Abstract Product):定义了产品的接口,是具体产品类的共同父类或接口。
- 具体产品(Concrete Product):实现了抽象产品接口,是工厂所创建的对象。
- 抽象工厂(Abstract Factory):声明了创建产品的方法,是工厂方法的核心接口。
- 具体工厂(Concrete Factory):实现了抽象工厂接口,负责创建具体产品的实例。
javaCopy code// 抽象产品 - 图形接口
public interface Shape {
void draw();
}
// 具体产品 - 圆形类
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a circle.");
}
}
// 具体产品 - 正方形类
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Drawing a square.");
}
}
// 抽象工厂 - 图形工厂接口
public interface ShapeFactory {
Shape createShape();
}
// 具体工厂 - 圆形工厂
public class CircleFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Circle();
}
}
// 具体工厂 - 正方形工厂
public class SquareFactory implements ShapeFactory {
@Override
public Shape createShape() {
return new Square();
}
}
# 观察者模式(Observer Pattern)
观察者模式(Observer Pattern)是一种行为型设计模式,用于在对象之间建立一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖它的对象都能得到通知并自动更新。
观察者模式涉及以下几个核心角色:
- Subject(主题):也称为被观察者或可观察对象,它维护一系列观察者并通知它们状态的变化。主题可以添加、删除和通知观察者。
- Observer(观察者):观察者是接收主题通知的对象。当主题的状态发生变化时,观察者会根据需求进行相应的处理。
import java.util.ArrayList;
import java.util.List;
// Subject(主题)接口
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
// ConcreteSubject(具体主题)类
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
public void setState(String state) {
this.state = state;
notifyObservers();
}
public String getState() {
return state;
}
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
// Observer(观察者)接口
interface Observer {
void update();
}
// ConcreteObserver(具体观察者)类
class ConcreteObserver implements Observer {
private String name;
private ConcreteSubject subject;
public ConcreteObserver(String name, ConcreteSubject subject) {
this.name = name;
this.subject = subject;
}
@Override
public void update() {
String state = subject.getState();
System.out.println("Observer " + name + " received state: " + state);
}
}
// 示例使用
public class ObserverPatternExample {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("Observer1", subject);
Observer observer2 = new ConcreteObserver("Observer2", subject);
subject.attach(observer1);
subject.attach(observer2);
subject.setState("state 1");
// 输出:
// Observer Observer1 received state: state 1
// Observer Observer2 received state: state 1
subject.setState("state 2");
// 输出:
// Observer Observer1 received state: state 2
// Observer Observer2 received state: state 2
subject.detach(observer1);
subject.setState("state 3");
// 输出:
// Observer Observer2 received state: state 3
}
}
Subject
接口定义了添加、删除和通知观察者的方法。ConcreteSubject
类实现了 Subject
接口,并在状态发生变化时通知观察者。Observer
接口定义了观察者的 update()
方法,该方法在接收到通知时执行相应的操作。ConcreteObserver
类实现了 Observer
接口,并根据需要实现 update()
方法。
在示例中,我们创建了一个具体主题 ConcreteSubject
,并创建了两个具体观察者 ConcreteObserver
。首先,我们将观察者添加到主题中,并设置主题的状态。当主题的状态发生变化时,观察者会接收到通知并执行相应的操作。
观察者模式可以实现松耦合的对象间交互,使得主题和观察者之间的关系可以动态建立和解除。它可以广泛应用于事件处理、消息系统、用户界面开发等场景,以实现对象之间的实时通信和状态更新。
# 适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern)是一种结构型设计模式,用于将一个类的接口转换成另一个客户端所期望的接口。适配器模式允许不兼容的类能够一起工作,解决了接口不匹配的问题。
适配器模式涉及以下几个核心角色:
目标接口(Target Interface):定义客户端所期望的接口,适配器将目标接口转换为被适配者的接口。
被适配者(Adaptee):存在于系统中的类,其接口与目标接口不匹配。
适配器(Adapter):实现了目标接口,并持有一个被适配者的实例,在目标接口的方法中调用被适配者的方法来完成适配。
// 目标接口
interface Target {
void request();
}
// 被适配者类
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee's specificRequest() called");
}
}
// 适配器类
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
// 示例使用
public class AdapterPatternExample {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.request(); // 通过适配器调用被适配者的方法
}
}
在上述示例中,我们有一个目标接口 Target
,其中定义了客户端所期望的方法 request()
。然后,我们有一个被适配者类 Adaptee
,其中有一个不匹配的方法 specificRequest()
。最后,我们创建了一个适配器类 Adapter
,它实现了目标接口 Target
,并持有一个被适配者的实例,在目标接口的方法中调用被适配者的方法。
在示例中,我们通过创建一个适配器对象 Adapter
,将 Adaptee
转换为了目标接口 Target
。通过调用目标接口的方法 request()
,实际上是在调用被适配者的方法 specificRequest()
。
适配器模式的优点在于可以使不兼容的类协同工作,增强了代码的复用性和灵活性。它允许在不改变现有代码的情况下进行接口的适配,符合开闭原则。然而,适配器模式也有一些缺点,如可能增加代码复杂性,引入了额外的间接层等。
适配器模式适用于
以下场景:
- 当需要将一个已经存在的类集成到另一个接口时。
- 当需要重用某个类,但是其接口与系统要求的接口不匹配时。
- 当需要创建一个可重用的类,该类与其他不相关的类或不可预见的类协同工作时。
通过适配器模式,可以有效地解决不同接口之间的兼容性问题,使得不同类能够协同工作,提高了代码的灵活性和可维护性。
← SQL 语句