目录
1.职责链模式
职责链模式将请求的发送者和接收者解耦,从而允许多个对象都有机会处理请求。这种模式通常用于处理请求的分发、过滤等操作。
职责链模式的实现方式比较简单,只需要定义一个处理请求的接口和一些具体处理者,然后让处理者持有下一个处理者的引用即可。客户端可以根据需要创建不同的处理者,并将它们串成一条链,从而实现请求的分发和过滤。
下面是一个职责链模式的实现:
public interface Handler {
void handleRequest(Request request);
}
public class ConcreteHandlerA implements Handler {
private Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(Request request) {
if (request.getType() == RequestType.TYPE1) {
System.out.println("ConcreteHandlerA handles request: " + request.getName());
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
public class ConcreteHandlerB implements Handler {
private Handler nextHandler;
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(Request request) {
if (request.getType() == RequestType.TYPE2) {
System.out.println("ConcreteHandlerB handles request: " + request.getName());
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
public class Request {
private RequestType type;
private String name;
public Request(RequestType type, String name) {
this.type = type;
this.name = name;
}
public RequestType getType() {
return type;
}
public String getName() {
return name;
}
}
public enum RequestType {
TYPE1, TYPE2
}
2.命令模式
命令模式是一种行为型设计模式,它将请求封装成对象,从而允许我们使用不同的请求、队列或者日志来参数化其他对象。这种模式通常用于处理请求的撤销、重做、事务等操作。
命令模式的实现方式比较简单,只需要定义一个命令接口和一些具体命令类,然后让命令类持有执行命令的对象的引用即可。客户端可以根据需要创建不同的命令对象,并将它们传递给执行命令的对象。
在命令模式中,有以下几个角色:
-
Command(命令接口):定义了执行命令的方法 execute。
-
ConcreteCommand(具体命令类):实现了 Command 接口,并持有执行命令的对象的引用。
-
Receiver(执行命令的对象):定义了执行命令的方法,具体命令类将调用该方法来执行命令。
-
Invoker(调用者):持有命令对象的引用,并调用命令对象的 execute 方法来执行命令。
下面是一个命令模式的实现:
public interface Command {
void execute();
}
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.action();
}
}
public class Receiver {
public void action() {
System.out.println("Receiver action");
}
}
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
public void executeCommand() {
command.execute();
}
}
3.解释器模式
解释器模式定义了一种语言,用于解释特定的上下文。这种模式通常用于处理自然语言、数学表达式等问题。
解释器模式的实现方式比较复杂,需要定义一个抽象语法树和一些具体节点类,用于表示语言的语法结构。然后,我们定义一个解释器接口和一些具体解释器类,用于解释语法树中的节点。客户端可以根据需要创建不同的语法树和解释器对象,并将它们组合起来来解决特定的问题。
4.迭代器模式
迭代器模式提供一种方法来访问聚合对象中的元素,而不需要暴露聚合对象的内部表示。这种模式通常用于处理集合类对象的遍历操作。
迭代器模式的实现方式比较简单,只需要定义一个迭代器接口和一个具体迭代器类,然后让聚合对象实现迭代器接口中的方法即可。客户端可以通过迭代器对象来访问聚合对象中的元素。
下面是一个迭代器模式的实现:
public interface Iterator<T> {
boolean hasNext();
T next();
}
public interface Aggregate<T> {
Iterator<T> createIterator();
}
public class ConcreteAggregate<T> implements Aggregate<T> {
private List<T> list = new ArrayList<>();
public void add(T t) {
list.add(t);
}
public void remove(T t) {
list.remove(t);
}
@Override
public Iterator<T> createIterator() {
return new ConcreteIterator<>(list);
}
}
public class ConcreteIterator<T> implements Iterator<T> {
private List<T> list;
private int index = 0;
public ConcreteIterator(List<T> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return index < list.size();
}
@Override
public T next() {
if (hasNext()) {
return list.get(index++);
}
return null;
}
}
在这个例子中,我们定义了一个迭代器接口 Iterator 和一个聚合接口 Aggregate。然后,我们定义了一个具体聚合类 ConcreteAggregate,它实现了 Aggregate 接口中的 createIterator 方法,并持有一个元素列表 list。最后,我们定义了一个具体迭代器类 ConcreteIterator,它实现了 Iterator 接口中的 hasNext 和 next 方法,用于遍历元素列表 list。客户端可以通过调用 ConcreteAggregate 的 createIterator 方法来获取一个迭代器对象,并使用迭代器对象来访问聚合对象中的元素。
5.中介者模式
中介者模式定义了一个中介对象,用于协调一组对象之间的交互。这种模式通常用于处理对象之间的复杂交互,从而减少对象之间的耦合。
中介者模式的实现方式比较简单,只需要定义一个中介者接口和一些具体中介者类,然后让对象持有中介者对象的引用即可。客户端可以通过中介者对象来协调对象之间的交互。
6.备忘录模式
7.观察者模式
观察者模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。这种模式通常用于处理对象之间的消息传递,例如 GUI 中的事件处理。
观察者模式的实现方式比较简单,只需要定义一个主题和一些观察者,然后让观察者注册到主题中即可。当主题的状态发生改变时,它会自动通知所有注册的观察者,并调用它们的更新方法。
下面是一个观察者模式的实现:
public interface Observer {
void update();
}
public 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() {
System.out.println(name + " received message: " + subject.getMessage());
}
}
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
notifyObservers();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
在这个例子中,我们定义了一个观察者接口 Observer 和一个具体观察者类 ConcreteObserver。然后,我们定义了一个主题接口 Subject 和一个具体主题类 ConcreteSubject。在 ConcreteSubject 中,我们定义了一个观察者列表 observers 和一个消息 message,然后实现了 Subject 接口中的三个方法。当消息发生改变时,我们会调用 notifyObservers 方法,通知所有注册的观察者,并调用它们的 update 方法。
8.状态模式
状态模式允许对象在内部状态发生改变时改变它的行为,从而使对象看起来像是改变了它的类。这种模式通常用于处理对象的状态转换和行为变化。
状态模式的实现方式比较简单,只需要定义一个状态接口和一些具体状态类,然后让对象持有当前状态的引用即可。客户端可以通过改变对象的状态来改变它的行为。
9.策略模式
策略模式定义一系列算法,将每个算法都封装起来,并且使它们之间可以互换。这种模式通常用于处理多种算法的情况,例如排序算法中的比较函数。
策略模式的实现方式比较简单,只需要定义一个策略接口和一些具体策略类,然后让客户端持有策略接口的引用即可。客户端可以根据需要选择不同的具体策略类,从而实现不同的算法。
下面是一个策略模式的实现:
public interface SortStrategy {
void sort(int[] array);
}
public class BubbleSortStrategy implements SortStrategy {
@Override
public void sort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
}
public class QuickSortStrategy implements SortStrategy {
@Override
public void sort(int[] array) {
quickSort(array, 0, array.length - 1);
}
private void quickSort(int[] array, int left, int right) {
if (left >= right) {
return;
}
int pivot = partition(array, left, right);
quickSort(array, left, pivot - 1);
quickSort(array, pivot + 1, right);
}
private int partition(int[] array, int left, int right) {
int pivot = array[left];
int i = left, j = right;
while (i < j) {
while (i < j && array[j] >= pivot) {
j--;
}
array[i] = array[j];
while (i < j && array[i] <= pivot) {
i++;
}
array[j] = array[i];
}
array[i] = pivot;
return i;
}
}
public class Sorter {
private SortStrategy sortStrategy;
public Sorter(SortStrategy sortStrategy) {
this.sortStrategy = sortStrategy;
}
public void sort(int[] array) {
sortStrategy.sort(array);
}
}
在这个例子中,我们定义了一个策略接口 SortStrategy 和两个具体策略类 BubbleSortStrategy 和 QuickSortStrategy。然后,我们定义了一个排序器类 Sorter,让它持有策略接口的引用。最后,我们可以通过调用 Sorter 的 sort 方法来排序一个数组,并且可以根据需要选择不同的具体策略类。
10.模板方法模式
模板方法模式定义一个操作中的算法骨架,而将一些步骤延迟到子类中。这种模式通常用于处理算法的变化点,例如排序算法中的比较函数。
模板方法模式的实现方式比较简单,只需要定义一个抽象类和一些具体子类,然后在抽象类中定义一个模板方法,该方法包含算法的骨架,而将一些步骤延迟到具体子类中实现。
下面是一个模板方法模式的实现:
public abstract class AbstractSort {
public final void sort(int[] array) {
if (array == null || array.length <= 1) {
return;
}
doSort(array);
}
protected abstract void doSort(int[] array);
}
public class BubbleSort extends AbstractSort {
@Override
protected void doSort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
}
public class QuickSort extends AbstractSort {
@Override
protected void doSort(int[] array) {
quickSort(array, 0, array.length - 1);
}
private void quickSort(int[] array, int left, int right) {
if (left >= right) {
return;
}
int pivot = partition(array, left, right);
quickSort(array, left, pivot - 1);
quickSort(array, pivot + 1, right);
}
private int partition(int[] array, int left, int right) {
int pivot = array[left];
int i = left, j = right;
while (i < j) {
while (i < j && array[j] >= pivot) {
j--;
}
array[i] = array[j];
while (i < j && array[i] <= pivot) {
i++;
}
array[j] = array[i];
}
array[i] = pivot;
return i;
}
}
在这个例子中,我们定义了一个抽象类 AbstractSort 和两个具体子类 BubbleSort 和 QuickSort。在抽象类中,我们定义了一个模板方法 sort,该方法包含算法的骨架,而将一些步骤延迟到具体子类中实现。在具体子类中,我们实现了 doSort 方法,该方法实现了算法中的具体步骤。最后,我们可以通过调用 sort 方法来排序一个数组。