Java之23种设计模式代码示例

创建型模式

1. 工厂方法模式(Factory Method)

工厂方法模式通过定义一个创建对象的接口,让子类决定实例化哪一个类。下面的示例展示了一个文档编辑器可以创建不同类型的文档。

// Product Interface
interface Document {
    void open();
    void save();
}
​
// Concrete Product A
class WordDocument implements Document {
    @Override
    public void open() {
        System.out.println("Opening Word document...");
    }
​
    @Override
    public void save() {
        System.out.println("Saving Word document...");
    }
}
​
// Concrete Product B
class PdfDocument implements Document {
    @Override
    public void open() {
        System.out.println("Opening PDF document...");
    }
​
    @Override
    public void save() {
        System.out.println("Saving PDF document...");
    }
}
​
// Creator
abstract class Application {
    abstract Document createDocument();
​
    public void openDocument() {
        Document doc = createDocument();
        doc.open();
    }
}
​
// Concrete Creator A
class WordApplication extends Application {
    @Override
    Document createDocument() {
        return new WordDocument();
    }
}
​
// Concrete Creator B
class PdfApplication extends Application {
    @Override
    Document createDocument() {
        return new PdfDocument();
    }
}
​
// Client code
public class FactoryMethodExample {
    public static void main(String[] args) {
        Application app = new WordApplication();
        app.openDocument(); // Output: Opening Word document...
​
        app = new PdfApplication();
        app.openDocument(); // Output: Opening PDF document...
    }
}

2. 抽象工厂模式(Abstract Factory)

抽象工厂模式提供一个接口,用于创建相关或依赖的对象家族,而无需明确指定具体类。以下示例展示了一个UI库,可以创建不同风格的按钮和文本框。

// Abstract Product A
interface Button {
    void click();
}
​
// Abstract Product B
interface TextField {
    void type(String text);
}
​
// Concrete Product A1
class WindowsButton implements Button {
    @Override
    public void click() {
        System.out.println("Windows Button clicked.");
    }
}
​
// Concrete Product B1
class WindowsTextField implements TextField {
    @Override
    public void type(String text) {
        System.out.println("Windows TextField typed: " + text);
    }
}
​
// Concrete Product A2
class MacButton implements Button {
    @Override
    public void click() {
        System.out.println("Mac Button clicked.");
    }
}
​
// Concrete Product B2
class MacTextField implements TextField {
    @Override
    public void type(String text) {
        System.out.println("Mac TextField typed: " + text);
    }
}
​
// Abstract Factory
interface GUIFactory {
    Button createButton();
    TextField createTextField();
}
​
// Concrete Factory 1
class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }
​
    @Override
    public TextField createTextField() {
        return new WindowsTextField();
    }
}
​
// Concrete Factory 2
class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }
​
    @Override
    public TextField createTextField() {
        return new MacTextField();
    }
}
​
// Client
public class AbstractFactoryExample {
    private Button button;
    private TextField textField;
​
    public AbstractFactoryExample(GUIFactory factory) {
        button = factory.createButton();
        textField = factory.createTextField();
    }
​
    public void interact() {
        button.click();
        textField.type("Hello, Abstract Factory!");
    }
​
    public static void main(String[] args) {
        GUIFactory factory = new WindowsFactory();
        AbstractFactoryExample example = new AbstractFactoryExample(factory);
        example.interact(); // Windows Button clicked, Windows TextField typed: Hello, Abstract Factory!
​
        factory = new MacFactory();
        example = new AbstractFactoryExample(factory);
        example.interact(); // Mac Button clicked, Mac TextField typed: Hello, Abstract Factory!
    }
}

3. 单例模式(Singleton)

单例模式确保一个类只有一个实例,并提供一个全局访问点。以下示例展示了一个简单的单例模式实现。

public class Singleton {
    private static volatile Singleton instance;
​
    private Singleton() {
        // private constructor to prevent instantiation
    }
​
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
​
    public void doSomething() {
        System.out.println("Doing something with Singleton.");
    }
​
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        singleton.doSomething(); // Output: Doing something with Singleton.
    }
}

4. 建造者模式(Builder)

建造者模式用于创建复杂对象的实例化过程,将其与表示分离。以下示例展示了创建一个复杂的House对象的过程。

// Product
class House {
    private String foundation;
    private String structure;
    private String roof;
    private boolean furnished;
​
    public void setFoundation(String foundation) {
        this.foundation = foundation;
    }
​
    public void setStructure(String structure) {
        this.structure = structure;
    }
​
    public void setRoof(String roof) {
        this.roof = roof;
    }
​
    public void setFurnished(boolean furnished) {
        this.furnished = furnished;
    }
​
    @Override
    public String toString() {
        return "House [foundation=" + foundation + ", structure=" + structure + ", roof=" + roof + ", furnished="
                + furnished + "]";
    }
}
​
// Builder Interface
interface HouseBuilder {
    void buildFoundation();
    void buildStructure();
    void buildRoof();
    void furnishHouse();
    House getHouse();
}
​
// Concrete Builder
class ConcreteHouseBuilder implements HouseBuilder {
    private House house;
​
    public ConcreteHouseBuilder() {
        this.house = new House();
    }
​
    @Override
    public void buildFoundation() {
        house.setFoundation("Concrete Foundation");
        System.out.println("ConcreteHouseBuilder: Building concrete foundation.");
    }
​
    @Override
    public void buildStructure() {
        house.setStructure("Concrete Structure");
        System.out.println("ConcreteHouseBuilder: Building concrete structure.");
    }
​
    @Override
    public void buildRoof() {
        house.setRoof("Concrete Roof");
        System.out.println("ConcreteHouseBuilder: Building concrete roof.");
    }
​
    @Override
    public void furnishHouse() {
        house.setFurnished(true);
        System.out.println("ConcreteHouseBuilder: Furnishing the house.");
    }
​
    @Override
    public House getHouse() {
        return this.house;
    }
}
​
// Director
class ConstructionEngineer {
    private HouseBuilder houseBuilder;
​
    public ConstructionEngineer(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }
​
    public House constructHouse() {
        houseBuilder.buildFoundation();
        houseBuilder.buildStructure();
        houseBuilder.buildRoof();
        houseBuilder.furnishHouse();
        return houseBuilder.getHouse();
    }
}
​
// Client
public class BuilderExample {
    public static void main(String[] args) {
        HouseBuilder builder = new ConcreteHouseBuilder();
        ConstructionEngineer engineer = new ConstructionEngineer(builder);
        House house = engineer.constructHouse();
        System.out.println("Constructed House: " + house);
    }
}

5. 原型模式(Prototype)

原型模式用于通过复制现有对象来创建新的对象。以下示例展示了一个简单的原型模式实现。

// Prototype Interface
interface Prototype extends Cloneable {
    Prototype clone();
}
​
// Concrete Prototype
class ConcretePrototype implements Prototype {
    private String field;
​
    public ConcretePrototype(String field) {
        this.field = field;
    }
​
    @Override
    public Prototype clone() {
        return new ConcretePrototype(this.field);
    }
​
    @Override
    public String toString() {
        return "ConcretePrototype [field=" + field + "]";
    }
}
​
// Client
public class PrototypeExample {
    public static void main(String[] args) {
        ConcretePrototype original = new ConcretePrototype("Original");
        ConcretePrototype clone = (ConcretePrototype) original.clone();
​
        System.out.println(original); // Output: ConcretePrototype [field=Original]
        System.out.println(clone);    // Output: ConcretePrototype [field=Original]
    }
}

结构型模式

6. 适配器模式(Adapter)

适配器模式将一个类的接口转换成客户期望的另一个接口。以下示例展示了如何适配一个旧的API到新的接口中。

// Old interface
class OldPrinter {
    void print(String text) {
        System.out.println("Old Printer: " + text);
    }
}
​
// Target interface
interface NewPrinter {
    void print(String text);
}
​
// Adapter
class PrinterAdapter implements NewPrinter {
    private OldPrinter oldPrinter;
​
    public PrinterAdapter(OldPrinter oldPrinter) {
        this.oldPrinter = oldPrinter;
    }
​
    @Override
    public void print(String text) {
        oldPrinter.print(text);
    }
}
​
// Client
public class AdapterExample {
    public static void main(String[] args) {
        OldPrinter oldPrinter = new OldPrinter();
        NewPrinter newPrinter = new PrinterAdapter(oldPrinter);
        newPrinter.print("Hello, Adapter Pattern!"); // Output: Old Printer: Hello, Adapter Pattern!
    }
}

7. 桥接模式(Bridge)

桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。以下示例展示了使用桥接模式将绘图功能与不同形状分离。

// Implementor Interface
interface DrawAPI {
    void drawCircle(int radius, int x, int y);
}
​
// Concrete Implementor A
class RedCircle implements DrawAPI {
    @Override
    public void drawCircle(int radius, int x, int y) {
        System.out.println("Drawing Circle [color: red, radius: " + radius + ", x: " + x + ", y: " + y + "]");
    }
}
​
// Concrete Implementor B
class GreenCircle implements DrawAPI {
    @Override
    public void drawCircle(int radius, int x, int y) {
        System.out.println("Drawing Circle [color: green, radius: " + radius + ", x: " + x + ", y: " + y + "]");
    }
}
​
// Abstraction
abstract class Shape {
    protected DrawAPI drawAPI;
​
    protected Shape(DrawAPI drawAPI) {
        this.drawAPI = drawAPI;
    }
​
    public abstract void draw();
}
​
// Refined Abstraction
class Circle extends Shape {
    private int radius, x, y;
​
    protected Circle(int radius, int x, int y, DrawAPI drawAPI) {
        super(drawAPI);
        this.radius = radius;
        this.x = x;
        this.y = y;
    }
​
    @Override
    public void draw() {
        drawAPI.drawCircle(radius, x, y);
    }
}
​
// Client
public class BridgeExample {
    public static void main(String[] args) {
        Shape redCircle = new Circle(10, 100, 100, new RedCircle());
        Shape greenCircle = new Circle(10, 200, 200, new GreenCircle());
​
        redCircle.draw(); // Output: Drawing Circle [color: red, radius: 10, x: 100, y: 100]
        greenCircle.draw(); // Output: Drawing Circle [color: green, radius: 10, x: 200, y: 200]
    }
}

8. 组合模式(Composite)

组合模式将对象组合成树形结构以表示部分-整体的层次结构。以下示例展示了如何使用组合模式表示文件系统。

// Component
interface FileSystemComponent {
    void showDetails();
}
​
// Leaf
class File implements FileSystemComponent {
    private String name;
​
    public File(String name) {
        this.name = name;
    }
​
    @Override
    public void showDetails() {
        System.out.println("File: " + name);
    }
}
​
// Composite
class Directory implements FileSystemComponent {
    private String name;
    private List<FileSystemComponent> components = new ArrayList<>();
​
    public Directory(String name) {
        this.name = name;
    }
​
    public void addComponent(FileSystemComponent component) {
        components.add(component);
    }
​
    public void removeComponent(FileSystemComponent component) {
        components.remove(component);
    }
​
    @Override
    public void showDetails() {
        System.out.println("Directory: " + name);
        for (FileSystemComponent component : components) {
            component.showDetails();
        }
    }
}
​
// Client
public class CompositeExample {
    public static void main(String[] args) {
        FileSystemComponent file1 = new File("file1.txt");
        FileSystemComponent file2 = new File("file2.txt");
        FileSystemComponent file3 = new File("file3.txt");
​
        Directory directory1 = new Directory("dir1");
        directory1.addComponent(file1);
​
        Directory directory2 = new Directory("dir2");
        directory2.addComponent(file2);
        directory2.addComponent(file3);
        directory2.addComponent(directory1);
​
        directory2.showDetails();
        // Output:
        // Directory: dir2
        // File: file2.txt
        // File: file3.txt
        // Directory: dir1
        // File: file1.txt
    }
}

9. 装饰器模式(Decorator)

装饰器模式动态地给一个对象添加一些额外的职责。以下示例展示了如何装饰一个文本输出。

// Component Interface
interface TextComponent {
    String formatText();
}
​
// Concrete Component
class PlainText implements TextComponent {
    private String text;
​
    public PlainText(String text) {
        this.text = text;
    }
​
    @Override
    public String formatText() {
        return text;
    }
}
​
// Decorator
abstract class TextDecorator implements TextComponent {
    protected TextComponent decoratedText;
​
    public TextDecorator(TextComponent decoratedText) {
        this.decoratedText = decoratedText;
    }
​
    public String formatText() {
        return decoratedText.formatText();
    }
}
​
// Concrete Decorator
class BoldDecorator extends TextDecorator {
    public BoldDecorator(TextComponent decoratedText) {
        super(decoratedText);
    }
​
    @Override
    public String formatText() {
        return "<b>" + super.formatText() + "</b>";
    }
}
​
// Another Concrete Decorator
class ItalicDecorator extends TextDecorator {
    public ItalicDecorator(TextComponent decoratedText) {
        super(decoratedText);
    }
​
    @Override
    public String formatText() {
        return "<i>" + super.formatText() + "</i>";
    }
}
​
// Client
public class DecoratorExample {
    public static void main(String[] args) {
        TextComponent plainText = new PlainText("Hello, Decorator Pattern!");
​
        TextComponent boldText = new BoldDecorator(plainText);
        TextComponent italicText = new ItalicDecorator(plainText);
        TextComponent boldItalicText = new ItalicDecorator(boldText);
​
        System.out.println(plainText.formatText()); // Output: Hello, Decorator Pattern!
        System.out.println(boldText.formatText());  // Output: <b>Hello, Decorator Pattern!</b>
        System.out.println(italicText.formatText()); // Output: <i>Hello, Decorator Pattern!</i>
        System.out.println(boldItalicText.formatText()); // Output: <i><b>Hello, Decorator Pattern!</b></i>
    }
}

10. 外观模式(Facade)

外观模式为子系统中的一组接口提供一个一致的界面。以下示例展示了一个简单的外观类,用于控制家庭影院系统的多个子系统。

// Subsystem Class A
class DVDPlayer {
    public void on() {
        System.out.println("DVD Player is ON");
    }
​
    public void play(String movie) {
        System.out.println("Playing movie: " + movie);
    }
​
    public void off() {
        System.out.println("DVD Player is OFF");
    }
}
​
// Subsystem Class B
class Amplifier {
    public void on() {
        System.out.println("Amplifier is ON");
    }
​
    public void setVolume(int level) {
        System.out.println("Setting volume to " + level);
    }
​
    public void off() {
        System.out.println("Amplifier is OFF");
    }
}
​
// Subsystem Class C
class Projector {
    public void on() {
        System.out.println("Projector is ON");
    }
​
    public void setInput(String input) {
        System.out.println("Setting input to " + input);
    }
​
    public void off() {
        System.out.println("Projector is OFF");
    }
}
​
// Facade
class HomeTheaterFacade {
    private DVDPlayer dvdPlayer;
    private Amplifier amplifier;
    private Projector projector;
​
    public HomeTheaterFacade(DVDPlayer dvdPlayer, Amplifier amplifier, Projector projector) {
        this.dvdPlayer = dvdPlayer;
        this.amplifier = amplifier;
        this.projector = projector;
    }
​
    public void watchMovie(String movie) {
        System.out.println("Get ready to watch a movie...");
        dvdPlayer.on();
        dvdPlayer.play(movie);
        amplifier.on();
        amplifier.setVolume(5);
        projector.on();
        projector.setInput("DVD");
    }
​
    public void endMovie() {
        System.out.println("Shutting down the movie theater...");
        dvdPlayer.off();
        amplifier.off();
        projector.off();
    }
}
​
// Client
public class FacadeExample {
    public static void main(String[] args) {
        DVDPlayer dvdPlayer = new DVDPlayer();
        Amplifier amplifier = new Amplifier();
        Projector projector = new Projector();
​
        HomeTheaterFacade homeTheater = new HomeTheaterFacade(dvdPlayer, amplifier, projector);
        homeTheater.watchMovie("Inception");
        // Output:
        // Get ready to watch a movie...
        // DVD Player is ON
        // Playing movie: Inception
        // Amplifier is ON
        // Setting volume to 5
        // Projector is ON
        // Setting input to DVD
​
        homeTheater.endMovie();
        // Output:
        // Shutting down the movie theater...
        // DVD Player is OFF
        // Amplifier is OFF
        // Projector is OFF
    }
}

11. 享元模式(Flyweight)

享元模式通过共享尽可能多的对象以减少内存消耗。以下示例展示了一个字符的字体样式共享的场景。

import java.util.HashMap;
import java.util.Map;
​
// Flyweight
class Font {
    private String fontName;
    private int size;
​
    public Font(String fontName, int size) {
        this.fontName = fontName;
        this.size = size;
    }
​
    public String getFontName() {
        return fontName;
    }
​
    public int getSize() {
        return size;
    }
​
    @Override
    public String toString() {
        return "Font[name=" + fontName + ", size=" + size + "]";
    }
}
​
// Flyweight Factory
class FontFactory {
    private Map<String, Font> fontMap = new HashMap<>();
​
    public Font getFont(String fontName, int size) {
        String key = fontName + size;
        Font font = fontMap.get(key);
        if (font == null) {
            font = new Font(fontName, size);
            fontMap.put(key, font);
        }
        return font;
    }
}
​
// Client
class Character {
    private char value;
    private Font font;
​
    public Character(char value, Font font) {
        this.value = value;
        this.font = font;
    }
​
    public void display() {
        System.out.println("Character: " + value + " with font: " + font);
    }
}
​
public class FlyweightExample {
    public static void main(String[] args) {
        FontFactory fontFactory = new FontFactory();
​
        Font font1 = fontFactory.getFont("Arial", 12);
        Font font2 = fontFactory.getFont("Arial", 12);
        Font font3 = fontFactory.getFont("Arial", 14);
​
        Character characterA = new Character('A', font1);
        Character characterB = new Character('B', font2);
        Character characterC = new Character('C', font3);
​
        characterA.display(); // Character: A with font: Font[name=Arial, size=12]
        characterB.display(); // Character: B with font: Font[name=Arial, size=12]
        characterC.display(); // Character: C with font: Font[name=Arial, size=14]
​
        // Checking object sharing
        System.out.println("font1 == font2: " + (font1 == font2)); // true
        System.out.println("font1 == font3: " + (font1 == font3)); // false
    }
}

12. 代理模式(Proxy)

代理模式为其他对象提供一种代理,以控制对这个对象的访问。以下示例展示了一个保护代理,用于控制对敏感操作的访问。

// Subject Interface
interface Image {
    void display();
}
​
// Real Subject
class RealImage implements Image {
    private String fileName;
​
    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFromDisk();
    }
​
    private void loadFromDisk() {
        System.out.println("Loading " + fileName);
    }
​
    @Override
    public void display() {
        System.out.println("Displaying " + fileName);
    }
}
​
// Proxy
class ProxyImage implements Image {
    private RealImage realImage;
    private String fileName;
​
    public ProxyImage(String fileName) {
        this.fileName = fileName;
    }
​
    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(fileName);
        }
        realImage.display();
    }
}
​
// Client
public class ProxyExample {
    public static void main(String[] args) {
        Image image1 = new ProxyImage("photo1.jpg");
        Image image2 = new ProxyImage("photo2.jpg");
​
        // Image will be loaded from disk and displayed
        image1.display(); // Output: Loading photo1.jpg, Displaying photo1.jpg
​
        // Image will not be loaded from disk, only displayed
        image1.display(); // Output: Displaying photo1.jpg
​
        // Image will be loaded from disk and displayed
        image2.display(); // Output: Loading photo2.jpg, Displaying photo2.jpg
    }
}

行为型模式

13. 责任链模式(Chain of Responsibility)

责任链模式将请求的发送者和接受者解耦,使多个对象都有机会处理该请求。以下示例展示了一个支持不同日志级别的日志记录系统。

// Handler
abstract class Logger {
    public static int INFO = 1;
    public static int DEBUG = 2;
    public static int ERROR = 3;
​
    protected int level;
​
    // Next element in chain of responsibility
    protected Logger nextLogger;
​
    public void setNextLogger(Logger nextLogger) {
        this.nextLogger = nextLogger;
    }
​
    public void logMessage(int level, String message) {
        if (this.level <= level) {
            write(message);
        }
        if (nextLogger != null) {
            nextLogger.logMessage(level, message);
        }
    }
​
    abstract protected void write(String message);
}
​
// Concrete Handler for Info
class InfoLogger extends Logger {
    public InfoLogger(int level) {
        this.level = level;
    }
​
    @Override
    protected void write(String message) {
        System.out.println("Info: " + message);
    }
}
​
// Concrete Handler for Debug
class DebugLogger extends Logger {
    public DebugLogger(int level) {
        this.level = level;
    }
​
    @Override
    protected void write(String message) {
        System.out.println("Debug: " + message);
    }
}
​
// Concrete Handler for Error
class ErrorLogger extends Logger {
    public ErrorLogger(int level) {
        this.level = level;
    }
​
    @Override
    protected void write(String message) {
        System.out.println("Error: " + message);
    }
}
​
// Client
public class ChainOfResponsibilityExample {
    private static Logger getChainOfLoggers() {
        Logger errorLogger = new ErrorLogger(Logger.ERROR);
        Logger debugLogger = new DebugLogger(Logger.DEBUG);
        Logger infoLogger = new InfoLogger(Logger.INFO);
​
        infoLogger.setNextLogger(debugLogger);
        debugLogger.setNextLogger(errorLogger);
​
        return infoLogger;
    }
​
    public static void main(String[] args) {
        Logger loggerChain = getChainOfLoggers();
​
        loggerChain.logMessage(Logger.INFO, "This is an information.");
        // Output: Info: This is an information.
​
        loggerChain.logMessage(Logger.DEBUG, "This is a debug level information.");
        // Output: Info: This is a debug level information.
        //         Debug: This is a debug level information.
​
        loggerChain.logMessage(Logger.ERROR, "This is an error information.");
        // Output: Info: This is an error information.
        //         Debug: This is an error information.
        //         Error: This is an error information.
    }
}

14. 命令模式(Command)

命令模式将请求封装成对象,从而使您可以用不同的请求对客户端进行参数化。以下示例展示了一个简单的遥控器实现,用于执行各种设备操作。

// Command Interface
interface Command {
    void execute();
}
​
// Receiver
class Light {
    public void on() {
        System.out.println("Light is ON");
    }
​
    public void off() {
        System.out.println("Light is OFF");
    }
}
​
// Concrete Command for turning on the light
class LightOnCommand implements Command {
    private Light light;
​
    public LightOnCommand(Light light) {
        this.light = light;
    }
​
    @Override
    public void execute() {
        light.on();
    }
}
​
// Concrete Command for turning off the light
class LightOffCommand implements Command {
    private Light light;
​
    public LightOffCommand(Light light) {
        this.light = light;
    }
​
    @Override
    public void execute() {
        light.off();
    }
}
​
// Invoker
class RemoteControl {
    private Command command;
​
    public void setCommand(Command command) {
        this.command = command;
    }
​
    public void pressButton() {
        command.execute();
    }
}
​
// Client
public class CommandExample {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);
​
        RemoteControl remote = new RemoteControl();
        remote.setCommand(lightOn);
        remote.pressButton(); // Output: Light is ON
​
        remote.setCommand(lightOff);
        remote.pressButton(); // Output: Light is OFF
    }
}

15. 解释器模式(Interpreter)

解释器模式为一种语言定义其文法,并为该语言中的文法表达式提供一个解释器。以下示例展示了一个简单的表达式解析器。

// Abstract Expression
interface Expression {
    boolean interpret(String context);
}
​
// Terminal Expression
class TerminalExpression implements Expression {
    private String data;
​
    public TerminalExpression(String data) {
        this.data = data;
    }
​
    @Override
    public boolean interpret(String context) {
        return context.contains(data);
    }
}
​
// Or Expression
class OrExpression implements Expression {
    private Expression expr1;
    private Expression expr2;
​
    public OrExpression(Expression expr1, Expression expr2) {
        this.expr1 = expr1;
        this.expr2 = expr2;
    }
​
    @Override
    public boolean interpret(String context) {
        return expr1.interpret(context) || expr2.interpret(context);
    }
}
​
// And Expression
class AndExpression implements Expression {
    private Expression expr1;
    private Expression expr2;
​
    public AndExpression(Expression expr1, Expression expr2) {
        this.expr1 = expr1;
        this.expr2 = expr2;
    }
​
    @Override
    public boolean interpret(String context) {
        return expr1.interpret(context) && expr2.interpret(context);
    }
}
​
// Client
public class InterpreterExample {
    // Rule: "John" or "Julie" are male
    public static Expression getMaleExpression() {
        Expression john = new TerminalExpression("John");
        Expression julie = new TerminalExpression("Julie");
        return new OrExpression(john, julie);
    }
​
    // Rule: "Married" and "Julie" are married women
    public static Expression getMarriedWomanExpression() {
        Expression julie = new TerminalExpression("Julie");
        Expression married = new TerminalExpression("Married");
        return new AndExpression(julie, married);
    }
​
    public static void main(String[] args) {
        Expression isMale = getMaleExpression();
        Expression isMarriedWoman = getMarriedWomanExpression();
        System.out.println("John is male? " + isMale.interpret("John")); // Output: John is male? true
        System.out.println("Julie is a married woman? " + isMarriedWoman.interpret("Married Julie")); // Output: Julie is a married woman? true
        System.out.println("Julie is male? " + isMale.interpret("Julie")); // Output: Julie is male? true
        System.out.println("Married John is a married woman? " + isMarriedWoman.interpret("Married John")); // Output: Married John is a married woman? false
    }
}

16. 迭代器模式(Iterator)

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。以下示例展示了一个简单的自定义聚合类及其迭代器。

import java.util.Iterator;
​
// Aggregate Interface
interface Container {
    Iterator<String> getIterator();
}
​
// Concrete Aggregate
class NameRepository implements Container {
    private String[] names = {"John", "Jane", "Julie", "Jake"};
​
    @Override
    public Iterator<String> getIterator() {
        return new NameIterator();
    }
​
    // Concrete Iterator
    private class NameIterator implements Iterator<String> {
        int index = 0;
​
        @Override
        public boolean hasNext() {
            return index < names.length;
        }
​
        @Override
        public String next() {
            if (this.hasNext()) {
                return names[index++];
            }
            return null;
        }
    }
}
​
// Client
public class IteratorExample {
    public static void main(String[] args) {
        NameRepository nameRepository = new NameRepository();
        for (Iterator<String> iter = nameRepository.getIterator(); iter.hasNext(); ) {
            String name = iter.next();
            System.out.println("Name : " + name);
        }
        // Output:
        // Name : John
        // Name : Jane
        // Name : Julie
        // Name : Jake
    }
}

17. 中介者模式(Mediator)

中介者模式定义一个中介对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。以下示例展示了一个聊天系统的实现。

import java.util.ArrayList;
import java.util.List;
​
// Mediator Interface
interface ChatMediator {
    void sendMessage(String message, User user);
    void addUser(User user);
}
​
// Concrete Mediator
class ChatMediatorImpl implements ChatMediator {
    private List<User> users;
​
    public ChatMediatorImpl() {
        this.users = new ArrayList<>();
    }
​
    @Override
    public void addUser(User user) {
        this.users.add(user);
    }
​
    @Override
    public void sendMessage(String message, User user) {
        for (User u : this.users) {
            // Message should not be received by the user sending it
            if (u != user) {
                u.receive(message);
            }
        }
    }
}
​
// Colleague Abstract Class
abstract class User {
    protected ChatMediator mediator;
    protected String name;
​
    public User(ChatMediator mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    }
​
    public abstract void send(String message);
    public abstract void receive(String message);
}
​
// Concrete Colleague
class UserImpl extends User {
    public UserImpl(ChatMediator mediator, String name) {
        super(mediator, name);
    }
​
    @Override
    public void send(String message) {
        System.out.println(this.name + ": Sending Message = " + message);
        mediator.sendMessage(message, this);
    }
​
    @Override
    public void receive(String message) {
        System.out.println(this.name + ": Received Message = " + message);
    }
}
​
// Client
public class MediatorExample {
    public static void main(String[] args) {
        ChatMediator mediator = new ChatMediatorImpl();
​
        User john = new UserImpl(mediator, "John");
        User jane = new UserImpl(mediator, "Jane");
        User bob = new UserImpl(mediator, "Bob");
​
        mediator.addUser(john);
        mediator.addUser(jane);
        mediator.addUser(bob);
​
        john.send("Hi everyone!");
        // Output:
        // John: Sending Message = Hi everyone!
        // Jane: Received Message = Hi everyone!
        // Bob: Received Message = Hi everyone!
    }
}

18. 备忘录模式(Memento)

备忘录模式用于保存对象的状态,以便可以在以后恢复。以下示例展示了一个文本编辑器的撤销操作。

import java.util.Stack;
​
// Memento
class TextMemento {
    private String text;
​
    public TextMemento(String text) {
        this.text = text;
    }
​
    public String getText() {
        return text;
    }
}
​
// Originator
class TextEditor {
    private StringBuilder text;
​
    public TextEditor() {
        this.text = new StringBuilder();
    }
​
    public void write(String newText) {
        text.append(newText);
    }
​
    public String getText() {
        return text.toString();
    }
​
    public TextMemento save() {
        return new TextMemento(text.toString());
    }
​
    public void undoToLastSave(Object obj) {
        TextMemento memento = (TextMemento) obj;
        text = new StringBuilder(memento.getText());
    }
}
​
// Caretaker
class Caretaker {
    private Stack<TextMemento> mementoStack = new Stack<>();
​
    public void save(TextEditor textEditor) {
        mementoStack.push(textEditor.save());
    }
​
    public void undo(TextEditor textEditor) {
        if (!mementoStack.isEmpty()) {
            textEditor.undoToLastSave(mementoStack.pop());
        }
    }
}
​
// Client
public class MementoExample {
    public static void main(String[] args) {
        TextEditor textEditor = new TextEditor();
        Caretaker caretaker = new Caretaker();
​
        textEditor.write("Hello, ");
        caretaker.save(textEditor);
​
        textEditor.write("World!");
        System.out.println(textEditor.getText()); // Output: Hello, World!
​
        caretaker.undo(textEditor);
        System.out.println(textEditor.getText()); // Output: Hello,
​
        caretaker.undo(textEditor);
        System.out.println(textEditor.getText()); // Output: Hello,
    }
}

19. 观察者模式(Observer)

观察者模式定义了对象之间的一对多依赖关系,当一个对象的状态改变时,所有依赖于它的对象都会得到通知并自动更新。以下示例展示了一个天气系统的实现。

import java.util.ArrayList;
import java.util.List;
​
// Subject
class WeatherStation {
    private List<Observer> observers = new ArrayList<>();
    private int temperature;
​
    public void addObserver(Observer observer) {
        observers.add(observer);
    }
​
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
​
    public void setTemperature(int temperature) {
        this.temperature = temperature;
        notifyObservers();
    }
​
    public int getTemperature() {
        return temperature;
    }
​
    private void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}
​
// Observer Interface
interface Observer {
    void update();
}
​
// Concrete Observer
class Display implements Observer {
    private WeatherStation weatherStation;
​
    public Display(WeatherStation weatherStation) {
        this.weatherStation = weatherStation;
    }
​
    @Override
    public void update() {
        System.out.println("Temperature updated to: " + weatherStation.getTemperature() + " degrees");
    }
}
​
// Client
public class ObserverExample {
    public static void main(String[] args) {
        WeatherStation weatherStation = new WeatherStation();
​
        Display display1 = new Display(weatherStation);
        Display display2 = new Display(weatherStation);
​
        weatherStation.addObserver(display1);
        weatherStation.addObserver(display2);
​
        weatherStation.setTemperature(25);
        // Output:
        // Temperature updated to: 25 degrees
        // Temperature updated to: 25 degrees
​
        weatherStation.setTemperature(30);
        // Output:
        // Temperature updated to: 30 degrees
        // Temperature updated to: 30 degrees
    }
}

20. 状态模式(State)

状态模式允许对象在内部状态改变时改变其行为。以下示例展示了一个简单的电灯开关的状态切换。

// State Interface
interface State {
    void pressSwitch(LightSwitch lightSwitch);
}
​
// Concrete State: On
class OnState implements State {
    @Override
    public void pressSwitch(LightSwitch lightSwitch) {
        System.out.println("Turning off the light.");
        lightSwitch.setState(new OffState());
    }
}
​
// Concrete State: Off
class OffState implements State {
    @Override
    public void pressSwitch(LightSwitch lightSwitch) {
        System.out.println("Turning on the light.");
        lightSwitch.setState(new OnState());
    }
}
​
// Context
class LightSwitch {
    private State state;
​
    public LightSwitch() {
        state = new OffState(); // Initial state
    }
​
    public void setState(State state) {
        this.state = state;
    }
​
    public void pressSwitch() {
        state.pressSwitch(this);
    }
}
​
// Client
public class StateExample {
    public static void main(String[] args) {
        LightSwitch lightSwitch = new LightSwitch();
​
        lightSwitch.pressSwitch(); // Output: Turning on the light.
        lightSwitch.pressSwitch(); // Output: Turning off the light.
    }
}

21. 策略模式(Strategy)

策略模式定义一系列算法,将每个算法封装起来,并使它们可以互换。以下示例展示了一个支付系统的实现,其中使用不同的支付方式。

// Strategy Interface
interface PaymentStrategy {
    void pay(int amount);
}
​
// Concrete Strategy: CreditCard
class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
​
    public CreditCardPayment(String cardNumber) {
        this.cardNumber = cardNumber;
    }
​
    @Override
    public void pay(int amount) {
        System.out.println("Paid " + amount + " using Credit Card.");
    }
}
​
// Concrete Strategy: PayPal
class PayPalPayment implements PaymentStrategy {
    private String email;
​
    public PayPalPayment(String email) {
        this.email = email;
    }
​
    @Override
    public void pay(int amount) {
        System.out.println("Paid " + amount + " using PayPal.");
    }
}
​
// Context
class ShoppingCart {
    private PaymentStrategy paymentStrategy;
​
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
​
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}
​
// Client
public class StrategyExample {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
​
        cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9876-5432"));
        cart.checkout(100); // Output: Paid 100 using Credit Card.
​
        cart.setPaymentStrategy(new PayPalPayment("email@example.com"));
        cart.checkout(200); // Output: Paid 200 using PayPal.
    }
}

22. 模板方法模式(Template Method)

模板方法模式定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变算法结构即可重新定义该算法的某些特定步骤。以下示例展示了一个饮料制作过程的模板方法。

// Abstract Class
abstract class Beverage {
    // Template method
    public final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
​
    abstract void brew();
​
    abstract void addCondiments();
​
    void boilWater() {
        System.out.println("Boiling water");
    }
​
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
}
​
// Concrete Class: Tea
class Tea extends Beverage {
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }
​
    @Override
    void addCondiments() {
        System.out.println("Adding lemon");
    }
}
​
// Concrete Class: Coffee
class Coffee extends Beverage {
    @Override
    void brew() {
        System.out.println("Dripping Coffee through filter");
    }
​
    @Override
    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}
​
// Client
public class TemplateMethodExample {
    public static void main(String[] args) {
        Beverage tea = new Tea();
        tea.prepareRecipe();
        // Output:
        // Boiling water
        // Steeping the tea
        // Pouring into cup
        // Adding lemon
​
        Beverage coffee = new Coffee();
        coffee.prepareRecipe();
        // Output:
        // Boiling water
        // Dripping Coffee through filter
        // Pouring into cup
        // Adding sugar and milk
    }
}

23. 访问者模式(Visitor)

访问者模式允许你为一个对象结构中的各元素添加新功能,而又不改变各元素的类。以下示例展示了一个用于计算购物车中物品价格的访问者模式实现。

// Visitor Interface
interface ShoppingCartVisitor {
    int visit(Book book);
    int visit(Fruit fruit);
}
​
// Concrete Visitor
class ShoppingCartVisitorImpl implements ShoppingCartVisitor {
    @Override
    public int visit(Book book) {
        int cost = book.getPrice();
        if (cost > 50) {
            cost -= 5; // Discount for books over $50
        }
        System.out.println("Book ISBN::" + book.getIsbn() + " cost =" + cost);
        return cost;
    }
​
    @Override
    public int visit(Fruit fruit) {
        int cost = fruit.getPricePerKg() * fruit.getWeight();
        System.out.println(fruit.getName() + " cost = " + cost);
        return cost;
    }
}
​
// Element Interface
interface ItemElement {
    int accept(ShoppingCartVisitor visitor);
}
​
// Concrete Element: Book
class Book implements ItemElement {
    private int price;
    private String isbn;
​
    public Book(int price, String isbn) {
        this.price = price;
        this.isbn = isbn;
    }
​
    public int getPrice() {
        return price;
    }
​
    public String getIsbn() {
        return isbn;
    }
​
    @Override
    public int accept(ShoppingCartVisitor visitor) {
        return visitor.visit(this);
    }
}
​
// Concrete Element: Fruit
class Fruit implements ItemElement {
    private int pricePerKg;
    private int weight;
    private String name;
​
    public Fruit(int pricePerKg, int weight, String name) {
        this.pricePerKg = pricePerKg;
        this.weight = weight;
        this.name = name;
    }
​
    public int getPricePerKg() {
        return pricePerKg;
    }
​
    public int getWeight() {
        return weight;
    }
​
    public String getName() {
        return name;
    }
​
    @Override
    public int accept(ShoppingCartVisitor visitor) {
        return visitor.visit(this);
    }
}
​
// Client
public class VisitorExample {
    public static void main(String[] args) {
        ItemElement[] items = new ItemElement[]{
            new Book(60, "1234"), 
            new Book(40, "5678"), 
            new Fruit(10, 2, "Banana"), 
            new Fruit(5, 5, "Apple")
        };
​
        int total = calculatePrice(items);
        System.out.println("Total Cost = " + total); // Output: Total Cost = 135
    }
​
    private static int calculatePrice(ItemElement[] items) {
        ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl();
        int sum = 0;
        for (ItemElement item : items) {
            sum += item.accept(visitor);
        }
        return sum;
    }
}

这些例子涵盖了设计模式的各个方面,每个模式都用具体的代码实现展示了其应用场景和优点。设计模式不仅仅是代码模板,它们是应对软件设计中常见问题的解决方案。理解这些模式的思想和使用场景将有助于你在实际开发中做出更好的设计决策。

23种设计模式介绍Java之23种设计模式介绍-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愤怒的代码

如果您有受益,欢迎打赏博主😊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值