1、适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期待的另一种接口,从而可以使原本因接口不兼容而无法在一起工作的类能够一起工作。
下面是一个简单的适配器模式示例:
// 目标接口
public interface Target {
void request();
}
// 需要适配的类
public class Adaptee {
public void specificRequest() {
System.out.println("执行特定请求");
}
}
// 适配器类,实现了目标接口,并持有需要适配的类的实例
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest(); // 调用需要适配的类的方法
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee(); // 创建需要适配的类的实例
Target target = new Adapter(adaptee); // 创建适配器类的实例,将需要适配的类的实例传入
target.request(); // 调用目标接口方法,输出:"执行特定请求"
}
}
在这个示例中,Adaptee
类有一个specificRequest
方法,但客户端代码需要的是实现Target
接口的类。因此,我们创建了一个Adapter
类,它实现了Target
接口并持有Adaptee
的实例。在Adapter
类的request
方法中,我们调用了Adaptee
的specificRequest
方法,使得客户端可以通过Target
接口调用Adaptee
的方法,实现了两者的兼容。
2、代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,它提供了一个替代对象(代理)来控制对另一个对象(目标对象)的访问。通过代理对象访问目标对象可以增加额外的功能,如访问控制、缓存、日志等。
下面是一个简单的代理模式示例:
// 目标接口
public interface Target {
void operation();
}
// 目标对象类,实现了目标接口
public class RealTarget implements Target {
@Override
public void operation() {
System.out.println("执行目标对象的操作");
}
}
// 代理类,实现了目标接口,并持有目标对象的引用
public class Proxy implements Target {
private Target target;
public Proxy(Target target) {
this.target = target;
}
@Override
public void operation() {
beforeOperation(); // 在目标对象方法执行前增加一些操作
target.operation(); // 调用目标对象的方法
afterOperation(); // 在目标对象方法执行后增加一些操作
}
private void beforeOperation() {
System.out.println("执行目标对象方法前的操作");
}
private void afterOperation() {
System.out.println("执行目标对象方法后的操作");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Target realTarget = new RealTarget(); // 创建目标对象实例
Proxy proxy = new Proxy(realTarget); // 创建代理实例,将目标对象实例传入
proxy.operation(); // 通过代理调用目标对象的方法,输出:"执行目标对象方法前的操作","执行目标对象的操作","执行目标对象方法后的操作"
}
}
在这个示例中,Target
是目标接口,RealTarget
是实现了该接口的目标对象类。Proxy
是代理类,它也实现了Target
接口,并在其中增加了额外的操作。在客户端代码中,我们通过代理对象来调用目标对象的方法,从而实现了在目标方法执行前后增加额外操作的功能。这就是代理模式的基本原理和用法。
3、策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,它允许你在运行时改变对象的行为。策略模式定义了一系列的算法,并且每一个算法封装起来,使它们可以互相替换。策略模式使得算法可以独立于使用它的客户端变化。
下面是一个简单的策略模式示例:
// 策略接口
public interface Strategy {
public int doOperation(int num1, int num2);
}
// 具体策略类:加法
public class OperationAdd implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
// 具体策略类:减法
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
// 具体策略类:乘法
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
// 上下文类,持有策略对象的引用
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Context context = new Context(new OperationAdd()); // 创建上下文对象,并传入加法策略对象
System.out.println("10 + 5 = " + context.executeStrategy(10, 5)); // 输出:10 + 5 = 15
context = new Context(new OperationSubtract()); // 更改策略为减法
System.out.println("10 - 5 = " + context.executeStrategy(10, 5)); // 输出:10 - 5 = 5
context = new Context(new OperationMultiply()); // 更改策略为乘法
System.out.println("10 * 5 = " + context.executeStrategy(10, 5)); // 输出:10 * 5 = 50
}
}
在这个示例中,我们定义了Strategy
接口,它描述了所有策略应实现的公共接口。然后,我们创建了具体策略类OperationAdd
,OperationSubtract
和OperationMultiply
,它们分别实现了Strategy
接口,并覆盖了doOperation
方法以提供特定的算法实现。接着我们创建了一个Context
类,它持有一个Strategy
引用,并通过executeStrategy
方法执行策略。在客户端代码中,我们可以创建Context
对象并传入所需的策略对象。这样,我们就可以在运行时更改上下文对象的策略,从而改变其行为。
4、模板方法模式
模板方法模式(Template Method Pattern)是一种行为型设计模式,它在一个方法中定义了一个算法的骨架,允许子类在不改变算法结构的情况下重定义某些步骤的具体内容。
下面是一个简单的模板方法模式示例:
// 抽象类,定义了模板方法
public abstract class AbstractClass {
// 模板方法
public void templateMethod() {
specificMethod1();
specificMethod2();
}
// 具体方法1,由子类实现
protected abstract void specificMethod1();
// 具体方法2,由子类实现
protected abstract void specificMethod2();
}
// 具体子类1,实现了抽象类的具体方法
public class ConcreteClass1 extends AbstractClass {
@Override
protected void specificMethod1() {
System.out.println("执行具体子类1的方法1");
}
@Override
protected void specificMethod2() {
System.out.println("执行具体子类1的方法2");
}
}
// 具体子类2,实现了抽象类的具体方法
public class ConcreteClass2 extends AbstractClass {
@Override
protected void specificMethod1() {
System.out.println("执行具体子类2的方法1");
}
@Override
protected void specificMethod2() {
System.out.println("执行具体子类2的方法2");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
AbstractClass class1 = new ConcreteClass1(); // 创建具体子类1的对象
class1.templateMethod(); // 执行模板方法,输出:"执行具体子类1的方法1","执行具体子类1的方法2"
AbstractClass class2 = new ConcreteClass2(); // 创建具体子类2的对象
class2.templateMethod(); // 执行模板方法,输出:"执行具体子类2的方法1","执行具体子类2的方法2"
}
}
在这个示例中,AbstractClass
是一个抽象类,它定义了templateMethod
这个模板方法。模板方法中调用了两个抽象方法specificMethod1
和specificMethod2
,这两个抽象方法由具体的子类来实现。ConcreteClass1
和ConcreteClass2
是两个具体的子类,它们分别实现了抽象类的抽象方法。在客户端代码中,我们创建了两个子类的对象,并分别调用了模板方法。这样,每个子类就可以通过实现抽象方法来提供模板方法的不同实现,而模板方法的结构则保持不变。这就是模板方法模式的基本原理和用法。