常用设计模式

一、工厂模式 + 单例模式

使用工厂模式来创建对象,通过单例模式来保证该工厂只有一个实例,从而减少创建对象时的开销。

首先,创建一个工厂类,该类使用单例模式来保证只有一个实例,该实例负责创建对象。然后,根据需要创建多个工厂方法,每个方法用于创建不同的对象。

class SingletonFactory {
    private static volatile SingletonFactory instance;

    private SingletonFactory() {
        // 私有构造方法
    }

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

    public Object createObject(String type) {
        if ("type1".equals(type)) {
            return new Type1();
        } else if ("type2".equals(type)) {
            return new Type2();
        } else {
            throw new IllegalArgumentException("Unsupported type: " + type);
        }
    }
}

class Type1 {
    // 类型1实现逻辑
}

class Type2 {
    // 类型2实现逻辑
}

二、模板方法模式 + 策略模式

使用模板方法模式来定义算法的骨架,同时使用策略模式来定义算法的不同实现方式

例如:实现一个图片处理程序,可以对不同类型的图片进行处理,包括缩放、旋转和裁剪等操作。具体的处理算法可以根据不同类型的图片而异。

abstract class ImageProcessor {
    //模板方法
    public void processImage() {
        // 打开图片的具体实现
        BufferedImage image = openImage();
        // 执行具体的处理算法
        ImageProcessingStrategy strategy = createImageProcessingStrategy();
        BufferedImage processedImage = strategy.processImage(image);
        // 保存图片的具体实现
        saveImage(processedImage);
    }

    protected BufferedImage openImage() {
    }

    protected abstract ImageProcessingStrategy createImageProcessingStrategy();

    protected void saveImage(BufferedImage image) {
    }
}

interface ImageProcessingStrategy {
    BufferedImage processImage(BufferedImage image);
}

//图片处理类
class JpegProcessor extends ImageProcessor {
    @Override
    protected ImageProcessingStrategy createImageProcessingStrategy() {
        return new JpegProcessingStrategy();
    }
}

class PngProcessor extends ImageProcessor {
    @Override
    protected ImageProcessingStrategy createImageProcessingStrategy() {
        return new PngProcessingStrategy();
    }
}

//定义不同的算法策略
class JpegProcessingStrategy implements ImageProcessingStrategy {
    @Override
    public BufferedImage processImage(BufferedImage image) {
        // Jpeg 图片处理算法
    }
}

class PngProcessingStrategy implements ImageProcessingStrategy {
    @Override
    public BufferedImage processImage(BufferedImage image) {
        // Png 图片处理算法
    }
}

三、策略模式 + 工厂模式

使用工厂模式来创建不同的策略对象,然后使用策略模式来选择不同的策略,以实现不同的功能。我们实现一个简单的计算器

interface CalculatorStrategy {
//计算两个数的结果
double calculate(double num1, double num2);
//获取当前策略的描述信息 String getDescription(); }
//各类算法 class AddStrategy implements CalculatorStrategy { @Override public double calculate(double num1, double num2) { return num1 + num2; } @Override public String getDescription() { return "加法"; } } class SubtractStrategy implements CalculatorStrategy { @Override public double calculate(double num1, double num2) { return num1 - num2; } @Override public String getDescription() { return "减法"; } } class MultiplyStrategy implements CalculatorStrategy { @Override public double calculate(double num1, double num2) { return num1 * num2; } @Override public String getDescription() { return "乘法"; } } class DivideStrategy implements CalculatorStrategy { @Override public double calculate(double num1, double num2) { return num1 / num2; } @Override public String getDescription() { return "除法"; } } //使用工厂模式创建具体的策略对象 class CalculatorStrategyFactory { public static CalculatorStrategy getCalculatorStrategy(String operator) { switch (operator) { case "+": return new AddStrategy(); case "-": return new SubtractStrategy(); case "*": return new MultiplyStrategy(); case "/": return new DivideStrategy(); default: throw new IllegalArgumentException("无效的操作符:" + operator); } } } class Calculator { public static double calculate(double num1, double num2, String operator) { CalculatorStrategy calculatorStrategy = CalculatorStrategyFactory.getCalculatorStrategy(operator); System.out.println("正在执行 " + calculatorStrategy.getDescription() + " 计算"); return calculatorStrategy.calculate(num1, num2); } } //调用计算器 // 执行加法计算 double result = Calculator.calculate(10, 5, "+"); // 输出 15.0 System.out.println(result);

四、适配器模式 + 装饰器模式

适配器模式用于将一个接口转换成另一个接口,而装饰器模式则用于动态地给对象添加一些额外的职责。当我们需要将一个已有的接口转换成新的接口,并且还需要给对象添加一些额外的职责时,可以使用这两个模式混合使用。

//被适配的接口
interface
AdvancedMediaPlayer { public void play(String audioType, String fileName); } class VlcPlayer implements AdvancedMediaPlayer { @Override public void play(String audioType, String fileName) { if (audioType.equalsIgnoreCase("vlc")) { System.out.println("Playing vlc file. Name: " + fileName); } } } //适配器接口 interface MediaPlayer { public void play(String audioType, String fileName); } class Mp3Player implements MediaPlayer { @Override public void play(String audioType, String fileName) { if (audioType.equalsIgnoreCase("mp3")) { System.out.println("Playing mp3 file. Name: " + fileName); } } } //适配器:将 AdvancedMediaPlayer 接口转成 MediaPlayer 接口 class MediaPlayerAdapter implements MediaPlayer { AdvancedMediaPlayer advancedMusicPlayer; public MediaPlayerAdapter(AdvancedMediaPlayer advancedMusicPlayer) { this.advancedMusicPlayer = advancedMusicPlayer; } @Override public void play(String audioType, String fileName) { if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) { advancedMusicPlayer.play(audioType, fileName); } else if (audioType.equalsIgnoreCase("mp3")) { System.out.println("Playing mp3 file. Name: " + fileName); } } } //装饰器:用于在播放mp3时,动态的添加一些额外的功能 class Mp3PlayerDecorator implements MediaPlayer { private MediaPlayer mediaPlayer; public Mp3PlayerDecorator(MediaPlayer mediaPlayer) { this.mediaPlayer = mediaPlayer; } @Override public void play(String audioType, String fileName) { if (audioType.equalsIgnoreCase("mp3")) { System.out.println("Playing mp3 file with additional features. Name: " + fileName); // 添加额外的功能 System.out.println("Adding equalizer to the mp3 file."); mediaPlayer.play(audioType, fileName); } else { mediaPlayer.play(audioType, fileName); } } } class A {
//使用适配器和装饰器播放不同类型的音频文件
public static void main(String[] args) { MediaPlayer mediaPlayer = new Mp3Player(); mediaPlayer.play("mp3", "song.mp3"); //适配器模式 AdvancedMediaPlayer advancedMediaPlayer = new VlcPlayer(); MediaPlayer mediaPlayerAdapter = new MediaPlayerAdapter(advancedMediaPlayer); mediaPlayerAdapter.play("vlc", "movie.vlc"); //装饰器模式 MediaPlayer decoratedMediaPlayer = new Mp3PlayerDecorator(mediaPlayer); decoratedMediaPlayer.play("vlc", "song.mp3"); } }

五、观察者模式 + 命令模式

观察者模式用于观察对象的状态变化,并及时通知观察者。而命令模式则用于将一个请求封装成一个对象,可以在运行时动态地切换命令的接收者。当我们需要观察对象的状态变化,并在状态变化时执行一些命令时,可以使用这两个模式混合使用。

// 观察者对象
interface Observer {
    void update();
}

// 被观察者对象
class Subject {
    //观察者对象的引用
    private List<Observer> observers = new ArrayList<>();

    // 注册
    public void register(Observer observer) {
        observers.add(observer);
    }

    // 注销
    public void unregister(Observer observer) {
        observers.remove(observer);
    }

    // 通知观察者
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

//命令对象
interface Command {
    void execute();
}

//具体命令类
class ConcreteCommand implements Command {
    private Subject subject;

    public ConcreteCommand(Subject subject) {
        this.subject = subject;
    }

    //执行命令
    @Override
    public void execute() {
        subject.notifyObservers();
        //...并执行其它命令
    }
}

// 具体观察者类
class ConcreteObserver implements Observer {
    @Override
    public void update() {
        System.out.println("ConcreteObserver received notification.");
    }
}

class Client {
    public static void main(String[] args) {
        // 创建一个被观察者对象
        Subject subject = new Subject();
        // 创建一个观察者对象
        Observer observer = new ConcreteObserver();
        // 注册观察者对象
        subject.register(observer);
        // 创建一个命令对象
        Command command = new ConcreteCommand(subject);
        // 执行命令,通知观察者对象
        command.execute();
    }
}

 

posted @ 2023-09-14 23:14  yifanSJ  阅读(9)  评论(0编辑  收藏  举报