欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > Java设计模式

Java设计模式

2024/12/27 4:03:45 来源:https://blog.csdn.net/GuoShao_/article/details/144144352  浏览:    关键词:Java设计模式

Java设计模式

  • 一、观察者设计模式
    • 1.1 概述
    • 1.2 结构
    • 1.3 特点
      • 1. 优点
      • 2. 缺点
      • 3. 使用场景
    • 1.4 JDK中的实现
      • 1. Observable 类
      • 2. Observer 接口
      • 3. 例子
  • 二、模板设计模式
  • 三、单例设计模式
    • 一、懒汉式单例
    • 二、饿汉式单例
  • 四、Builder模式
    • 4.1 概述
    • 4.2 结构
    • 4.3 具体实现
    • 4.4 使用场景
  • 五、责任链设计模式
    • 5.1 定义:
    • 5.2 结构:
    • 5.3 举例
    • 5.4 应用场景
  • 六、策略模式

一、观察者设计模式

1.1 概述

观察者模式(Observer Pattern),又称发布-订阅模式,是一种行为设计模式。它定义了一种一对多的依赖关系,允许多个观察者对象同时监听某个主题对象(Subject)。当主题对象的状态发生变化时,它会通知所有注册的观察者,以便这些观察者能够自动更新自身的状态。

1.2 结构

观察者模式通常包含以下角色:

  1. Subject(主题)
    • 抽象主题角色,负责维护观察者的列表。
    • 提供接口以添加和删除观察者。
    • 通常包括方法如 attach(observer)detach(observer)
  2. ConcreteSubject(具体主题)
    • 实现了 Subject 接口的具体类,维护有关状态。
    • 当状态变化时,调用通知方法以更新所有观察者。
  3. Observer(观察者)
    • 抽象观察者角色,定义更新接口,通常是 update() 方法。
    • 观察者在收到主题变化的通知时调用该方法更新自身状态。
  4. ConcreteObserver(具体观察者)
    • 实现 Observer 接口的具体类。
    • 在更新方法中实现如何响应主题变化。

例子:
在使用微信公众号时,大家都会有这样的体验,当你关注的公众号中有新内容更新的话,它就会推送给关注公众号的微信用户端。我们使用观察者模式来模拟这样的场景

  • 微信用户就是观察者
  • 微信公众号是被观察者
    有多个的微信用户关注了这个公众号。
    在这里插入图片描述
// 观察者接口
public interface Observer {void update(String message); // 接收更新消息
}// 主题接口
public interface Subject {void attach(Observer observer); // 添加观察者void detach(Observer observer); // 删除观察者void notifyObservers(String message); // 通知观察者更新消息
}// 具体主题类
import java.util.ArrayList;
import java.util.List;public class WeChatOfficialAccount implements Subject {private List<Observer> observers = new ArrayList<>(); // 观察者列表@Overridepublic void attach(Observer observer) {observers.add(observer);System.out.println(observer + " 关注了公众号。");}@Overridepublic void detach(Observer observer) {observers.remove(observer);System.out.println(observer + " 取消关注了公众号。");}@Overridepublic void notifyObservers(String message) {System.out.println("公众号发布新内容: " + message);for (Observer observer : observers) {observer.update(message);}}
}// 具体观察者类
public class WeChatUser implements Observer {private String name;public WeChatUser(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " 收到了新推送: " + message);}@Overridepublic String toString() {return name; // 方便打印}
}// 示例用法
public class WeChatObserverPattern {public static void main(String[] args) {// 创建公众号WeChatOfficialAccount wechatAccount = new WeChatOfficialAccount();// 创建微信用户WeChatUser user1 = new WeChatUser("用户A");WeChatUser user2 = new WeChatUser("用户B");WeChatUser user3 = new WeChatUser("用户C");// 用户关注公众号wechatAccount.attach(user1);wechatAccount.attach(user2);wechatAccount.attach(user3);// 发布新内容wechatAccount.notifyObservers("今天的天气真不错!");// 用户取消关注wechatAccount.detach(user2);// 再次发布新内容wechatAccount.notifyObservers("明天有一场特别活动!");}
}

1.3 特点

1. 优点

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 被观察者发送通知,所有注册的观察者都会收到信息(可以实现广播机制)。

2. 缺点

  • 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时。
  • 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃。

3. 使用场景

  • 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时。

1.4 JDK中的实现

在Java中,通过iava.util. Observable类和java.util. observer接口定义了观察者模式,只要实现它们的子类就可以编写 观察者模式实例。

1. Observable 类

Observable 类是抽象目标类(被观察者),它有一个 Vector 集合成员变量,用于保存所有要通知的观察者对象。它的三个重要方法如下:

  • void addObserver(Observer o)
    用于将新的观察者对象添加到集合中。

  • void notifyObservers(Object arg)
    调用集合中的所有观察者对象的 update 方法,通知它们数据发生改变。通常,越晚加入集合的观察者越先得到通知。

  • void setChanged()
    用来设置一个 boolean 类型的内部标志,注明目标对象发生了变化。当它为 true 时,notifyObservers() 才会通知观察者。

2. Observer 接口

Observer 接口是抽象观察者,它监视目标对象的变化。当目标对象发生变化时,观察者会得到通知,并调用 update 方法进行相应的工作。

3. 例子

import java.util.Observable;
import java.util.Observer;// 具体的被观察者类
class WeatherData extends Observable {private float temperature;public void setTemperature(float temperature) {this.temperature = temperature;setChanged(); // 标记状态已更改notifyObservers(temperature); // 通知观察者}
}// 具体的观察者类
class CurrentConditionsDisplay implements Observer {private float temperature;@Overridepublic void update(Observable o, Object arg) {if (o instanceof WeatherData) {this.temperature = (float) arg; // 更新温度display(); // 显示当前条件}}public void display() {System.out.println("Current temperature: " + temperature + " degrees.");}
}// 主程序
public class WeatherStation {public static void main(String[] args) {WeatherData weatherData = new WeatherData();CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();weatherData.addObserver(currentDisplay); // 注册观察者weatherData.setTemperature(25.5f); // 更新温度,触发通知weatherData.setTemperature(30.0f); // 再次更新温度}
}

二、模板设计模式

模板方法设计模式( Template Method Design Pattern ),在一个方法中定义一个算法骨架(即模板),并将某些步骤推迟到子类中实现
该模式在父类中定义一个方法的骨架(或算法的框架),并允许子类在不改变算法结构的情况下重新定义该算法的某些步骤。

举例:

  • 创建一个抽象类,定义算法骨架:
// 抽象类,定义制作饮料的模板方法
abstract class Beverage {// 模板方法,定义了制作饮料的通用步骤public final void prepareRecipe() {boilWater();brew();pourInCup();if (customerWantsCondiments()) { // 钩子方法,子类可以选择重写addCondiments();}}// 具体步骤:烧水private void boilWater() {System.out.println("Boiling water");}// 具体步骤:倒入杯中private void pourInCup() {System.out.println("Pouring into cup");}// 抽象步骤:冲泡饮料,具体实现由子类提供protected abstract void brew();// 抽象步骤:添加调料,具体实现由子类提供protected abstract void addCondiments();// 钩子方法:决定是否添加调料,子类可以选择重写protected boolean customerWantsCondiments() {return true; // 默认添加调料}
}
  • 创建具体的子类,实现抽象类中定义的抽象方法:
// 具体类:茶
class Tea extends Beverage {@Overrideprotected void brew() {System.out.println("Steeping the tea");}@Overrideprotected void addCondiments() {System.out.println("Adding lemon");}// 重写钩子方法,茶默认不添加调料@Overrideprotected boolean customerWantsCondiments() {return false;}
}
// 具体类:咖啡
class Coffee extends Beverage {@Overrideprotected void brew() {System.out.println("Dripping coffee through filter");}@Overrideprotected void addCondiments() {System.out.println("Adding sugar and milk");}
}
  • 客户端代码:
// 客户端代码
public class TemplateMethodPatternExample {public static void main(String[] args) {System.out.println("Preparing tea:");Beverage tea = new Tea();tea.prepareRecipe();System.out.println("\nPreparing coffee:");Beverage coffee = new Coffee();coffee.prepareRecipe();}
}
  • 输出:
Preparing tea:
Boiling water
Steeping the tea
Pouring into cupPreparing coffee:
Boiling water
Dripping coffee through filter
Pouring into cup
Adding sugar and milk
  • Beverage 抽象类定义了模板方法prepareRecipe,并封装了制作饮料的固定步骤
  • brew()addCondiments() 是由子类实现的抽象方法,各自实现了茶和咖啡的制作过程
  • 钩子方法 customerWantsCondiments()允许子类控制是否执行某个步骤

三、单例设计模式

单例模式有以下特点:

  1. 单例类只能有一个实例。
  2. 单例类必须自己创建自己的唯一实例。
  3. 单例类必须给所有其他对象提供这一实例。

一、懒汉式单例

在第一次访问时实例化自己

//懒汉式单例类.在第一次调用的时候实例化自己 
public class Singleton {private Singleton() {}private static Singleton single=null;//静态工厂方法 public static Singleton getInstance() {if (single == null) {  single = new Singleton();}  return single;}
}

Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。

如果走到single == null时发生线程切换,会存在线程不安全的问题。

有三种方式确保懒汉式单例的线程安全问题:

  1. 在getInstance上加上同步:
public static synchronized Singleton getInstance() {if (single == null) {  single = new Singleton();}  return single;
}
  1. 双重检查锁定
public static Singleton getInstance() {if (singleton == null) {  synchronized (Singleton.class) {  if (singleton == null) {  singleton = new Singleton(); }  }  }  return singleton; 
}
  1. 静态内部类
public class Singleton {  private static class LazyHolder {  private static final Singleton INSTANCE = new Singleton();  }  private Singleton (){}  public static final Singleton getInstance() {  return LazyHolder.INSTANCE;  }  
}  
  • 静态内部类的特点
    • LazyHolder 是一个静态内部类,它只有在第一次被访问时才会被加载和初始化。
    • 类加载是线程安全的,JVM 在加载类时会确保类加载的线程安全性。
  • INSTANCE 的初始化
    • LazyHolder 内的 INSTANCE 是一个 static final 的变量,它在 LazyHolder 被加载时完成初始化。
    • static final 保证了 INSTANCE 的初始化只会发生一次,并且由 JVM 保证线程安全。
  • 特点:延迟加载,线程安全,利用类加载机制实现,推荐使用。

第三种比1、2好,即实现了线程安全,又避免了同步带来的性能影响

二、饿汉式单例

饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。

//饿汉式单例类.在类初始化时,已经自行实例化 
public class Singleton1 {private Singleton1() {}private static final Singleton1 single = new Singleton1();//静态工厂方法 public static Singleton1 getInstance() {return single;}
}
  • 特点:线程安全,类加载时初始化,简单实现,但可能会造成资源浪费。

四、Builder模式

4.1 概述

Builder 模式是一种创建型设计模式,通过逐步构建复杂对象,将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的对象。

特点

  1. 将对象构建与其表示分离:
    • 构建复杂对象时,不直接实例化对象,而是使用 Builder 逐步设置属性,最后通过 build() 方法生成对象。
  2. 灵活性和可扩展性:
    • 新增属性或功能只需修改 Builder 类,而无需更改已有的构造代码。
  3. 链式调用:
    • Builder 模式允许链式设置属性,代码可读性更强。

4.2 结构

  1. 产品类(Product)
    • 要创建的复杂对象。
    • 包含多个属性,通常是不可变的。
  2. 构建器类(Builder)
    • 定义构建对象的步骤,每个步骤设置对象的一个属性。
    • 提供 build() 方法返回完整的产品对象。
  3. 具体构建器(ConcreteBuilder)
    • 实现构建器类,包含构建对象的具体逻辑。
  4. 指导者类(Director,可选)
    • 用于控制构建过程的顺序和逻辑。
    • 实际应用中常常省略,由客户端直接调用 Builder。

4.3 具体实现

比如我们现在要自定义一个http发送请求连接:

传统的方式(构造函数)

http对象代码为:

public class HttpRequest {private String url;private String method;private Map<String, String> headers;private String body;public HttpRequest(String url, String method, Map<String, String> headers, String body) {this.url = url;this.method = method;this.headers = headers != null ? headers : new HashMap<>();this.body = body;}@Overridepublic String toString() {return "HttpRequest { " +"url='" + url + '\'' +", method='" + method + '\'' +", headers=" + headers +", body='" + body + '\'' +" }";}
}

构建方式:

public class Main {public static void main(String[] args) {// 构建请求Map<String, String> headers = new HashMap<>();headers.put("Content-Type", "application/json");headers.put("Authorization", "Bearer token123");HttpRequest request = new HttpRequest("https://api.example.com/data", // URL"POST",                         // 方法headers,                        // Headers"{\"key\":\"value\"}"           // Body);System.out.println(request);}
}

问题分析

  • 构造器参数过多时,易混淆或出错,特别是可选参数场景。
  • 代码可读性差

传统方式(Set函数)
http对象代码:

public class HttpRequest {private String url;private String method;private Map<String, String> headers = new HashMap<>();private String body;public void setUrl(String url) {this.url = url;}public void setMethod(String method) {this.method = method;}public void setHeader(String key, String value) {this.headers.put(key, value);}public void setBody(String body) {this.body = body;}@Overridepublic String toString() {return "HttpRequest { " +"url='" + url + '\'' +", method='" + method + '\'' +", headers=" + headers +", body='" + body + '\'' +" }";}
}

构建方式:

public class Main {public static void main(String[] args) {// 构建请求HttpRequest request = new HttpRequest();request.setUrl("https://api.example.com/data");request.setMethod("POST");request.setHeader("Content-Type", "application/json");request.setHeader("Authorization", "Bearer token123");request.setBody("{\"key\":\"value\"}");System.out.println(request);}
}

问题分析

  • 缺点: 无法保证对象的完整性(可能遗漏某些关键参数),容易导致不一致的状态

为什么改用 Builder 模式

  • 参数过多且部分可选时,传统方式可读性差。
  • Builder 模式可以链式调用,代码更清晰。
  • Builder 可封装复杂的初始化逻辑,确保对象的一致性和不可变性。

改进后的builder:

  1. PRODUCT
public class HttpRequest {private String url;        // 必填private  String method;     // 必填private Map<String, String> headers; // 可选private String body;       // 可选// 私有构造器,确保只能通过 Builder 创建private HttpRequest(String url, String method, Map<String, String> headers, String body) {this.url = url;this.method = method;this.headers = headers;this.body = body;}// Getterspublic String getUrl() { return url; }public String getMethod() { return method; }public Map<String, String> getHeaders() { return headers; }public String getBody() { return body; }
}
  1. 构建器类(Builder)
public interface Builder {Builder setUrl(String url);Builder setMethod(String method);Builder addHeader(String key, String value);Builder setBody(String body);HttpRequest build();
}
  1. 具体构建器(ConcreteBuilder)
import java.util.HashMap;
import java.util.Map;public class HttpRequestBuilder implements Builder {private String url;private String method;private Map<String, String> headers = new HashMap<>();private String body;@Overridepublic Builder setUrl(String url) {this.url = url;return this;}@Overridepublic Builder setMethod(String method) {this.method = method;return this;}@Overridepublic Builder addHeader(String key, String value) {this.headers.put(key, value);return this;}@Overridepublic Builder setBody(String body) {this.body = body;return this;}@Overridepublic HttpRequest build() {// 校验必填参数if (url == null || method == null) {throw new IllegalStateException("URL and Method are required!");}return new HttpRequest(url, method, headers, body);}
}
  1. 指导者类(Director,可选)
public class HttpRequestDirector {private final Builder builder;public HttpRequestDirector(Builder builder) {this.builder = builder;}public HttpRequest constructGetRequest(String url) {return builder.setUrl(url).setMethod("GET").build();}public HttpRequest constructPostRequest(String url, String body) {return builder.setUrl(url).setMethod("POST").setBody(body).addHeader("Content-Type", "application/json").build();}
}
  1. 客户端代码
public class Main {public static void main(String[] args) {// 使用 Builder 直接构建HttpRequest request1 = new HttpRequestBuilder().setUrl("https://api.example.com/resource").setMethod("GET").addHeader("Authorization", "Bearer token123").build();System.out.println("Request1: " + request1.getUrl());// 使用 Director 构建HttpRequestDirector director = new HttpRequestDirector(new HttpRequestBuilder());HttpRequest request2 = director.constructPostRequest("https://api.example.com/resource", "{\"key\":\"value\"}");System.out.println("Request2: " + request2.getBody());}
}

Builder 的优势

  1. 强制性:
    • 必须设置关键参数(如 URL、method),否则无法创建对象。
  2. 校验性:
    • build() 方法集中校验,确保对象状态一致。
  3. 可读性:
    • 链式调用使代码更直观,避免参数顺序错误。

通过这种方式,Builder 模式能够显著提升代码的安全性和可靠性,避免遗漏关键参数的问题。

4.4 使用场景

  1. 参数多且部分可选的对象构建
    • 如配置类、网络请求对象(如 oKHttp)、数据库连接对象等。
  2. 不可变对象的构建
    • 需要在对象创建后禁止修改时,如 StringBuilderImmutable 对象。
  3. 复杂初始化逻辑的对象
    • 如需要组合多个子对象或处理复杂逻辑的初始化。
  4. 跨平台对象创建
    • 如需要动态生成 JSON、XML 等结构。
  5. 避免构造器参数过多
    • 如果构造器参数多且顺序容易搞混,Builder 模式可以显著改善代码可读性和安全性。

五、责任链设计模式

5.1 定义:

责任链模式是一种行为设计模式,它允许多个对象按顺序处理请求,而不明确指定处理者。请求沿着链传递,直到某个对象处理它或链的末端。

责任链也可以想象成推卸责任
假设要去公司领取资料,首先向公司前台打听要去哪里领取资料,她告诉我们去”营业窗口“。等到了”营业窗口“后,又被告知应该去”售后部门“。等我们好不容易赶到了”售后部门“,又被告知应该去”资料中心“,因此最后不得不去”资料中心“。

在找到合适的办事人之前,被不断踢给一个又一个人,这就是”推卸责任“。

这种模式,当外部请求程序进行某个处理,但程序暂时无法直接决定由哪个对象负载处理时,就需要推卸责任。这种情况下,可以考虑将多个对象组成一条责任链,然后按照它们在职责链上的顺序一个一个地找出到底应该谁来负责

5.2 结构:

  1. Handler(抽象处理者)
    • 定义处理请求的方法 handleRequest
    • 保存下一个处理者的引用。
  2. ConcreteHandler(具体处理者)
    • 实现具体的处理逻辑。
    • 如果当前处理者无法处理请求,则将请求传递给下一个处理者。
  3. Client(客户端)
    • 向第一个ConcreteHandler角色发送请求的角色,创建责任链并发送请求

5.3 举例

表单验证

  • 场景:用户提交表单时,需要对不同字段进行依次验证(如非空、格式、长度等)。
  • 实现:每个验证规则是责任链中的一个节点,如果当前验证失败,则返回错误;否则传递给下一个验证器。
  1. 定义一个抽象的处理类(Handler):

    abstract class Validator {//定义下一个验证器,即推卸责任的对象protected Validator next;public void setNext(Validator next) {this.next = next;}public abstract boolean validate(String input);
    }
    
  2. 然后,我们创建具体的处理类(ConcreteHandler),它们继承自抽象的处理类,并实现了自己的处理逻辑validate:

    class NotEmptyValidator extends Validator {@Overridepublic boolean validate(String input) {if (input == null || input.isEmpty()) {System.out.println("Field cannot be empty");return false;}return next == null || next.validate(input);}
    }class LengthValidator extends Validator {@Overridepublic boolean validate(String input) {if (input.length() > 10) {System.out.println("Input too long");return false;}return next == null || next.validate(input);}
    }
    
  3. 最后,在客户端代码中创建处理器对象,并将它们连接起来:

    // 客户端代码
    Validator validator = new NotEmptyValidator();
    validator.setNext(new LengthValidator());
    validator.validate("TestInput");
    

5.4 应用场景

  • 多个对象可以处理一个请求,但具体由哪个对象处理该请求在运行时自动确定。
  • 可动态指定一组对象处理请求,或添加新的处理者。
  • 需要在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。

六、策略模式

问题描述:

  • 有各种鸭子(北京鸭、玩具鸭),鸭子有各种行为(叫、飞)
  • 希望能够实现不同的鸭子,显示不同鸭子的信息

传统方法会创建一个抽象类

    public abstract class Duck{public Duck(){}public abstract  void display();//显示鸭子信息public void fly(){System.out.println("鸭子会飞翔");}}

这时候我们要实现具体的鸭子,如玩具鸭,得重写Duck类里的所有方法,因为玩具鸭不会飞。如果要实现北京鸭,又得重写Duck类里的所有方法,因为北京鸭飞飞行能力一般。

传统方式存在问题:

  • 其他鸭子都继承了Duck类,所有fly让所有的子类都会飞了,这是不正确的
  • 即继承带来的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分,会有溢出效应

这时引出策略模式

  • 策略模式中,定义算法族(策略组),分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户

我的理解是:
把原来继承的部分换成一个插槽,这个插槽在策略模式中是一个接口。不同的类插槽处的具体实现不一样,这时候我们可以搭建很多个不一样的积木(策略组),用哪一个就把哪一个积木放到插槽里,不用对插槽进行重新改动,这样后面的其他人也可以重复使用这个积木。策略模式中具体的实现是:积木即继承了接口的实现类,使用哪一个实现了就将其赋值给接口即可,不用重新接口方法。

实例:
策略模式的原则就是,分离变化部分,封装接口,基于接口编程各种功能

将原来的方法定义改成策略接口(创建一个插槽)

public abstract class Duck{//属性,策略接口FlyBehavior flyBehavior;public abstract  void display();//显示鸭子信息public void fly(){//改进if(flyBehavior!=null){flyBehavior.fly();}}//提供给用户,动态变化行为动作(更换插槽里的积木调用这个方法就行)public  void setFlyBehavior(FlyBehavior flyBehavior){this.flyBehavior = flyBehavior;}
}

策略接口:

public interface FlyBehavior {void fly();//子类的具体实现
}

策略组的实现(实现放到接口里的积木):

public class GoodFlyBehavior implements FlyBehavior{@Overridepublic void fly() {System.out.println("飞翔技术高超");}
}
public class NoFlyFlyBehavior implements FlyBehavior{@Overridepublic void fly() {System.out.println("不会飞翔");}
}

不同鸭子的实现:

public class ToyDuck extends Duck{@Overridepublic void display() {//把想放的积木放到插槽里flyBehavior = new NoFlyFlyBehavior();}
}
public class BeiJingDuck extends Duck{@Overridepublic void display() {flyBehavior = new GoodFlyBehavior();}
}

即将项目中变化的部分分离出来,多用组合/聚合,少用继承;用行为类组合,而不是行为的继承。

体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改原有代码,只需要添加一种策略即可。

需要注意的是:没添加一个策略就需要增加一个类,当策略过多是会导致类数目庞大。

实例
通过定义一组算法接口(如存储操作),让不同的存储服务(OSS、MinIO)实现具体的逻辑,客户端只需依赖接口,动态选择实现即可。

// 1. 策略接口
public interface StorageStrategy {void upload(String file);
}// 2. 具体策略:OSS
public class OSSStorage implements StorageStrategy {@Overridepublic void upload(String file) {System.out.println("Uploading to OSS: " + file);}
}// 3. 具体策略:MinIO
public class MinIOStorage implements StorageStrategy {@Overridepublic void upload(String file) {System.out.println("Uploading to MinIO: " + file);}
}
// 4. 上下文类
public class StorageContext {private StorageStrategy strategy;public StorageContext(StorageStrategy strategy) {this.strategy = strategy;}public void setStrategy(StorageStrategy strategy) {this.strategy = strategy;}public void uploadFile(String file) {strategy.upload(file);}
}
// 5. 客户端使用
public class Main {public static void main(String[] args) {StorageContext context = new StorageContext(new OSSStorage());context.uploadFile("file1.txt"); // 使用 OSS 上传context.setStrategy(new MinIOStorage());context.uploadFile("file2.txt"); // 使用 MinIO 上传}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com