设计模式和举例

Java是一门流行的面向对象编程语言,设计模式是一种软件设计的经验总结。设计模式可以帮助程序员提高代码的可读性、可维护性和可扩展性。Java中有23种经典的设计模式,它们被分为三类:创建型、结构型和行为型。

  • 创建型设计模式
  1. 单例模式(Singleton)
  2. 工厂模式(Factory)
  3. 抽象工厂模式(Abstract Factory)
  4. 建造者模式(Builder)
  5. 原型模式(Prototype)
  • 结构型设计模式
  1. 适配器模式(Adapter)
  2. 桥接模式(Bridge)
  3. 组合模式(Composite)
  4. 装饰器模式(Decorator)
  5. 外观模式(Facade)
  6. 享元模式(Flyweight)
  7. 代理模式(Proxy)
  • 行为型设计模式
  1. 责任链模式(Chain of Responsibility)
  2. 命令模式(Command)
  3. 解释器模式(Interpreter)
  4. 迭代器模式(Iterator)
  5. 中介者模式(Mediator)
  6. 备忘录模式(Memento)
  7. 观察者模式(Observer)
  8. 状态模式(State)
  9. 策略模式(Strategy)
  10. 模板方法模式(Template Method)
  11. 访问者模式(Visitor)

1. 创建型设计模式

1.1 单例模式(Singleton)

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。这种模式很常见,因为它可以避免频繁地创建对象,从而提高应用程序的性能。

例:

public class Singleton {
    private static Singleton instance;
    
    private Singleton() {
        // 私有构造函数,防止外部实例化
    }
    
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
    
    public void doSomething() {
        // 单例类的具体方法实现
    }
}

1.2 工厂模式(Factory)

工厂模式是一种创建型设计模式,它提供一种统一的接口来创建一组相关的对象,而不必指定它们的具体类。这种模式有助于将对象的创建与使用分离开来,并提高代码的可扩展性。

例:

// 工厂接口
public interface AnimalFactory {
    Animal createAnimal();
}

// 具体工厂实现
public class CatFactory implements AnimalFactory {
    public Animal createAnimal() {
        return new Cat();
    }
}

// 具体工厂实现
public class DogFactory implements AnimalFactory {
    public Animal createAnimal() {
        return new Dog();
    }
}

// 抽象产品类
public abstract class Animal {
    public abstract void makeSound();
}

// 具体产品类
public class Cat extends Animal {
    public void makeSound() {
        System.out.println("喵喵喵");
    }
}

// 具体产品类
public class Dog extends Animal {
    public void makeSound() {
        System.out.println("汪汪汪");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        AnimalFactory catFactory = new CatFactory();
        Animal cat = catFactory.createAnimal();
        cat.makeSound(); // 输出:喵喵喵

        AnimalFactory dogFactory = new DogFactory();
        Animal dog = dogFactory.createAnimal();
        dog.makeSound(); // 输出:汪汪汪
    }
}

1.3 抽象工厂模式(Abstract Factory)

抽象工厂模式是一种创建型设计模式,它提供一种创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。它是工厂模式的扩展,可以帮助我们处理更复杂的对象关系。

例:

// 抽象工厂接口
public interface AnimalFactory {
    Animal createAnimal();
    Food createFood();
}

// 具体工厂实现
public class CatFactory implements AnimalFactory {
    public Animal createAnimal() {
        return new Cat();
    }
    public Food createFood() {
        return new Fish();
    }
}

// 具体工厂实现
public class DogFactory implements AnimalFactory {
    public Animal createAnimal() {
        return new Dog();
    }
    public Food createFood() {
        return new Meat();
    }
}

// 抽象产品类
public abstract class Animal {
    public abstract void eat(Food food);
}

// 具体产品类
public class Cat extends Animal {
    public void eat(Food food) {
        if (food instanceof Fish) {
            System.out.println("猫吃鱼");
        } else {
            System.out.println("猫不吃这种食物");
        }
    }
}

// 具体产品类
public class Dog extends Animal {
    public void eat(Food food) {
        if (food instanceof Meat) {
            System.out.println("狗吃肉");
        } else {
            System.out.println("狗不吃这种食物");
        }
    }
}

// 抽象产品类
public abstract class Food {
    // 食物类的具体实现略
}

// 具体产品类
public class Fish extends Food {
    // 食物类的具体实现略
}

// 具体产品类
public class Meat extends Food {
    // 食物类的具体实现略
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        AnimalFactory catFactory = new CatFactory();
        Animal cat = catFactory.createAnimal();
        Food fish = catFactory.createFood();
        cat.eat(fish); // 输出:猫吃鱼

        AnimalFactory dogFactory = new DogFactory();
        Animal dog = dogFactory.createAnimal();
        Food meat = dogFactory.createFood();
        dog.eat(meat); // 输出:狗吃肉
    }
}

1.4 建造者模式(Builder)

建造者模式是一种创建型设计模式,它允许您使用相同的构建过程来创建不同类型的对象。这种模式有助于减少重复的构建代码,并使代码更易于维护和扩展。

例:

// 产品类
public class House {
    private String foundation;
    private String wall;
    private String roof;
    
    public void setFoundation(String foundation) {
        this.foundation = foundation;
    }
    
    public void setWall(String wall) {
        this.wall = wall;
    }
    
    public void setRoof(String roof) {
        this.roof = roof;
    }
    
    public String getFoundation() {
        return foundation;
    }
    
    public String getWall() {
        return wall;
    }
    
    public String getRoof() {
        return roof;
    }
}

// 抽象建造者类
public abstract class HouseBuilder {
    protected House house = new House();
    
    public abstract void buildFoundation();
    public abstract void buildWall();
    public abstract void buildRoof();
    
    public House getResult() {
        return house;
    }
}

// 具体建造者类
public class LuxuryHouseBuilder extends HouseBuilder {
    public void buildFoundation() {
        house.setFoundation("豪华地基");
    }
    
    public void buildWall() {
        house.setWall("豪华墙壁");
    }
    
    public void buildRoof() {
        house.setRoof("豪华屋顶");
    }
}

// 具体建造者类
public class SimpleHouseBuilder extends HouseBuilder {
    public void buildFoundation() {
        house.setFoundation("普通地基");
    }
    
    public void buildWall() {
        house.setWall("普通墙壁");
    }
    
    public void buildRoof() {
        house.setRoof("普通屋顶");
    }
}

// 指挥者类
public class Director {
    private HouseBuilder builder;
    
    public Director(HouseBuilder builder) {
        this.builder = builder;
    }
    
    public void buildHouse() {
        builder.buildFoundation();
        builder.buildWall();
        builder.buildRoof();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        HouseBuilder builder = new SimpleHouseBuilder();
        Director director = new Director(builder);
        director.buildHouse();
        House house = builder.getResult();
        System.out.println(house.getFoundation() + " " + house.getWall() + " " + house.getRoof());
        
        builder = new LuxuryHouseBuilder();
        director = new Director(builder);
        director.buildHouse();
        house = builder.getResult();
        System.out.println(house.getFoundation() + " " + house.getWall() + " " + house.getRoof());
    }
}

1.5 原型模式(Prototype)

原型模式是一种创建型设计模式,它允许您通过克隆现有对象来创建新对象,而无需重新创建它们。这种模式可以帮助您处理大量的对象创建,并且可以提高应用程序的性能。

例:

// 原型接口
public interface Prototype {
    Prototype clone();
}

// 具体原型类
public class ConcretePrototype implements Prototype {
    private String name;
    
    public ConcretePrototype(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public Prototype clone() {
        return new ConcretePrototype(name);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Prototype prototype = new ConcretePrototype("原型对象");
        Prototype clone = prototype.clone();
        System.out.println(clone.getName());
    }
}

2. 结构型设计模式

2.1 适配器模式(Adapter)

适配器模式是一种结构型设计模式,它将一个类的接口转换为客户端所期望的另一个接口。它允许不兼容的接口之间的协作,并提高代码的可扩展性。

类适配器:

// 目标接口
public interface Target {
    void request();
}

// 源类
public class Adaptee {
    public void specificRequest() {
        System.out.println("Adaptee.specificRequest()");
    }
}

// 类适配器
public class ClassAdapter extends Adaptee implements Target {
    public void request() {
        specificRequest();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Target target = new ClassAdapter();
        target.request();
    }
}

对象适配器:

// 目标接口
public interface Target {
    void request();
}

// 源类
public class Adaptee {
    public void specificRequest() {
        System.out.println("Adaptee.specificRequest()");
    }
}

// 对象适配器
public class ObjectAdapter implements Target {
    private Adaptee adaptee;
    
    public ObjectAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    
    public void request() {
        adaptee.specificRequest();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new ObjectAdapter(adaptee);
        target.request();
    }
}

2.2 桥接模式(Bridge)

桥接模式是一种结构型设计模式,它将一个抽象类的实现与另一个实现解耦,从而允许它们独立地变化。这种模式可以提高代码的灵活性和可扩展性。

桥接模式的核心是抽象部分和实现部分的解耦,它们之间通过一个桥接对象来连接。桥接对象包含一个指向实现部分的引用,这个引用可以在运行时进行动态绑定:

// 抽象部分
public abstract class Abstraction {
    protected Implementor implementor;
    
    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }
    
    public abstract void operation();
}

// 实现部分
public interface Implementor {
    void operationImpl();
}

// 具体的抽象部分
public class ConcreteAbstraction extends Abstraction {
    public ConcreteAbstraction(Implementor implementor) {
        super(implementor);
    }
    
    public void operation() {
        implementor.operationImpl();
    }
}

// 具体的实现部分
public class ConcreteImplementorA implements Implementor {
    public void operationImpl() {
        System.out.println("ConcreteImplementorA.operationImpl()");
    }
}

public class ConcreteImplementorB implements Implementor {
    public void operationImpl() {
        System.out.println("ConcreteImplementorB.operationImpl()");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Implementor implementor = new ConcreteImplementorA();
        Abstraction abstraction = new ConcreteAbstraction(implementor);
        abstraction.operation();
        
        implementor = new ConcreteImplementorB();
        abstraction = new ConcreteAbstraction(implementor);
        abstraction.operation();
    }
}

2.3 组合模式(Composite)

组合模式是一种结构型设计模式,它允许您将对象组合成树状结构,并且能够像处理单个对象一样处理它们。这种模式有助于处理对象之间的层次关系,并简化代码结构。

下面是组合模式的一个示例,假设我们要创建一个图形编辑器,其中包含不同类型的图形,包括简单图形(如线、矩形和圆)和组合图形(如图形集合和图形组合)。我们可以使用组合模式来实现这个图形编辑器:

// 定义一个 Graphic 接口
public interface Graphic {
    void draw();
    void resize();
}

// 创建接口的不同实现
public class Line implements Graphic {
    @Override
    public void draw() {
        System.out.println("Draw a line.");
    }

    @Override
    public void resize() {
        System.out.println("Resize a line.");
    }
}

public class Rectangle implements Graphic {
    @Override
    public void draw() {
        System.out.println("Draw a rectangle.");
    }

    @Override
    public void resize() {
        System.out.println("Resize a rectangle.");
    }
}

public class Circle implements Graphic {
    @Override
    public void draw() {
        System.out.println("Draw a circle.");
    }

    @Override
    public void resize() {
        System.out.println("Resize a circle.");
    }
}

// 定义组合实现
public class GraphicGroup implements Graphic {
    private List<Graphic> graphics = new ArrayList<>();

    public void addGraphic(Graphic graphic) {
        graphics.add(graphic);
    }

    public void removeGraphic(Graphic graphic) {
        graphics.remove(graphic);
    }

    @Override
    public void draw() {
        System.out.println("Draw a group.");
        for (Graphic graphic : graphics) {
            graphic.draw();
        }
    }

    @Override
    public void resize() {
        System.out.println("Resize a group.");
        for (Graphic graphic : graphics) {
            graphic.resize();
        }
    }
}

public class Client {
    public static void main(String[] args) {
        Graphic line = new Line();
        Graphic rectangle = new Rectangle();
        GraphicGroup group1 = new GraphicGroup();
        group1.addGraphic(line);
        group1.addGraphic(rectangle);
        group1.draw();
        group1.resize();

        Graphic circle = new Circle();
        GraphicGroup group2 = new GraphicGroup();
        group2.addGraphic(circle);
        group2.draw();
        group2.resize();
    }
}

2.4 装饰器模式(Decorator)

装饰器模式是一种结构型设计模式,它允许您动态地将功能添加到对象中,而无需改变对象的原始类。这种模式可以提高代码的灵活性和可扩展性。

下面是一个示例,假设我们有一个简单的咖啡店,我们想要提供一些咖啡饮料,可以通过添加各种调料来自定义味道。我们可以使用装饰器模式来实现这个功能:

// 定义基础接口
public interface Beverage {
    String getDescription();
    double getCost();
}

// 定义实现类
public class Espresso implements Beverage {
    @Override
    public String getDescription() {
        return "Espresso";
    }

    @Override
    public double getCost() {
        return 1.99;
    }
}

public class HouseBlend implements Beverage {
    @Override
    public String getDescription() {
        return "House Blend Coffee";
    }

    @Override
    public double getCost() {
        return 0.89;
    }
}

public class DarkRoast implements Beverage {
    @Override
    public String getDescription() {
        return "Dark Roast Coffee";
    }

    @Override
    public double getCost() {
        return 0.99;
    }
}

// 定义装饰器类
public abstract class CondimentDecorator implements Beverage {
    protected Beverage beverage;

    public CondimentDecorator(Beverage beverage) {
        this.beverage = beverage;
    }
}

public class Mocha extends CondimentDecorator {
    public Mocha(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    @Override
    public double getCost() {
        return beverage.getCost() + 0.20;
    }
}

public class Whip extends CondimentDecorator {
    public Whip(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Whip";
    }

    @Override
    public double getCost() {
        return beverage.getCost() + 0.10;
    }
}

public class Soy extends CondimentDecorator {
    public Soy(Beverage beverage) {
        super(beverage);
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Soy";
    }

    @Override
    public double getCost() {
        return beverage.getCost() + 0.15;
    }
}

public class Client {
    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        beverage = new Mocha(beverage);
        beverage = new Whip(beverage);
        System.out.println(beverage.getDescription() + " $" + beverage.getCost()); // Espresso, Mocha, Whip $2.29
    }
}

2.5 外观模式(Facade)

外观模式是一种结构型设计模式,它提供了一个简单的接口来访问复杂的子系统。这种模式有助于将系统的复杂性隐藏在一个单一的接口后面,并提高代码的可维护性和可扩展性。

举个例子,我们可以考虑一个家庭影院系统。这个系统可能由许多不同的设备组成,例如电视、音响、DVD 播放器等。如果我们需要操作这些设备,可能需要多个遥控器,并且需要对每个设备进行逐个设置。这是一件非常繁琐的事情。但是,如果我们将这些设备封装到一个单一的接口中,那么我们只需要使用一个遥控器就可以控制所有的设备:

public class HomeTheaterFacade {
    private final Amplifier amp;
    private final Tuner tuner;
    private final DvdPlayer dvd;
    private final CdPlayer cd;
    private final Projector projector;
    private final TheaterLights lights;
    private final Screen screen;
    private final PopcornPopper popper;

    public HomeTheaterFacade(Amplifier amp, Tuner tuner, DvdPlayer dvd, CdPlayer cd, Projector projector, TheaterLights lights, Screen screen, PopcornPopper popper) {
        this.amp = amp;
        this.tuner = tuner;
        this.dvd = dvd;
        this.cd = cd;
        this.projector = projector;
        this.lights = lights;
        this.screen = screen;
        this.popper = popper;
    }

    public void watchMovie(String movie) {
        System.out.println("Get ready to watch a movie...");
        popper.on();
        popper.pop();
        lights.dim(10);
        screen.down();
        projector.on();
        projector.setInput(dvd);
        projector.wideScreenMode();
        amp.on();
        amp.setDvd(dvd);
        amp.setSurroundSound();
        amp.setVolume(5);
        dvd.on();
        dvd.play(movie);
    }

    public void endMovie() {
        System.out.println("Shutting movie theater down...");
        popper.off();
        lights.on();
        screen.up();
        projector.off();
        amp.off();
        dvd.stop();
        dvd.eject();
        dvd.off();
    }

    public void listenToCd(String cdTitle) {
        System.out.println("Get ready for an audiopile experence...");
        lights.on();
        amp.on();
        amp.setVolume(5);
        amp.setCd(cd);
        amp.setStereoSound();
        cd.on();
        cd.play(cdTitle);
    }

    public void endCd() {
        System.out.println("Shutting down CD...");
        amp.off();
        amp.setCd(cd);
        cd.eject();
        cd.off();
    }

    public void listenToRadio(double frequency) {
        System.out.println("Tuning in the airwaves...");
        tuner.on();
        tuner.setFrequency(frequency);
        amp.on();
        amp.setVolume(5);
        amp.setTuner(tuner);
    }

    public void endRadio() {
        System.out.println("Shutting down the tuner...");
        tuner.off();
        amp.off();
    }
}

2.6 享元模式(Flyweight)

享元模式是一种结构型设计模式,它通过共享尽可能多的对象来减少内存使用。这种模式适用于需要创建大量相似对象的情况,可以提高应用程序的性能和效率。

以下是一个享元模式的示例代码,模拟一个网站中的博客文章:

public class BlogPostFactory {
    private Map<String, BlogPost> posts;

    public BlogPostFactory() {
        this.posts = new HashMap<>();
    }

    public BlogPost createPost(String author, String title, String body, String category) {
        String key = author + "_" + category;
        BlogPost post = posts.get(key);

        if (post == null) {
            post = new BlogPost(author, title, body, category);
            posts.put(key, post);
        }

        return post;
    }

    public int getNumberOfPosts() {
        return posts.size();
    }
}

public class BlogPost {
    private String author;
    private String title;
    private String body;
    private String category;

    public BlogPost(String author, String title, String body, String category) {
        this.author = author;
        this.title = title;
        this.body = body;
        this.category = category;
    }

    public void display() {
        System.out.println("Author: " + author);
        System.out.println("Title: " + title);
        System.out.println("Body: " + body);
        System.out.println("Category: " + category);
    }
}

public class Client {
    public static void main(String[] args) {
        BlogPostFactory factory = new BlogPostFactory();

        BlogPost post1 = factory.createPost("John Doe", "My Blog Post", "This is my first blog post", "Technology");
        BlogPost post2 = factory.createPost("Jane Doe", "My Blog Post", "This is my first blog post", "Technology");

        post1.display(); // Output: Author: John Doe Title: My Blog Post Body: This is my first blog post Category: Technology
        post2.display(); // Output: Author: Jane Doe Title: My Blog Post Body: This is my first blog post Category: Technology

        System.out.println("Number of posts: " + factory.getNumberOfPosts()); // Output: Number of posts: 1
    }
}

2.7 代理模式(Proxy)

代理模式是一种结构型设计模式,它提供了一个代理对象来控制对原始对象的访问。代理模式可以用于实现访问控制、延迟加载和远程调用等功能,从而提高代码的可扩展性和可维护性。

以下是一个简单的示例,演示如何使用代理模式来实现对远程服务的访问:

// 定义服务接口
public interface RemoteService {
    void doSomething();
}

// 远程服务的实现
public class RemoteServiceImpl implements RemoteService {
    @Override
    public void doSomething() {
        System.out.println("Doing something remotely...");
    }
}

// 代理类
public class RemoteServiceProxy implements RemoteService {
    private RemoteService remoteService;

    public RemoteServiceProxy(RemoteService remoteService) {
        this.remoteService = remoteService;
    }

    @Override
    public void doSomething() {
        System.out.println("Verifying user access...");
        remoteService.doSomething();
        System.out.println("Caching data...");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        RemoteService remoteService = new RemoteServiceImpl();
        RemoteService proxy = new RemoteServiceProxy(remoteService);
        proxy.doSomething();
    }
}

3. 行为型设计模式

3.1 责任链模式(Chain of Responsibility)

责任链模式是一种行为型设计模式,它允许您将请求沿着处理链传递,直到找到可以处理请求的对象。这种模式可以帮助您实现松散耦合的对象之间的通信,并提高代码的可扩展性和可维护性。

以下是一个简单的示例,假设一个员工提交了一个请假申请,需要被经理、部门主管和公司总经理逐级审批才能生效,我们可以使用责任链模式来实现这个流程:

// 抽象处理者接口
public interface LeaveRequestHandler {
    void handleRequest(LeaveRequest request);
    void setNextHandler(LeaveRequestHandler nextHandler);
}

// 定义三个具体的处理者
public class Manager implements LeaveRequestHandler {
    private LeaveRequestHandler nextHandler;

    @Override
    public void setNextHandler(LeaveRequestHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() <= 3) {
            System.out.println("经理审批通过:" + request);
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            } else {
                System.out.println("请假申请未通过!");
            }
        }
    }
}

public class Director implements LeaveRequestHandler {
    private LeaveRequestHandler nextHandler;

    @Override
    public void setNextHandler(LeaveRequestHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() <= 7) {
            System.out.println("部门主管审批通过:" + request);
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            } else {
                System.out.println("请假申请未通过!");
            }
        }
    }
}

public class CEO implements LeaveRequestHandler {
    private LeaveRequestHandler nextHandler;

    @Override
    public void setNextHandler(LeaveRequestHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() <= 30) {
            System.out.println("公司总经理审批通过:" + request);
        } else {
            System.out.println("请假申请未通过!");
        }
    }
}

public class Client {
    public static void main(String[] args) {
        LeaveRequestHandler ceo = new CEO();
        LeaveRequestHandler director = new Director();
        director.setNextHandler(ceo);
        LeaveRequestHandler manager = new Manager();
        manager.setNextHandler(director);

        LeaveRequest request = new LeaveRequest("张三", 5, "家里有急事,请假5天");
        manager.handleRequest(request);

    }
}

3.2 命令模式(Command)

命令模式是一种行为型设计模式,它将请求封装成对象,从而允许您参数化不同的请求、队列或记录请求日志,并支持可撤销操作。这种模式可以提高代码的灵活性和可扩展性。

以下是一个简单的示例,演示如何使用命令模式实现一个简单的遥控器:

// 命令接口
public interface Command {
    void execute();
}

// 接收者
public class Light {
    public void on() {
        System.out.println("Light is on");
    }

    public void off() {
        System.out.println("Light is off");
    }
}

// 开灯命令
public class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.on();
    }
}

// 关灯命令
public class LightOffCommand implements Command {
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.off();
    }
}

// 遥控器
public class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOnCommand = new LightOnCommand(light);
        Command lightOffCommand = new LightOffCommand(light);

        RemoteControl remoteControl = new RemoteControl();
        remoteControl.setCommand(lightOnCommand);
        remoteControl.pressButton();

        remoteControl.setCommand(lightOffCommand);
        remoteControl.pressButton();
    }
}

3.3 解释器模式(Interpreter)

解释器模式是一种行为型设计模式,它定义了一种语言,用于解释指定的问题。这种模式可以帮助您将复杂的问题分解成简单的问题,并提高代码的可维护性和可扩展性。

以下是一个简单的示例,演示如何使用解释器模式来解析简单的数学表达式:

// 抽象表达式类
public abstract class Expression {
    public abstract int interpret();
}

// 数字表达式类
public class NumberExpression extends Expression {
    private int number;

    public NumberExpression(int number) {
        this.number = number;
    }

    @Override
    public int interpret() {
        return number;
    }
}

// 加法表达式类
public class AddExpression extends Expression {
    private Expression left;
    private Expression right;

    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() + right.interpret();
    }
}

// 减法表达式类
public class SubtractExpression extends Expression {
    private Expression left;
    private Expression right;

    public SubtractExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() - right.interpret();
    }
}

// 解释器
public class Interpreter {
    private Expression expression;

    public Interpreter(Expression expression) {
        this.expression = expression;
    }

    public int interpret() {
        return expression.interpret();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        // 构造一个表达式:(5 + 3) - 2
        Expression expression = new SubtractExpression(
            new AddExpression(new NumberExpression(5), new NumberExpression(3)),
            new NumberExpression(2));

        // 构造一个解释器
        Interpreter interpreter = new Interpreter(expression);

        // 执行解释器
        System.out.println(interpreter.interpret()); // 输出 6
    }
}

3.4 迭代器模式(Iterator)

迭代器模式是一种行为型设计模式,它提供了一种简单的方式来遍历集合对象中的元素。这种模式可以帮助您将集合对象与它们的遍历方式分离开来,并提高代码的可读性和可维护性。

以下是一个简单的示例,演示如何使用迭代器模式来遍历一个列表:

// 抽象迭代器类
public interface Iterator<T> {
    boolean hasNext();
    T next();
}

// 具体迭代器类
public class ListIterator<T> implements Iterator<T> {
    private List<T> list;
    private int position;

    public ListIterator(List<T> list) {
        this.list = list;
        this.position = 0;
    }

    @Override
    public boolean hasNext() {
        return position < list.size();
    }

    @Override
    public T next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        T element = list.get(position);
        position++;
        return element;
    }
}

// 抽象集合类
public interface IterableCollection<T> {
    Iterator<T> iterator();
}

// 具体集合类
public class ListCollection<T> implements IterableCollection<T> {
    private List<T> list;

    public ListCollection(List<T> list) {
        this.list = list;
    }

    @Override
    public Iterator<T> iterator() {
        return new ListIterator<T>(list);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("Apple");
        list.add("Banana");
        list.add("Orange");

        ListCollection<String> collection = new ListCollection<String>(list);

        Iterator<String> iterator = collection.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println(element);
        }
    }
}

3.5 中介者模式(Mediator)

中介者模式是一种行为型设计模式,它允许您封装对象之间的交互作用,并使它们之间的通信更加松散耦合。这种模式可以帮助您减少代码中的紧耦合关系,并提高代码的可维护性和可扩展性。

以下是一个简单的示例,演示如何使用中介者模式来协调多个用户之间的聊天:

// 抽象中介者类
public abstract class ChatMediator {
    public abstract void sendMessage(String message, User user);
}

// 具体中介者类
public class ChatMediatorImpl extends ChatMediator {
    private List<User> users;

    public ChatMediatorImpl() {
        this.users = new ArrayList<User>();
    }

    public void addUser(User user) {
        users.add(user);
    }

    @Override
    public void sendMessage(String message, User sender) {
        for (User user : users) {
            if (user != sender) {
                user.receiveMessage(message);
            }
        }
    }
}

// 抽象同事类
public abstract class User {
    protected ChatMediator mediator;
    protected String name;

    public User(ChatMediator mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    }

    public abstract void sendMessage(String message);

    public abstract void receiveMessage(String message);
}

// 具体同事类
public class ChatUser extends User {
    public ChatUser(ChatMediator mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println(name + " received message: " + message);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ChatMediator mediator = new ChatMediatorImpl();

        User user1 = new ChatUser(mediator, "User1");
        User user2 = new ChatUser(mediator, "User2");
        User user3 = new ChatUser(mediator, "User3");

        mediator.addUser(user1);
        mediator.addUser(user2);
        mediator.addUser(user3);

        user1.sendMessage("Hi everyone!");
    }
}

3.6 备忘录模式(Memento)

备忘录模式是一种行为型设计模式,它允许您保存对象的状态,以便稍后恢复它。这种模式可以帮助您实现撤销和重做等功能,并提高代码的可扩展性和可维护性。

例:

// 发起人类
public class Originator {
    private String state;
 
    public void setState(String state) {
        this.state = state;
    }
 
    public String getState() {
        return state;
    }
 
    // 创建备忘录,将当前状态保存到备忘录中
    public Memento createMemento() {
        return new Memento(state);
    }
 
    // 恢复状态
    public void restoreMemento(Memento memento) {
        this.state = memento.getState();
    }
}
 
// 备忘录类
public class Memento {
    private String state;
 
    public Memento(String state) {
        this.state = state;
    }
 
    public String getState() {
        return state;
    }
}
 
// 管理者类
public class Caretaker {
    private Memento memento;
 
    public void setMemento(Memento memento) {
        this.memento = memento;
    }
 
    public Memento getMemento() {
        return memento;
    }
}

3.7 观察者模式(Observer)

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这种模式可以帮助您实现松散耦合的对象之间的通信,并提高代码的可扩展性和可维护性。

假设我们有一个气象站,它会定期地测量当前的温度、湿度和气压,并将这些数据发送给所有注册了的观察者。我们可以用观察者模式来实现这个气象站:

// 定义一个主题接口
public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 定义一个观察者接口
public interface Observer {
    void update(float temperature, float humidity, float pressure);
}

// 实现一个具体的气象站类

public class WeatherStation implements Subject {
    private List<Observer> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherStation() {
        observers = new ArrayList<>();
    }

    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }

    public void measurementsChanged() {
        notifyObservers();
    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(temperature, humidity, pressure);
        }
    }
}


// 定义一个具体的观察者类
public class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;

    @Override
    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        display();
    }

    public void display() {
        System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
    }
}

public class Client {
    public static void main(String[] args) {
        WeatherStation weatherStation = new WeatherStation();
        Observer currentConditionsDisplay = new CurrentConditionsDisplay();
        weatherStation.registerObserver(currentConditionsDisplay);
        weatherStation.setMeasurements(80, 65, 30.4f);
        weatherStation.setMeasurements(82, 70, 29.2f);
        weatherStation.setMeasurements(78, 90, 29.2f);
    }
}

3.8 状态模式(State)

状态模式是一种行为型设计模式,它允许对象在内部状态发生变化时改变其行为。这种模式可以帮助您消除大量的条件语句,并提高代码的可读性和可维护性。

例:

// 状态接口
interface State {
    void pressButton(TV context);
}

// 具体状态实现类
class OnState implements State {
    public void pressButton(TV context) {
        System.out.println("电视机已经开机,现在关机。");
        context.setState(new OffState());
    }
}

class OffState implements State {
    public void pressButton(TV context) {
        System.out.println("电视机已经关机,现在开机。");
        context.setState(new OnState());
    }
}

class MuteState implements State {
    public void pressButton(TV context) {
        System.out.println("电视机已经静音,现在取消静音。");
        context.setState(new OnState());
    }
}

// 上下文类
class TV {
    private State state;

    public TV(State state) {
        this.state = state;
    }

    public void setState(State state) {
        this.state = state;
    }

    public void pressButton() {
        state.pressButton(this);
    }
}

// 测试代码
public class StatePatternDemo {
    public static void main(String[] args) {
        TV tv = new TV(new OffState());
        tv.pressButton();
        tv.pressButton();
        tv.pressButton();
    }
}

3.9 策略模式(Strategy)

策略模式是一种行为型设计模式,它定义了一系列算法,并将每个算法封装到单独的对象中,从而使它们可以相互替换。这种模式可以帮助您实现动态算法选择,并提高代码的可扩展性和可维护性。

假设有一个商店出售各种商品,商店需要根据不同的销售策略来计算折扣价格。我们可以使用策略模式来实现这个功能:

// 定义商品
public class Product {
    private String name;
    private double price;
    private DiscountStrategy discountStrategy;
    
    public Product(String name, double price, DiscountStrategy discountStrategy) {
        this.name = name;
        this.price = price;
        this.discountStrategy = discountStrategy;
    }
    
    public double getDiscountPrice() {
        return discountStrategy.calculateDiscount(price);
    }
    
    // getter and setter methods
}

// 定义打折策略
public interface DiscountStrategy {
    double calculateDiscount(double price);
}

public class FixedAmountDiscountStrategy implements DiscountStrategy {
    private double discountAmount;
    
    public FixedAmountDiscountStrategy(double discountAmount) {
        this.discountAmount = discountAmount;
    }
    
    @Override
    public double calculateDiscount(double price) {
        return price - discountAmount;
    }
}

public class PercentageDiscountStrategy implements DiscountStrategy {
    private double discountRate;
    
    public PercentageDiscountStrategy(double discountRate) {
        this.discountRate = discountRate;
    }
    
    @Override
    public double calculateDiscount(double price) {
        return price * (1 - discountRate);
    }   
}

// 购物实现
public class Shop {
    public static void main(String[] args) {
        Product product1 = new Product("iPhone X", 799.99, new PercentageDiscountStrategy(0.1));
        Product product2 = new Product("MacBook Pro", 1499.99, new FixedAmountDiscountStrategy(200));
        
        System.out.println("Discounted price for " + product1.getName() + ": " + product1.getDiscountPrice()); // Discounted price for iPhone X: 719.991
        System.out.println("Discounted price for " + product2.getName() + ": " + product2.getDiscountPrice()); // Discounted price for MacBook Pro: 1299.99
    }
}

3.10 模板方法模式(Template Method)

模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,并将其具体实现留给子类。这种模式可以帮助您将重复的代码提取到基类中,并提高代码的可读性和可维护性。

例:

abstract class DataExporter {
    // 声明导出方法为final,不允许子类覆盖
    public final void exportData() {
        prepareData();
        writeData();
        finalizeData();
    }

    // 子类必须实现这些方法
    protected abstract void prepareData();
    protected abstract void writeData();

    // finalizeData有一个默认实现,子类可以覆盖
    protected void finalizeData() {
        // do nothing
    }
}

class ExcelExporter extends DataExporter {
    private String data;

    public ExcelExporter(String data) {
        this.data = data;
    }

    @Override
    protected void prepareData() {
        System.out.println("ExcelExporter: Prepare data");
        // prepare data here
    }

    @Override
    protected void writeData() {
        System.out.println("ExcelExporter: Write data to Excel file");
        // write data to Excel file here
    }
}

class CsvExporter extends DataExporter {
    private String data;

    public CsvExporter(String data) {
        this.data = data;
    }

    @Override
    protected void prepareData() {
        System.out.println("CsvExporter: Prepare data");
        // prepare data here
    }

    @Override
    protected void writeData() {
        System.out.println("CsvExporter: Write data to CSV file");
        // write data to CSV file here
    }

    @Override
    protected void finalizeData() {
        System.out.println("CsvExporter: Finalize data");
        // finalize data here
    }
}

public class TemplateMethodExample {
    public static void main(String[] args) {
        DataExporter exporter = new ExcelExporter("Excel data");
        exporter.exportData();

        System.out.println();

        exporter = new CsvExporter("CSV data");
        exporter.exportData();
    }
}

3.11 访问者模式(Visitor)

访问者模式是一种行为型设计模式,它允许您在不修改对象结构的情况下定义新的操作。这种模式可以帮助您将对象的操作与对象本身分离开来,并提高代码的可扩展性和可维护性。

下面是一个访问者模式的示例,它演示了如何对一个包含不同类型元素的数据结构进行操作:

// 定义Visitor接口
public interface Visitor {
    void visit(Book book);
    void visit(Movie movie);
    void visit(Audio audio);
}

// 定义元素类
public interface Element {
    void accept(Visitor visitor);
}

public class Book implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

public class Movie implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

public class Audio implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// 实现不同的Visitor
public class DiscountVisitor implements Visitor {
    @Override
    public void visit(Book book) {
        System.out.println("Applying 10% discount to book " + book);
    }

    @Override
    public void visit(Movie movie) {
        System.out.println("Applying 5% discount to movie " + movie);
    }

    @Override
    public void visit(Audio audio) {
        System.out.println("Applying 15% discount to audio " + audio);
    }
}

public class PromotionVisitor implements Visitor {
    @Override
    public void visit(Book book) {
        System.out.println("Applying buy one get one free promotion to book " + book);
    }

    @Override
    public void visit(Movie movie) {
        System.out.println("Applying 50% off promotion to movie " + movie);
    }

    @Override
    public void visit(Audio audio) {
        System.out.println("Applying 20% off promotion to audio " + audio);
    }
}

// 定义购物车
public class ShoppingCart {
    private List<Element> elements = new ArrayList<>();

    public void add(Element element) {
        elements.add(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}

public class VisitorDemo {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.add(new Book());
        cart.add(new Movie());
        cart.add(new Audio());

        Visitor discountVisitor = new DiscountVisitor();
        cart.accept(discountVisitor);

        Visitor promotionVisitor = new PromotionVisitor();
        cart.accept(promotionVisitor);
    }
}

你可能感兴趣的:(设计模式)