常见设计模式之Java实现

引言

设计模式是软件工程中的一套被反复使用的、大家公认的、经过分类编目的代码设计经验的总结。它们是解决特定问题的模板,可以提高代码的可重用性、可读性和可维护性。本文将介绍Java中常见的20种设计模式,并提供具体的使用场景、设计模式的解释以及示例代码。

创建型模式

单例模式(Singleton)

使用场景 :需要确保某个类只有一个实例,并且提供一个全局访问点。
解释 :单例模式确保一个类只有一个实例,并提供一个全局访问点。
示例代码

java 复制代码
public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

工厂方法模式(Factory Method)

使用场景 :当需要创建对象的类很多时,可以使用工厂方法模式来封装对象的创建过程。
解释 :定义一个用于创建对象的接口,让子类决定实例化哪一个类。
示例代码

java 复制代码
interface Product {
    void use();
}

class ConcreteProduct implements Product {
    public void use() {
        // ...
    }
}

abstract class Creator {
    abstract Product factoryMethod();
}

class ConcreteCreator extends Creator {
    public Product factoryMethod() {
        return new ConcreteProduct();
    }
}

抽象工厂模式(Abstract Factory)

使用场景 :当需要创建多个相关或依赖对象的家族时。
解释 :提供一个创建一系列相关或相互依赖对象的接口,而不需要指定它们具体的类。
示例代码

java 复制代码
// 类似工厂方法模式,但增加了多个产品族的创建

建造者模式(Builder)

使用场景 :当创建复杂对象时,需要逐步构建。
解释 :将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
示例代码

java 复制代码
class Product {
    // ...
}

class Builder {
    private Product product = new Product();
    public Builder setPart1(String part1) {
        product.setPart1(part1);
        return this;
    }
    // ...
    public Product build() {
        return product;
    }
}

原型模式(Prototype)

使用场景 :当创建新对象成本较高时,可以使用原型模式。
解释 :通过拷贝现有的实例来创建新的实例,而不是通过新建。
示例代码

java 复制代码
class Prototype implements Cloneable {
    // ...
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

结构型模式

适配器模式(Adapter)

使用场景 :当需要将一个类的接口转换成客户期望的另一个接口时。
解释 :使原本由于接口不兼容而不能一起工作的类可以一起工作。
示例代码

java 复制代码
interface Target {
    void request();
}

class Adaptee {
    public void specificRequest() {
        // ...
    }
}

class Adapter implements Target {
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    public void request() {
        adaptee.specificRequest();
    }
}

装饰器模式(Decorator)

使用场景 :当需要动态地给一个对象添加额外的职责时。
解释 :在不修改对象结构的情况下,动态地给对象添加职责。
示例代码

java 复制代码
interface Component {
    void operate();
}

class ConcreteComponent implements Component {
    public void operate() {
        // ...
    }
}

abstract class Decorator implements Component {
    protected Component component;
    public Decorator(Component component) {
        this.component = component;
    }
    public void operate() {
        component.operate();
    }
}

class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }
    public void operate() {
        super.operate();
        // 添加额外职责
    }
}

代理模式(Proxy)

使用场景 :当需要控制对原始对象的访问时。
解释 :为其他对象提供一个代替或占位符作为它的接口。
示例代码

java 复制代码
interface Subject {
    void request();
}

class RealSubject implements Subject {
    public void request() {
        // ...
    }
}

class Proxy implements Subject {
    private RealSubject realSubject;
    public Proxy() {
        this.realSubject = null;
    }
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        realSubject.request();
    }
}

外观模式(Facade)

使用场景 :当需要提供一个客户端可以访问系统的复杂接口的简化接口时。
解释 :定义一个高层接口,使得子系统更容易使用。
示例代码

java 复制代码
interface SubSystem {
    void operation();
}

class SubSystem0 implements SubSystem {
    public void operation() {
        // ...
    }
}

class SubSystem1 implements SubSystem {
    public void operation() {
        // ...
    }
}

class Facade {
    private SubSystem0 subSystem0 = new SubSystem0();
    private SubSystem1 subSystem1 = new SubSystem1();
    public void operation() {
        subSystem0.operation();
        subSystem1.operation();
    }
}

桥接模式(Bridge)

使用场景 :当需要将抽象部分与它的实现部分分离,使它们可以独立地变化时。
解释 :将抽象与实现解耦,让它们可以独立地变化。
示例代码

java 复制代码
abstract class Abstraction {
    protected Implementor implementor;
    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }
    public void operation() {
        implementor.operationImpl();
    }
}

interface Implementor {
    void operationImpl();
}

class ConcreteImplementorA implements Implementor {
    public void operationImpl() {
        // ...
    }
}

class RefinedAbstraction extends Abstraction {
    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }
    // ...
}

组合模式(Composite)

使用场景 :当需要将对象组合成树形结构以表示"部分-整体"的层次结构时。
解释 :将对象组合成树形结构来表示"部分-整体"的层次结构。
示例代码

java 复制代码
interface Component {
    void operation();
}

class Leaf implements Component {
    public void operation() {
        // ...
    }
}

class Composite implements Component {
    private List<Component> children = new ArrayList<>();
    public void add(Component component) {
        children.add(component);
    }
    public void operation() {
        for (Component component : children) {
            component.operation();
        }
    }
}

享元模式(Flyweight)

使用场景 :当需要减少创建大量相似对象时。
解释 :通过共享来高效地支持大量细粒度的对象。
示例代码

java 复制代码
class Flyweight {
    private String intrinsicState;
    public Flyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }
    public void operation(String extrinsicState) {
        // ...
    }
}

class FlyweightFactory {
    private HashMap<String, Flyweight> flyweights = new HashMap<>();
    public Flyweight getFlyweight(String key) {
        if (!flyweights.containsKey(key)) {
            flyweights.put(key, new Flyweight(key));
        }
        return flyweights.get(key);
    }
}

行为型模式

策略模式(Strategy)

使用场景 :当需要在运行时选择算法或行为时。
解释 :定义一系列算法,把它们一个个封装起来,并使它们可互换。
示例代码

java 复制代码
interface Strategy {
    void algorithmInterface();
}

class ConcreteStrategyA implements Strategy {
    public void algorithmInterface() {
        // ...
    }
}

class Context {
    private Strategy strategy;
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    public void executeStrategy() {
        strategy.algorithmInterface();
    }
}

模板方法模式(Template Method)

使用场景 :当需要在方法中定义算法的框架,将一些步骤的实现延迟到子类中时。
解释 :定义算法的骨架,将一些步骤的实现延迟到子类中。
示例代码

java 复制代码
abstract class AbstractClass {
    public void templateMethod() {
        step1();
        step2();
        step3();
    }
    public abstract void step2();
    public void step1() {
        // ...
    }
    public void step3() {
        // ...
    }
}

class ConcreteClass extends AbstractClass {
    public void step2(){
        // ...
    }
}

观察者模式(Observer)

使用场景 :当一个对象的改变需要同时改变其他对象,而不知道具体有多少对象待改变时。
解释 :对象间存在一对多关系时,则使用观察者模式。
示例代码

java 复制代码
interface Observer {
    void update();
}

interface Subject {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();
}

class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    public void registerObserver(Observer o) {
        observers.add(o);
    }
    public void removeObserver(Observer o) {
        observers.remove(o);
    }
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

class ConcreteObserver implements Observer {
    public void update() {
        // ...
    }
}

迭代器模式(Iterator)

使用场景 :当需要访问一个聚合对象中的元素,而又不暴露其内部的表示时。
解释 :提供一种顺序访问一个聚合对象中的各个元素的方法,而又不暴露其内部的表示。
示例代码

java 复制代码
interface Iterator {
    boolean hasNext();
    Object next();
}

interface Aggregate {
    Iterator createIterator();
}

class ConcreteIterator implements Iterator {
    private List items;
    private int position = 0;
    public ConcreteIterator(List items) {
        this.items = items;
    }
    public boolean hasNext() {
        return position < items.size();
    }
    public Object next() {
        return items.get(position++);
    }
}

class ConcreteAggregate implements Aggregate {
    private List items = new ArrayList();
    public Iterator createIterator() {
        return new ConcreteIterator(items);
    }
}

中介者模式(Mediator)

使用场景 :当系统中对象之间存在复杂的引用关系时。
解释 :用一个中介对象来封装一系列对象之间的交互。
示例代码

java 复制代码
interface Mediator {
    void register(String colleague, Colleague colleague);
    void relay(String colleague);
}

interface Colleague {
    void setMediator(Mediator mediator);
    void notify(String message);
}

class ConcreteMediator implements Mediator {
    private Map<String, Colleague> colleagues = new HashMap<>();
    public void register(String colleague, Colleague colleague) {
        colleagues.put(colleague, colleague);
    }
    public void relay(String colleague, String event) {
        Colleague c = colleagues.get(colleague);
        // ...
    }
}

class ConcreteColleagueA implements Colleague {
    private Mediator mediator;
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }
    public void notify(String message) {
        mediator.relay("ColleagueA", message);
    }
}

命令模式(Command)

使用场景 :当需要将请求封装为一个对象,从而使用不同的请求、队列或日志请求时。
解释 :将请求封装为一个对象,从而使你可用不同的请求、队列或日志来参数化其他对象。
示例代码

java 复制代码
interface Command {
    void execute();
}

class Receiver {
    public void action() {
        // ...
    }
}

class ConcreteCommand implements Command {
    private Receiver receiver;
    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }
    public void execute() {
        receiver.action();
    }
}

class Invoker {
    private Command command;
    public void setCommand(Command command) {
        this.command = command;
    }
    public void executeCommand() {
        command.execute();
    }
}

责任链模式(Chain of Responsibility)

使用场景 :当多个对象处理请求,但具体哪个对象处理该请求待运行时才能确定时。
解释 :使多个对象都有机会处理请求。从而避免请求的发送者和接收者之间的耦合关系。
示例代码

java 复制代码
interface Handler {
    void handleRequest(Request request);
}

class ConcreteHandler1 extends Handler {
    private Handler next;
    public void setNext(Handler next) {
        this.next = next;
    }
    public void handleRequest(Request request) {
        if (next != null) {
            next.handleRequest(request);
        }
    }
}

class Request {
    // ...
}

备忘录模式(Memento)

使用场景 :当需要保存和恢复对象的内部状态时。
解释 :在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
示例代码

java 复制代码
class Memento {
    private String state;
    public Memento(String state) {
        this.state = state;
    }
    public String getState() {
        return state;
    }
}

class Originator {
    private String state;
    public Memento saveStateToMemento() {
        return new Memento(state);
    }
    public void getStateFromMemento(Memento memento) {
        state = memento.getState();
    }
}

class Caretaker {
    private Memento memento;
    public void setMemento(Memento memento) {
        this.memento = memento;
    }
    public Memento getMemento() {
        return memento;
    }
}

状态模式(State)

使用场景 :当一个对象的行为取决于它的状态,并且它的状态值在运行时改变时。
解释 :允许对象在内部状态改变时改变它的行为。
示例代码

java 复制代码
interface State {
    void handle(StateContext context);
}

class ConcreteStateA implements State {
    public void handle(StateContext context) {
        // ...
    }
}

class StateContext {
    private State state;
    public StateContext(State state) {
        this.state = state;
    }
    public void handleState() {
        state.handle(this);
    }
}

访问者模式(Visitor)

使用场景 :当需要对一个对象结构中的对象进行操作,而又不想让这些操作依赖于对象的类时。
解释 :为一个对象结构(比如组合结构)增加新能力。
示例代码

java 复制代码
interface Element {
    void accept(Visitor visitor);
}

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

interface Visitor {
    void visit(ConcreteElementA element);
}

class ConcreteVisitor implements Visitor {
    public void visit(ConcreteElementA element) {
        // ...
    }
}

结语

本文介绍了Java中常见的20种设计模式,每种模式都提供了使用场景、简要的解释以及示例代码。设计模式是软件开发中的重要工具,它们帮助我们写出更加清晰、灵活且可维护的代码。希望本文能够帮助你更好地理解和应用设计模式。

相关推荐
hccee12 分钟前
C# IO文件操作
开发语言·c#
Viktor_Ye15 分钟前
高效集成易快报与金蝶应付单的方案
java·前端·数据库
hummhumm17 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
一二小选手22 分钟前
【Maven】IDEA创建Maven项目 Maven配置
java·maven
J老熊27 分钟前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
猿java32 分钟前
什么是 Hystrix?它的工作原理是什么?
java·微服务·面试
AuroraI'ncoding34 分钟前
时间请求参数、响应
java·后端·spring
zmd-zk41 分钟前
flink学习(2)——wordcount案例
大数据·开发语言·学习·flink
好奇的菜鸟1 小时前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang
所待.3831 小时前
JavaEE之线程初阶(上)
java·java-ee