12.Android 十一种设计模式 设计理念独家解读 在大型企业级APP的综合应用

208 阅读20分钟

风格-AI.jpg

1.设计模式的7大设计原则

7大设计原则主要包括 开闭原则、 里氏替换原则、 依赖倒置原则、 单一职责原则、 接口隔离原则、 最小知识原则 和合成复用原则 下面是一个展示设计模式7大原则及其关系的可视化图表,采用了环形布局展示各原则间的内在联系:

1.1 开闭原则 (Open-Closed Principle)

  • 核心思想:软件实体应对扩展开放,对修改关闭

  • 关键实现

    • 使用抽象化定义
    • 利用多态机制
    • 依赖接口编程

1.2. 里氏替换原则 (Liskov Substitution Principle)

  • 核心思想:子类必须能够替换其父类而不影响程序正确性

  • 关键要点

    • 子类不改变父类方法行为
    • 不强加额外约束条件
    • 不削弱前置条件
  • 应用场景

    • 继承体系设计
    • 多态实现
    • 接口实现

1.3. 依赖倒置原则 (Dependency Inversion Principle)

  • 核心思想

    • 高层模块不依赖低层模块
    • 二者都应依赖抽象

1.4. 单一职责原则 (Single Responsibility Principle)

  • 核心思想:一个类只应有一个引起变化的原因

  • 判断标准

    • 类描述是否包含"和"(如"用户管理和日志记录")
    • 方法是否服务于不同功能

1.5. 接口隔离原则 (Interface Segregation Principle)

  • 核心思想:客户端不应被迫依赖它不使用的接口

  • 实现方法

    • 将臃肿接口拆分为多个专门接口
    • 使用接口继承建立层次关系
  • 优势

    • 减少接口污染
    • 降低依赖耦合
    • 提高系统灵活性

1.6. 最小知识原则 (Law of Demeter)

  • 核心思想:一个对象应对其他对象保持最少的了解

  • 通信规则

    • 与自身成员通信
    • 与方法参数通信
    • 与自身创建的对象通信
    • 与直接组件对象通信

1.7. 合成复用原则 (Composite Reuse Principle)

  • 核心思想:优先使用对象组合,而不是继承

  • 应用场景

    • 功能扩展
    • 代码复用
    • 系统重构

七大原则关联关系

deepseek_mermaid_20250708_66856d.png

  1. 开闭原则是核心目标:其他原则都在不同角度支持开闭原则的实现
  2. 里氏替换是继承基础:保证子类替换父类时的系统稳定性
  3. 依赖倒置是架构关键:通过抽象解耦高层与低层模块
  4. 单一职责是设计前提:确保类的内聚性和可维护性
  5. 接口隔离是抽象手段:提供精确的抽象定义
  6. 最小知识是通信准则:限制对象间的过度耦合
  7. 合成复用是实践方案:提供比继承更灵活的复用方式

这七大原则共同构成了面向对象设计的基石,它们相互关联、相互支持,为创建灵活、可维护、可扩展的软件系统提供了理论指导和实践准则。

2.java的三大特性和设计模式的关系

Java三大特性与设计模式的关系图

deepseek_mermaid_20250708_fd883e.png

2.1 封装

作用:隐藏对象内部状态,提供公共访问方式
设计模式应用

  • 工厂模式:封装对象创建过程
  • 单例模式:封装实例化控制
  • 外观模式:封装子系统复杂接口

2.2 继承

作用:实现代码复用和扩展
设计模式应用

  • 模板方法:父类定义算法骨架
  • 装饰器模式:继承+组合实现功能扩展
  • 适配器模式:通过继承适配接口

2.3 多态

作用:同一操作作用于不同对象产生不同行为
设计模式应用

  • 策略模式:运行时选择算法
  • 观察者模式:通知不同类型观察者
  • 命令模式:执行不同命令对象

Java三大特性与设计模式的关系可以概括为:

  • 封装是设计模式实现的基础,用于隐藏复杂性和保护内部状态
  • 继承为设计模式提供扩展能力,实现代码复用和层次化结构
  • 多态赋予设计模式灵活性,支持运行时行为变化和接口统一

3.设计模式3大类型

设计模式全景图

deepseek_mermaid_20250708_b3d810.png

3大设计模式主要包括创建型、结构型和行为型

3.1 创建型模式

目的:解耦对象的创建过程

模式应用场景关键特点
单例(Singleton)全局唯一对象私有构造、静态实例
工厂方法(Factory)创建相关对象族子类决定实例化类
抽象工厂(Abstract)创建产品家族工厂的工厂
建造者(Builder)创建复杂对象分步构建、分离构造与表示
原型(Prototype)克隆对象实现Cloneable接口

3.2 结构型模式

目的:组合类和对象形成更大结构

模式应用场景关键特点
适配器(Adapter)接口转换兼容不兼容接口
组合(Composite)树形结构部分-整体层次结构
装饰器(Decorator)动态添加功能透明扩展功能
外观(Facade)简化复杂系统统一入口接口
享元(Flyweight)大量细粒度对象共享内部状态与外部状态分离
代理(Proxy)控制对象访问间接访问对象

3.3 行为型模式

目的:管理对象间的交互和职责分配

模式应用场景关键特点
责任链(Chain)请求处理链多个对象处理请求
命令(Command)封装请求命令对象化
解释器(Interpreter)特定语言解释定义语法规则
迭代器(Iterator)集合遍历统一遍历接口
中介者(Mediator)对象间交互集中控制通信
备忘录(Memento)状态恢复保存/恢复对象状态
观察者(Observer)一对多依赖主题-观察者机制
状态(State)状态改变行为状态封装行为
策略(Strategy)算法替换封装可互换算法
模板方法(Template)算法骨架步骤固定,实现可变
访问者(Visitor)元素操作分离双重分发机制

4.Android 写一个完整的语音项目,包含,单例,构造者模式,工厂模式,策略模式,观察者模式,责任链模式,动态代理,模板方法,适配器模式,享元模式,外观模式

4.1 架构图说明

deepseek_mermaid_20250708_b27dd5.png

4.2 源码

// 1. 单例模式 - 全局配置管理
public class VoiceConfigManager {
    private static volatile VoiceConfigManager instance;
    private String language = "zh-CN";
    private int volume = 80;
    private boolean useOfflineMode = false;

    private VoiceConfigManager() {}

    public static VoiceConfigManager getInstance() {
        if (instance == null) {
            synchronized (VoiceConfigManager.class) {
                if (instance == null) {
                    instance = new VoiceConfigManager();
                }
            }
        }
        return instance;
    }

    public void setLanguage(String lang) { this.language = lang; }
    public String getLanguage() { return language; }
    public void setVolume(int volume) { this.volume = volume; }
    public int getVolume() { return volume; }
    public void setUseOfflineMode(boolean use) { this.useOfflineMode = use; }
    public boolean isOfflineMode() { return useOfflineMode; }
}
// 2. 建造者模式 - 语音命令构建
public class VoiceCommand {
    private final String action;
    private final String target;
    private final String params;
    private final String source;

    private VoiceCommand(Builder builder) {
        this.action = builder.action;
        this.target = builder.target;
        this.params = builder.params;
        this.source = builder.source;
    }

    public String getAction() { return action; }
    public String getTarget() { return target; }
    public String getParams() { return params; }
    public String getSource() { return source; }

    public static class Builder {
        private String action;
        private String target;
        private String params = "";
        private String source = "user";

        public Builder setAction(String action) {
            this.action = action;
            return this;
        }

        public Builder setTarget(String target) {
            this.target = target;
            return this;
        }

        public Builder setParams(String params) {
            this.params = params;
            return this;
        }

        public Builder setSource(String source) {
            this.source = source;
            return this;
        }

        public VoiceCommand build() {
            return new VoiceCommand(this);
        }
    }
}
// 3. 工厂模式 - 语音处理器创建
public interface VoiceProcessor {
    String process(String audio);
}
public class SpeechProcessorFactory {
    public static VoiceProcessor createProcessor(String type) {
        VoiceConfigManager config = VoiceConfigManager.getInstance();

        if ("RECOGNITION".equals(type)) {
            if (config.isOfflineMode()) {
                return new OfflineSpeechRecognizer();
            }
            return new OnlineSpeechRecognizer();
        } else if ("SYNTHESIS".equals(type)) {
            if (config.isOfflineMode()) {
                return new OfflineSpeechSynthesizer();
            }
            return new OnlineSpeechSynthesizer();
        }
        throw new IllegalArgumentException("Invalid processor type");
    }
}

class OnlineSpeechRecognizer implements VoiceProcessor {
    @Override
    public String process(String audio) {
        return "Online Recognition: " + audio;
    }
}

class OfflineSpeechRecognizer implements VoiceProcessor {
    @Override
    public String process(String audio) {
        return "Offline Recognition: " + audio;
    }
}

class OnlineSpeechSynthesizer implements VoiceProcessor {
    @Override
    public String process(String text) {
        return "Synthesized: " + text;
    }
}

class OfflineSpeechSynthesizer implements VoiceProcessor {
    @Override
    public String process(String text) {
        return "Offline Synthesized: " + text;
    }
}
// 4. 策略模式 - 语音识别算法切换
public interface RecognitionStrategy {
    String recognize(byte[] audioData);
}
public class AccurateRecognition implements RecognitionStrategy {
    @Override
    public String recognize(byte[] audioData) {
        return "Accurate result: " + new String(audioData);
    }
}
public class FastRecognition implements RecognitionStrategy {
    @Override
    public String recognize(byte[] audioData) {
        return "Fast result: " + new String(audioData).substring(0, 10);
    }
}
public class VoiceRecognitionContext {
    private RecognitionStrategy strategy = new FastRecognition();

    public void setStrategy(RecognitionStrategy strategy) {
        this.strategy = strategy;
    }

    public String executeRecognition(byte[] audioData) {
        return strategy.recognize(audioData);
    }
}
// 5. 观察者模式 - 语音识别结果通知
public interface RecognitionListener {
    void onRecognitionResult(String result);
    void onError(String error);
}
public class VoiceRecognitionSubject {
    private final List<RecognitionListener> listeners = new ArrayList<>();

    public void addListener(RecognitionListener listener) {
        listeners.add(listener);
    }

    public void removeListener(RecognitionListener listener) {
        listeners.remove(listener);
    }

    public void notifyResult(String result) {
        for (RecognitionListener listener : listeners) {
            listener.onRecognitionResult(result);
        }
    }

    public void notifyError(String error) {
        for (RecognitionListener listener : listeners) {
            listener.onError(error);
        }
    }
}
// 6. 责任链模式 - 语音命令处理
public abstract class CommandHandler {
    protected CommandHandler next;

    public void setNext(CommandHandler next) {
        this.next = next;
    }

    public abstract boolean handleCommand(VoiceCommand command);
}
public class MusicCommandHandler extends CommandHandler {
    @Override
    public boolean handleCommand(VoiceCommand command) {
        if ("PLAY".equals(command.getAction()) && "MUSIC".equals(command.getTarget())) {
            System.out.println("Playing music: " + command.getParams());
            return true;
        }
        return next != null && next.handleCommand(command);
    }
}
public class SystemCommandHandler extends CommandHandler {
    @Override
    public boolean handleCommand(VoiceCommand command) {
        if ("SET".equals(command.getAction()) && "VOLUME".equals(command.getTarget())) {
            try {
                int volume = Integer.parseInt(command.getParams());
                VoiceConfigManager.getInstance().setVolume(volume);
                System.out.println("Volume set to: " + volume);
                return true;
            } catch (NumberFormatException e) {
                System.out.println("Invalid volume value");
            }
        }
        return next != null && next.handleCommand(command);
    }
}
public class WeatherCommandHandler extends CommandHandler {
    @Override
    public boolean handleCommand(VoiceCommand command) {
        if ("GET".equals(command.getAction()) && "WEATHER".equals(command.getTarget())) {
            System.out.println("Fetching weather for: " + command.getParams());
            return true;
        }
        return next != null && next.handleCommand(command);
    }
}
// 7. 动态代理 - 语音服务日志记录
public interface IVoiceService {
    void processVoice(byte[] data);
    String synthesizeText(String text);
}
public class RealVoiceService implements IVoiceService {
    @Override
    public void processVoice(byte[] data) {
        System.out.println("Processing voice data...");
    }

    @Override
    public String synthesizeText(String text) {
        return "Synthesized: " + text;
    }
}
public class VoiceServiceProxy implements InvocationHandler {
    private final Object target;

    public VoiceServiceProxy(Object target) {
        this.target = target;
    }

    public static IVoiceService createProxy() {
        return (IVoiceService) Proxy.newProxyInstance(
                VoiceServiceProxy.class.getClassLoader(),
                new Class[]{IVoiceService.class},
                new VoiceServiceProxy(new RealVoiceService()));
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("==> Calling method: " + method.getName());
        long start = System.currentTimeMillis();
        Object result = method.invoke(target, args);
        long duration = System.currentTimeMillis() - start;
        System.out.println("<== Method " + method.getName() + " executed in " + duration + "ms");
        return result;
    }
}
// 8. 模板方法 - 语音处理流程
public abstract class VoiceProcessingTemplate {
    public final String process(byte[] audio) {
        byte[] cleaned = preProcess(audio);
        String text = recognize(cleaned);
        String response = handleCommand(text);
        return synthesizeResponse(response);
    }

    protected byte[] preProcess(byte[] audio) {
        System.out.println("Applying noise reduction...");
        // 模拟降噪处理
        return Arrays.copyOf(audio, audio.length);
    }

    protected abstract String recognize(byte[] audio);

    protected String handleCommand(String text) {
        System.out.println("Handling command: " + text);
        // 这里会连接责任链处理命令
        return "Processed: " + text;
    }

    protected String synthesizeResponse(String response) {
        System.out.println("Synthesizing response...");
        return response;
    }
}
public class StandardVoiceProcessing extends VoiceProcessingTemplate {
    private final VoiceRecognitionContext recognitionContext = new VoiceRecognitionContext();

    @Override
    protected String recognize(byte[] audio) {
        return recognitionContext.executeRecognition(audio);
    }
}
// 9. 适配器模式 - 第三方语音库集成
public class ThirdPartyRecognizer {
    public String recognize(byte[] input) {
        return "ThirdParty result: " + input.length + " bytes";
    }
}
public class ThirdPartyRecognizerAdapter implements VoiceProcessor {
    private final ThirdPartyRecognizer thirdPartyRecognizer;

    public ThirdPartyRecognizerAdapter(ThirdPartyRecognizer recognizer) {
        this.thirdPartyRecognizer = recognizer;
    }

    @Override
    public String process(String audio) {
        byte[] data = audio.getBytes();
        return thirdPartyRecognizer.recognize(data);
    }
}
// 10. 享元模式 - 语音命令解析器复用
public class CommandParserFactory {
    private static final Map<String, CommandParser> parserCache = new HashMap<>();

    public static CommandParser getParser(String language) {
        if (!parserCache.containsKey(language)) {
            parserCache.put(language, new CommandParser(language));
        }
        return parserCache.get(language);
    }
}
public class CommandParser {
    private final String language;

    public CommandParser(String language) {
        this.language = language;
        // 初始化解析器(模拟耗时操作)
        System.out.println("Initializing parser for: " + language);
    }

    public VoiceCommand parse(String text) {
        // 简化的解析逻辑
        if (text.contains("播放")) {
            return new VoiceCommand.Builder()
                    .setAction("PLAY")
                    .setTarget("MUSIC")
                    .setParams(text.replace("播放", "").trim())
                    .build();
        } else if (text.contains("天气")) {
            return new VoiceCommand.Builder()
                    .setAction("GET")
                    .setTarget("WEATHER")
                    .setParams(text.replace("天气", "").trim())
                    .build();
        }
        return new VoiceCommand.Builder()
                .setAction("UNKNOWN")
                .setTarget("UNKNOWN")
                .setParams(text)
                .build();
    }
}
// 11. 外观模式 - 语音系统统一接口
public class VoiceAssistantFacade {
    private final VoiceRecognitionSubject recognitionSubject = new VoiceRecognitionSubject();
    private final VoiceProcessingTemplate processingTemplate = new StandardVoiceProcessing();
    private final CommandHandler commandHandlerChain;

    private final IVoiceService voiceService;

    public VoiceAssistantFacade() {
        // 创建责任链
        CommandHandler musicHandler = new MusicCommandHandler();
        CommandHandler weatherHandler = new WeatherCommandHandler();
        CommandHandler systemHandler = new SystemCommandHandler();

        musicHandler.setNext(weatherHandler);
        weatherHandler.setNext(systemHandler);

        this.commandHandlerChain = musicHandler;

        // 创建带代理的语音服务
        this.voiceService = VoiceServiceProxy.createProxy();
    }

    public void startListening() {
        System.out.println("Listening for voice input...");
        // 模拟语音输入
        byte[] audioData = "播放周杰伦的歌".getBytes();
        processAudio(audioData);
    }

    public void processAudio(byte[] audioData) {
        new Thread(() -> {
            try {
                String result = processingTemplate.process(audioData);
                recognitionSubject.notifyResult(result);
            } catch (Exception e) {
                recognitionSubject.notifyError("Processing error: " + e.getMessage());
            }
        }).start();
    }

    public void addRecognitionListener(RecognitionListener listener) {
        recognitionSubject.addListener(listener);
    }

    // 处理命令的方法(被模板方法调用)
    public String handleCommandInternal(String text) {
        VoiceConfigManager config = VoiceConfigManager.getInstance();
        CommandParser parser = CommandParserFactory.getParser(config.getLanguage());
        VoiceCommand command = parser.parse(text);

        if (commandHandlerChain.handleCommand(command)) {
            return "Command executed: " + command.getAction() + " " + command.getTarget();
        }
        return "Unknown command: " + text;
    }

    // 语音合成
    public String synthesize(String text) {
        return voiceService.synthesizeText(text);
    }
}

调用过程:

public class DesignActivity extends AppCompatActivity implements RecognitionListener {

    private VoiceAssistantFacade voiceAssistant;
    private TextView statusView;
    private TextView resultView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_design);

        statusView = findViewById(R.id.status_view);
        resultView = findViewById(R.id.result_view);

        // 初始化语音助手
        voiceAssistant = new VoiceAssistantFacade();
        voiceAssistant.addRecognitionListener(this);

        // 设置配置
        VoiceConfigManager.getInstance().setLanguage("zh-CN");

        // 设置策略
        Button fastBtn = findViewById(R.id.fast_btn);
        Button accurateBtn = findViewById(R.id.accurate_btn);

        fastBtn.setOnClickListener(v -> {
            VoiceRecognitionContext context = new VoiceRecognitionContext();
            context.setStrategy(new FastRecognition());
            updateStatus("Fast recognition strategy set");
        });

        accurateBtn.setOnClickListener(v -> {
            VoiceRecognitionContext context = new VoiceRecognitionContext();
            context.setStrategy(new AccurateRecognition());
            updateStatus("Accurate recognition strategy set");
        });

        // 开始监听
        Button startBtn = findViewById(R.id.start_btn);
        startBtn.setOnClickListener(v -> voiceAssistant.startListening());

        // 语音合成
        Button speakBtn = findViewById(R.id.speak_btn);
        speakBtn.setOnClickListener(v -> {
            String response = voiceAssistant.synthesize("你好,我是语音助手");
            resultView.setText(response);
        });
    }

    private void updateStatus(String message) {
        runOnUiThread(() -> statusView.setText(message));
    }

    @Override
    public void onRecognitionResult(String result) {
        runOnUiThread(() -> {
            resultView.setText(result);
            statusView.setText("Recognition complete");
        });
    }

    @Override
    public void onError(String error) {
        runOnUiThread(() -> {
            resultView.setText("Error: " + error);
            statusView.setText("Recognition failed");
        });
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp"
    android:background="@color/background">

    <!-- 标题区域 -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="语音助手"
        android:textSize="24sp"
        android:textColor="@color/primary"
        android:textStyle="bold"
        android:gravity="center"
        android:layout_marginBottom="24dp"/>

    <!-- 状态显示区域 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginBottom="16dp"
        android:gravity="center_vertical">

        <ImageView
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:src="@drawable/ic_mic"
           />

        <TextView
            android:id="@+id/status_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="准备就绪"
            android:textSize="16sp"
            android:textColor="@color/text_primary"
            android:layout_marginStart="8dp"/>
    </LinearLayout>

    <!-- 结果显示区域 -->
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:cardCornerRadius="8dp"
        app:cardElevation="4dp"
        android:layout_marginBottom="16dp"
        tools:ignore="MissingClass">

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="16dp"
            android:background="@color/card_background">

            <TextView
                android:id="@+id/result_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="识别结果将显示在这里..."
                android:textSize="18sp"
                android:textColor="@color/text_primary"/>
        </ScrollView>
    </androidx.cardview.widget.CardView>

    <!-- 策略选择区域 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginBottom="16dp"
        android:gravity="center">

        <Button
            android:id="@+id/fast_btn"
            android:layout_width="0dp"
            android:layout_height="48dp"
            android:layout_weight="1"
            android:text="快速识别"
            android:backgroundTint="@color/primary"
            android:textColor="@android:color/white"
            android:layout_marginEnd="8dp"/>

        <Button
            android:id="@+id/accurate_btn"
            android:layout_width="0dp"
            android:layout_height="48dp"
            android:layout_weight="1"
            android:text="准确识别"
            android:backgroundTint="@color/secondary"
            android:textColor="@android:color/white"/>
    </LinearLayout>

    <!-- 麦克风按钮 -->
    <Button
        android:id="@+id/start_btn"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="开始语音输入"
        android:textSize="18sp"
        android:drawableStart="@drawable/ic_mic"
        android:drawablePadding="8dp"
        android:backgroundTint="@color/accent"
        android:textColor="@android:color/white"
        android:layout_marginBottom="16dp"
        style="@style/RoundedButton"/>

    <!-- 语音合成按钮 -->
    <Button
        android:id="@+id/speak_btn"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:text="语音合成测试"
        android:textSize="18sp"
        android:drawableStart="@drawable/ic_mic"
        android:drawablePadding="8dp"
        android:backgroundTint="@color/secondary"
        android:textColor="@android:color/white"
        style="@style/RoundedButton"/>

</LinearLayout>

4.3 详细分析

4.3.1. 用户界面层

  • MainActivity:用户交互界面
  • RecognitionListener:观察者模式的UI监听器

4.3.2. 外观层(核心协调者)

  • VoiceAssistantFacade

    • 提供统一系统入口
    • 协调各子系统工作
    • 管理监听器注册

4.3.3. 语音处理引擎

(1) 模板方法模式
  • VoiceProcessingTemplate: process(byte[] audio) { 1. 预处理(preProcess) 2. 语音识别(recognize) 3. 命令处理(handleCommand) 4. 响应合成(synthesizeResponse) }
(2) 策略模式
  • RecognitionStrategy

    • FastRecognition:快速识别
    • AccurateRecognition:精确识别
  • 支持运行时动态切换算法

(3) 适配器模式
  • ThirdPartyRecognizerAdapter

    • 集成第三方语音识别库
    • 统一接口对接系统
(4) 工厂模式
  • SpeechProcessorFactory

    createProcessor(type) {
      if (离线模式) return OfflineProcessor
      else return OnlineProcessor
    }
    

4.3.4. 命令处理系统

(1) 享元模式
  • CommandParserFactory

    • 缓存和复用命令解析器
    • 按语言类型共享解析器
(2) 建造者模式
  • VoiceCommand.Builder

    new VoiceCommand.Builder()
        .setAction("PLAY")
        .setTarget("MUSIC")
        .setParams("周杰伦")
        .build();
    
(3) 责任链模式
  • CommandHandler

    • MusicCommandHandler:处理音乐命令
    • WeatherCommandHandler:处理天气查询
    • SystemCommandHandler:处理系统设置
    • 链式传递未处理命令

4.3.5. 服务层

(1) 动态代理
  • VoiceServiceProxy

    • 增强真实语音服务
    • 添加日志、性能监控等横切关注点
(2) 单例模式
  • VoiceConfigManager

    • 全局唯一配置管理
    • 统一访问点

4.3.6. 通知机制

  • 观察者模式

    • VoiceRecognitionSubject:主题
    • RecognitionListener:观察者接口
    • 支持多监听器注册
    • 状态变化自动通知

设计模式协同关系

设计模式主要职责协同对象
外观模式系统入口协调所有子系统
模板方法定义处理流程调用策略、工厂、责任链
策略模式算法切换被模板方法调用
工厂模式对象创建为模板方法提供处理器
享元模式对象复用为命令处理提供解析器
建造者构建复杂对象创建语音命令对象
责任链命令处理接收模板方法传递的命令
观察者状态通知接收外观模式的通知请求
动态代理服务增强包装真实语音服务
单例配置管理全局共享配置信息

5.项目中其他经典的场景,使用设计模式

5.1.抖音应用:图片要处理,美颜

在 Android 图片处理(旋转、缩放、裁剪、滤镜等)场景中

// 策略模式:滤镜算法接口
interface FilterStrategy {
    Bitmap apply(Bitmap input);
}

// 具体策略实现
class VintageFilter implements FilterStrategy {
    @Override public Bitmap apply(Bitmap input) {
        // 简化的怀旧滤镜实现
        Bitmap output = Bitmap.createBitmap(input.getWidth(), input.getHeight(), input.getConfig());
        Canvas canvas = new Canvas(output);
        Paint paint = new Paint();
        paint.setColorFilter(null);
        canvas.drawBitmap(input, 0, 0, paint);
        return output;
    }
}

class BlurFilter implements FilterStrategy {
    @Override public Bitmap apply(Bitmap input) {
        // 简化的模糊实现
        Bitmap output = Bitmap.createScaledBitmap(input,
                input.getWidth()/2, input.getHeight()/2, true);
        return Bitmap.createScaledBitmap(output,
                input.getWidth(), input.getHeight(), true);
    }
}

// 工厂模式:创建滤镜
class FilterFactory {
    public static FilterStrategy createFilter(String type) {
        switch (type.toUpperCase()) {
            case "VINTAGE": return new VintageFilter();
            case "BLUR": return new BlurFilter();
            default: throw new IllegalArgumentException("Unknown filter: " + type);
        }
    }
}

// 命令模式:封装操作
interface ImageCommand {
    Bitmap execute(Bitmap input);
    Bitmap undo(Bitmap input);
}

// 基础命令
abstract class BaseCommand implements ImageCommand {
    protected Bitmap originalState;

    @Override
    public Bitmap execute(Bitmap input) {
        originalState = input.copy(input.getConfig(), false);
        return process(input);
    }

    @Override
    public Bitmap undo(Bitmap input) {
        return originalState;
    }

    protected abstract Bitmap process(Bitmap input);
}

// 具体命令
class RotateCommand extends BaseCommand {
    private final float degrees;

    public RotateCommand(float degrees) {
        this.degrees = degrees;
    }

    @Override
    protected Bitmap process(Bitmap input) {
        Matrix matrix = new Matrix();
        matrix.postRotate(degrees);
        return Bitmap.createBitmap(input, 0, 0,
                input.getWidth(), input.getHeight(), matrix, true);
    }
}

class ScaleCommand extends BaseCommand {
    private final float scaleX, scaleY;

    public ScaleCommand(float scaleX, float scaleY) {
        this.scaleX = scaleX;
        this.scaleY = scaleY;
    }

    @Override
    protected Bitmap process(Bitmap input) {
        Matrix matrix = new Matrix();
        matrix.postScale(scaleX, scaleY);
        return Bitmap.createBitmap(input, 0, 0,
                input.getWidth(), input.getHeight(), matrix, true);
    }
}

class CropCommand extends BaseCommand {
    private final Rect rect;

    public CropCommand(int left, int top, int right, int bottom) {
        this.rect = new Rect(left, top, right, bottom);
    }

    @Override
    protected Bitmap process(Bitmap input) {
        return Bitmap.createBitmap(input, rect.left, rect.top,
                rect.width(), rect.height());
    }
}

class FilterCommand extends BaseCommand {
    private final FilterStrategy filter;

    public FilterCommand(String filterType) {
        this.filter = FilterFactory.createFilter(filterType);
    }

    @Override
    protected Bitmap process(Bitmap input) {
        return filter.apply(input);
    }
}

// 责任链模式:处理管道
class ProcessingPipeline {
    private final List<ImageCommand> commands = new ArrayList<>();

    public ProcessingPipeline addCommand(ImageCommand command) {
        commands.add(command);
        return this;
    }

    public Bitmap execute(Bitmap input) {
        Bitmap result = input;
        for (ImageCommand cmd : commands) {
            result = cmd.execute(result);
        }
        return result;
    }
}

// 装饰者模式:添加额外功能
abstract class ImageDecorator implements ImageCommand {
    protected ImageCommand wrapped;

    public ImageDecorator(ImageCommand wrapped) {
        this.wrapped = wrapped;
    }
}

class WatermarkDecorator extends ImageDecorator {
    private final Bitmap watermark;

    public WatermarkDecorator(ImageCommand wrapped, Bitmap watermark) {
        super(wrapped);
        this.watermark = watermark;
    }

    @Override
    public Bitmap execute(Bitmap input) {
        Bitmap processed = wrapped.execute(input);
        return addWatermark(processed, watermark);
    }

    @Override
    public Bitmap undo(Bitmap input) {
        return wrapped.undo(input);
    }

    private Bitmap addWatermark(Bitmap base, Bitmap watermark) {
        Bitmap result = base.copy(base.getConfig(), true);
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(watermark,
                base.getWidth() - watermark.getWidth() - 20,
                base.getHeight() - watermark.getHeight() - 20, null);
        return result;
    }
}

// 建造者模式:构建处理流程
class ImageProcessorBuilder {
    private final ProcessingPipeline pipeline = new ProcessingPipeline();
    private final Stack<ImageCommand> commandStack = new Stack<>();

    public ImageProcessorBuilder rotate(float degrees) {
        ImageCommand cmd = new RotateCommand(degrees);
        pipeline.addCommand(cmd);
        commandStack.push(cmd);
        return this;
    }

    public ImageProcessorBuilder scale(float scale) {
        return scale(scale, scale);
    }

    public ImageProcessorBuilder scale(float scaleX, float scaleY) {
        ImageCommand cmd = new ScaleCommand(scaleX, scaleY);
        pipeline.addCommand(cmd);
        commandStack.push(cmd);
        return this;
    }

    public ImageProcessorBuilder crop(int left, int top, int right, int bottom) {
        ImageCommand cmd = new CropCommand(left, top, right, bottom);
        pipeline.addCommand(cmd);
        commandStack.push(cmd);
        return this;
    }

    public ImageProcessorBuilder applyFilter(String filterType) {
        ImageCommand cmd = new FilterCommand(filterType);
        pipeline.addCommand(cmd);
        commandStack.push(cmd);
        return this;
    }

    public ImageProcessorBuilder addWatermark(Bitmap watermark) {
        if (!commandStack.isEmpty()) {
            ImageCommand lastCmd = commandStack.peek();
            WatermarkDecorator decorator = new WatermarkDecorator(lastCmd, watermark);
            pipeline.addCommand(decorator);
            commandStack.push(decorator);
        }
        return this;
    }

    public Bitmap execute(Bitmap input) {
        return pipeline.execute(input);
    }
}

// 外观模式:简化客户端调用
class ImageProcessorFacade {
    private final ImageProcessorBuilder builder = new ImageProcessorBuilder();

    public ImageProcessorFacade rotate(float degrees) {
        builder.rotate(degrees);
        return this;
    }

    public ImageProcessorFacade scale(float scale) {
        builder.scale(scale);
        return this;
    }

    public ImageProcessorFacade crop(int left, int top, int right, int bottom) {
        builder.crop(left, top, right, bottom);
        return this;
    }

    public ImageProcessorFacade applyFilter(String filterType) {
        builder.applyFilter(filterType);
        return this;
    }

    public ImageProcessorFacade addWatermark(Bitmap watermark) {
        builder.addWatermark(watermark);
        return this;
    }

    public Bitmap process(Bitmap input) {
        return builder.execute(input);
    }
}
// 客户端使用示例
public class ImageProcessingDemo {
    public static void main(String[] args) {
        // 原始图片
        Bitmap original = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888);
        Bitmap watermark = Bitmap.createBitmap(100, 40, Bitmap.Config.ARGB_8888);

        // 使用外观模式简化调用
        ImageProcessorFacade processor = new ImageProcessorFacade();
        Bitmap result = processor
                .rotate(90)
                .scale(0.8f)
                .crop(100, 100, 700, 700)
                .applyFilter("VINTAGE")
                .addWatermark(watermark)
                .process(original);

        System.out.println("Processing completed. Result size: "
                + result.getWidth() + "x" + result.getHeight());

        // 工厂模式创建独立滤镜
        FilterStrategy blurFilter = FilterFactory.createFilter("BLUR");
        Bitmap blurred = blurFilter.apply(original);
    }
}

架构图:

[原始图片]
     │
     ▼
[外观控制台]───用户点击按钮───▶ 
     │
     ▼
[建造者装配站]─┬─旋转模块🔄
              ├─缩放模块📏
              ├─裁剪模块✂️
              └─滤镜卡带🎞️
     │
     ▼
[处理流水线]───→ 🖼️ ──旋转─→ 🖼️ ──缩放─→ 🖼️ ──滤镜─→ 🖼️ ──水印─→ 
     │          │         │         │         │         │
     │          │ (保存状态)│ (保存状态)│ (保存状态)│ (保存状态)│
     ▼          ▼         ▼         ▼         ▼         ▼
 [最终结果] + [撤销缓存] + [撤销缓存] + [撤销缓存] + [撤销缓存]
5.2. KEEP应用,运动锻炼场景

运动类型分为3种,计时,计数,计分

计数:俯卧撑

计时:平板支撑

计分:广播体操

他们有相同的一些流程可以复用: 都来自一个引擎,引擎的初始化,释放是相同的, 不同的是引擎统计是否计数,计时,计分 输入是一种类型的运动,输出可能是分数,时间,个数! 里面需要用到哪些设计模式 策略模式,工厂模式,模板方法, 继续优化需求:

1).引擎都是来自第三方SDK,有百度的和讯飞的!

2).期望在sdk的方法前面和后面统一添加日志!

3).结果都是通过回调,观察者拿到的结果

4).构造引擎的时候携带多个参数

5).组合模式产生多中健身运动,先做俯卧撑,然后做平板支持,再做广播体操,获取先平板支撑,再俯卧撑,再广播体操,或者先广播体操,再俯卧撑,再平板支撑

// ================== 基础类型和常量 ==================
enum ExerciseType {
    COUNT,  // 计数类型(俯卧撑)
    TIME,   // 计时类型(平板支撑)
    SCORE   // 计分类型(广播体操)
}

enum SDKProvider {
    BAIDU,  // 百度SDK
    IFLYTEK // 讯飞SDK
}

// ================== 结果对象 ==================
class ExerciseResult {
    private final int count;
    private final long time;
    private final float score;

    public ExerciseResult(int count, long time, float score) {
        this.count = count;
        this.time = time;
        this.score = score;
    }

    public int getCount() { return count; }
    public long getTime() { return time; }
    public float getScore() { return score; }

    @Override
    public String toString() {
        if (count > 0) return "计数结果: " + count + "次";
        if (time > 0) return "计时结果: " + time + "ms";
        if (score > 0) return "计分结果: " + score + "分";
        return "无结果";
    }
}

// ================== 观察者模式 ==================
interface ExerciseObserver {
    void onResult(ExerciseResult result);
}

// ================== 模板方法模式 + 策略模式 ==================
abstract class ExerciseEngine {
    private final List<ExerciseObserver> observers = new ArrayList<>();
    protected final EngineConfig config;
    protected final SDKProvider provider;

    public ExerciseEngine(EngineConfig config, SDKProvider provider) {
        this.config = config;
        this.provider = provider;
    }

    // 模板方法
    public final void perform() {
        start();
        execute();
        stop();
    }

    // 公共步骤
    private void start() {
        System.out.println("[" + provider + "] 运动引擎启动");
    }

    private void stop() {
        System.out.println("[" + provider + "] 运动引擎停止");
    }

    // 抽象策略方法
    protected abstract void execute();

    // 观察者管理
    public void registerObserver(ExerciseObserver observer) {
        observers.add(observer);
    }

    public void unregisterObserver(ExerciseObserver observer) {
        observers.remove(observer);
    }

    protected void notifyResult(ExerciseResult result) {
        for (ExerciseObserver observer : observers) {
            observer.onResult(result);
        }
    }
}

// ================== 具体引擎实现 ==================
class PushUpEngine extends ExerciseEngine {
    public PushUpEngine(EngineConfig config, SDKProvider provider) {
        super(config, provider);
    }

    @Override
    protected void execute() {
        System.out.println("[" + provider + "] 执行俯卧撑计数...");
        // 模拟SDK逻辑
        int count = (int) (Math.random() * 30) + 10;
        notifyResult(new ExerciseResult(count, 0, 0));
    }
}

class PlankEngine extends ExerciseEngine {
    public PlankEngine(EngineConfig config, SDKProvider provider) {
        super(config, provider);
    }

    @Override
    protected void execute() {
        System.out.println("[" + provider + "] 执行平板支撑计时...");
        // 模拟SDK逻辑
        long time = (long) (Math.random() * 30000) + 10000;
        notifyResult(new ExerciseResult(0, time, 0));
    }
}

class GymnasticsEngine extends ExerciseEngine {
    public GymnasticsEngine(EngineConfig config, SDKProvider provider) {
        super(config, provider);
    }

    @Override
    protected void execute() {
        System.out.println("[" + provider + "] 执行广播体操评分...");
        // 模拟SDK逻辑
        float score = (float) (Math.random() * 40) + 60;
        notifyResult(new ExerciseResult(0, 0, score));
    }
}

// ================== 建造者模式 ==================
class EngineConfig {
    private final String deviceId;
    private final int sensitivity;
    private final boolean enableSound;

    private EngineConfig(Builder builder) {
        this.deviceId = builder.deviceId;
        this.sensitivity = builder.sensitivity;
        this.enableSound = builder.enableSound;
    }

    public String getDeviceId() { return deviceId; }
    public int getSensitivity() { return sensitivity; }
    public boolean isEnableSound() { return enableSound; }

    public static class Builder {
        private String deviceId = UUID.randomUUID().toString();
        private int sensitivity = 5;
        private boolean enableSound = true;

        public Builder setDeviceId(String deviceId) {
            this.deviceId = deviceId;
            return this;
        }

        public Builder setSensitivity(int sensitivity) {
            if (sensitivity < 1 || sensitivity > 10) {
                throw new IllegalArgumentException("灵敏度范围1-10");
            }
            this.sensitivity = sensitivity;
            return this;
        }

        public Builder setEnableSound(boolean enableSound) {
            this.enableSound = enableSound;
            return this;
        }

        public EngineConfig build() {
            return new EngineConfig(this);
        }
    }
}

// ================== 抽象工厂模式 ==================
interface EngineFactory {
    ExerciseEngine createPushUpEngine(EngineConfig config);
    ExerciseEngine createPlankEngine(EngineConfig config);
    ExerciseEngine createGymnasticsEngine(EngineConfig config);
}

class BaiduEngineFactory implements EngineFactory {
    @Override
    public ExerciseEngine createPushUpEngine(EngineConfig config) {
        return new PushUpEngine(config, SDKProvider.BAIDU);
    }

    @Override
    public ExerciseEngine createPlankEngine(EngineConfig config) {
        return new PlankEngine(config, SDKProvider.BAIDU);
    }

    @Override
    public ExerciseEngine createGymnasticsEngine(EngineConfig config) {
        return new GymnasticsEngine(config, SDKProvider.BAIDU);
    }
}

class IflytekEngineFactory implements EngineFactory {
    @Override
    public ExerciseEngine createPushUpEngine(EngineConfig config) {
        return new PushUpEngine(config, SDKProvider.IFLYTEK);
    }

    @Override
    public ExerciseEngine createPlankEngine(EngineConfig config) {
        return new PlankEngine(config, SDKProvider.IFLYTEK);
    }

    @Override
    public ExerciseEngine createGymnasticsEngine(EngineConfig config) {
        return new GymnasticsEngine(config, SDKProvider.IFLYTEK);
    }
}

// ================== 动态代理模式 ==================
class LoggingProxyHandler implements InvocationHandler {
    private final Object target;
    private final String engineName;

    public LoggingProxyHandler(Object target, String engineName) {
        this.target = target;
        this.engineName = engineName;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long start = System.currentTimeMillis();
        System.out.printf("[%s] 方法 %s 开始执行 | 时间: %d%n",
                engineName, method.getName(), start);

        Object result = method.invoke(target, args);

        long end = System.currentTimeMillis();
        System.out.printf("[%s] 方法 %s 执行完成 | 耗时: %dms%n",
                engineName, method.getName(), end - start);
        return result;
    }

    public static ExerciseEngine createProxy(ExerciseEngine engine, String name) {
        return (ExerciseEngine) Proxy.newProxyInstance(
                engine.getClass().getClassLoader(),
                engine.getClass().getInterfaces(),
                new LoggingProxyHandler(engine, name)
        );
    }
}

// ================== 责任链模式 ==================
interface ExerciseCallback {
    void onExercisePerformed(ExerciseType type, ExerciseResult result);
    void onChainCompleted();
}

abstract class ExerciseHandler {
    protected ExerciseHandler next;

    public void setNext(ExerciseHandler next) {
        this.next = next;
    }

    public abstract void perform(ExerciseCallback callback);
}

class PushUpHandler extends ExerciseHandler {
    private final ExerciseEngine engine;

    public PushUpHandler(ExerciseEngine engine) {
        // 添加动态代理
        this.engine = LoggingProxyHandler.createProxy(engine, "俯卧撑引擎");
    }

    @Override
    public void perform(ExerciseCallback callback) {
        engine.registerObserver(result -> {
            callback.onExercisePerformed(ExerciseType.COUNT, result);
            if (next != null) {
                next.perform(callback);
            } else {
                callback.onChainCompleted();
            }
        });
        engine.perform();
    }
}

class PlankHandler extends ExerciseHandler {
    private final ExerciseEngine engine;

    public PlankHandler(ExerciseEngine engine) {
        // 添加动态代理
        this.engine = LoggingProxyHandler.createProxy(engine, "平板支撑引擎");
    }

    @Override
    public void perform(ExerciseCallback callback) {
        engine.registerObserver(result -> {
            callback.onExercisePerformed(ExerciseType.TIME, result);
            if (next != null) {
                next.perform(callback);
            } else {
                callback.onChainCompleted();
            }
        });
        engine.perform();
    }
}

class GymnasticsHandler extends ExerciseHandler {
    private final ExerciseEngine engine;

    public GymnasticsHandler(ExerciseEngine engine) {
        // 添加动态代理
        this.engine = LoggingProxyHandler.createProxy(engine, "广播体操引擎");
    }

    @Override
    public void perform(ExerciseCallback callback) {
        engine.registerObserver(result -> {
            callback.onExercisePerformed(ExerciseType.SCORE, result);
            if (next != null) {
                next.perform(callback);
            } else {
                callback.onChainCompleted();
            }
        });
        engine.perform();
    }
}

// 责任链建造者
class ExerciseChainBuilder {
    private final List<ExerciseHandler> handlers = new ArrayList<>();

    public ExerciseChainBuilder addHandler(ExerciseHandler handler) {
        handlers.add(handler);
        return this;
    }

    public void buildAndExecute(ExerciseCallback callback) {
        if (handlers.isEmpty()) return;

        // 构建责任链
        for (int i = 0; i < handlers.size() - 1; i++) {
            handlers.get(i).setNext(handlers.get(i + 1));
        }

        // 启动责任链
        handlers.get(0).perform(callback);
    }
}
// ================== 客户端代码 ==================
public class FitnessApp {
    public static void main(String[] args) {
        // 1. 创建配置(建造者模式)
        EngineConfig config = new EngineConfig.Builder()
                .setDeviceId("ANDROID_2023")
                .setSensitivity(8)
                .setEnableSound(true)
                .build();

        // 2. 创建工厂(抽象工厂模式)
        SDKProvider provider = SDKProvider.BAIDU; // 可切换为IFLYTEK
        EngineFactory factory = createEngineFactory(provider);

        // 3. 创建引擎
        ExerciseEngine pushUpEngine = factory.createPushUpEngine(config);
        ExerciseEngine plankEngine = factory.createPlankEngine(config);
        ExerciseEngine gymEngine = factory.createGymnasticsEngine(config);

        // 4. 构建责任链(责任链模式)
        ExerciseChainBuilder builder = new ExerciseChainBuilder()
                .addHandler(new PushUpHandler(pushUpEngine))
                .addHandler(new PlankHandler(plankEngine))
                .addHandler(new GymnasticsHandler(gymEngine));

        // 5. 执行运动链
        builder.buildAndExecute(new ExerciseCallback() {
            @Override
            public void onExercisePerformed(ExerciseType type, ExerciseResult result) {
                System.out.println(">>> 运动完成: " + type + " | " + result);
            }

            @Override
            public void onChainCompleted() {
                System.out.println("==============================");
                System.out.println("所有运动完成!训练结束");
                System.out.println("==============================");
            }
        });
    }

    private static EngineFactory createEngineFactory(SDKProvider provider) {
        if (provider == SDKProvider.BAIDU) {
            return new BaiduEngineFactory();
        } else if (provider == SDKProvider.IFLYTEK) {
            return new IflytekEngineFactory();
        }else {
            return new IflytekEngineFactory();
        }
    }
}

deepseek_mermaid_20250708_273bb8.png