掌握设计模式--模板方法模式

模板方法模式(Template Method Pattern)

模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个操作中的算法骨架,并允许子类在不改变算法结构的情况下重新定义算法的某些步骤。

核心思想:模板方法定义算法骨架,浅白地说,定义通用的逻辑框架、控制流程和调用顺序,而具体的实现将延迟到子类,从而在不改变结构的前提下扩展算法的灵活性。再简单点说:定义了一个处理逻辑的步骤(一个骨架),具体的处理逻辑由子类继承后实现(真正的血肉)。

主要组成部分

  1. 抽象类(AbstractClass)
  • 定义模板方法,模板方法包含算法的骨架。
  • 实现一些不变的步骤,或声明需要子类实现的抽象方法。
  1. 具体类(ConcreteClass)
  • 实现抽象类中声明的抽象方法,从而完成算法的具体步骤。

案例实现

实现一个简单的自定义锁,展示如何利用模板方法模式来定义锁的行为。

案例类图

定义抽象类 AbstractLock

AbstractLock 提供了模板方法(lockunlock),而具体的处理逻辑是获取锁和释放锁 方法tryAcquiretryRelease,这两个方法的具体实现交由子类完成。

java 复制代码
// 抽象类定义锁的框架
public abstract class AbstractLock {
    // 模板方法:锁的流程固定
    public final void lock() {
        if (!tryAcquire()) { // 尝试获取锁
            waitForLock();   // 获取失败时等待
        }
    }

    // 模板方法:解锁的流程固定
    public final void unlock() {
        if (tryRelease()) { // 尝试释放锁
            notifyWaitingThreads(); // 唤醒等待的线程
        }
    }

    // 钩子方法:尝试获取锁(子类实现)
    protected abstract boolean tryAcquire();

    // 钩子方法:尝试释放锁(子类实现)
    protected abstract boolean tryRelease();

    // 默认行为:等待获取锁(可以覆盖)
    protected void waitForLock() {
        try {
            synchronized (this) {
                wait(); // 阻塞线程
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    // 默认行为:通知等待线程(可以覆盖)
    protected void notifyWaitingThreads() {
        synchronized (this) {
            notifyAll(); // 唤醒所有等待线程
        }
    }
}

实现具体的锁 SimpleLock

SimpleLock 继承了 AbstractLock,并实现了具体的锁逻辑:

java 复制代码
public class SimpleLock extends AbstractLock {
    private boolean isLocked = false; // 锁状态
    private Thread lockingThread = null; // 持有锁的线程

    @Override
    protected synchronized boolean tryAcquire() {
        if (!isLocked) {
            isLocked = true;
            lockingThread = Thread.currentThread();
            return true;
        }
        return false;
    }

    @Override
    protected synchronized boolean tryRelease() {
        if (Thread.currentThread() == lockingThread) {
            isLocked = false;
            lockingThread = null;
            return true;
        }
        return false;
    }
}

测试 SimpleLock

通过多线程模拟锁的使用场景

java 复制代码
public class TemplateLockExample {
    public static void main(String[] args) {
        SimpleLock lock = new SimpleLock();

        Runnable task = () -> {
            lock.lock(); // 获取锁
            try {
                System.out.println(Thread.currentThread().getName() + " acquired the lock");
                Thread.sleep(1000); // 模拟任务执行
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println(Thread.currentThread().getName() + " released the lock");
                lock.unlock(); // 释放锁
            }
        };

        // 启动多个线程测试锁的互斥
        Thread t1 = new Thread(task, "Thread-1");
        Thread t2 = new Thread(task, "Thread-2");
        Thread t3 = new Thread(task, "Thread-3");

        t1.start();
        t2.start();
        t3.start();
    }
}

运行结果

复制代码
Thread-1 获得锁
Thread-1 释放锁
Thread-3 获得锁
Thread-2 获得锁
Thread-2 释放锁
Thread-3 释放锁

注:该案例并未正确实现完整的锁机制,仅仅为了讲述模版方法模式。

分析

  1. 模板方法的作用lockunlock 方法在 AbstractLock 中定义了锁的固定流程,子类只需实现具体的 tryAcquiretryRelease 方法即可。

  2. 扩展性 :可以通过继承 AbstractLock 实现不同的锁机制,例如:读写锁、可重入锁、公平锁等。

  3. 简化逻辑:模板方法模式将通用逻辑集中在抽象类中,避免子类重复实现。

优缺点和应用场景

优点

  1. 提高代码复用性,通用代码在父类中实现。
  2. 提供扩展灵活性,通过子类覆盖实现具体步骤。
  3. 符合开闭原则,增加新功能时无需修改模板方法。

缺点

  1. 每个具体实现都需要定义子类,导致类数量增加。
  2. 对算法步骤的控制较为严格,可能不适合所有场景。

应用场景

  1. 多个类的逻辑相同但细节不同:公共部分代码抽取到父类,具体实现由子类提供。
  2. 避免代码重复:在模板方法中实现通用逻辑,特定逻辑由子类实现。
  3. 固定框架:需要确保子类遵循算法的基本结构。

模板方法模式的应用

  1. Java中锁的实现(模版类AbstractQueuedSynchronizer,简称AQS),子类(如ReentrantLockReentrantReadWriteLock等)通过继承AQS并实现其抽象方法(如tryAcquiretryRelease等)来完成具体的同步逻辑;
  2. Java Swing 中的框架设计(例如 paint() 方法是一个模板方法);
  3. JUnit 中的测试框架(测试用例继承 TestCase 并重写具体方法)。

总结

在一个抽象类中定义一个模板方法作为算法骨架,其中包含若干通用逻辑和抽象步骤 ,通过子类实现 这些抽象步骤的具体逻辑 ,确保算法流程固定且具有灵活扩展性,同时实现代码复用和行为定制

需要查看往期设计模式文章的,可以在个人主页中或者文章开头的集合中查看,可关注我,持续更新中。。。


超实用的SpringAOP实战之日志记录

2023年下半年软考考试重磅消息

通过软考后却领取不到实体证书?

计算机算法设计与分析(第5版)

Java全栈学习路线、学习资源和面试题一条龙

软考证书=职称证书?

软考中级--软件设计师毫无保留的备考分享

相关推荐
庄小焱26 分钟前
设计模式——中介者设计模式(行为型)
设计模式
庄小焱3 小时前
设计模式——备忘录设计模式(行为型)
设计模式
庄小焱3 小时前
设计模式——代理设计模式(结构型)
设计模式
哆啦A梦的口袋呀3 小时前
基于Python学习《Head First设计模式》第三章 装饰者模式
python·学习·设计模式
哆啦A梦的口袋呀3 小时前
基于Python学习《Head First设计模式》第五章 单件模式
python·学习·设计模式
季鸢4 小时前
Java设计模式之备忘录模式详解
java·设计模式·备忘录模式
摘星编程8 小时前
工厂方法模式深度解析:从原理到应用实战
java·设计模式·软件工程·工厂方法模式
何中应8 小时前
【设计模式-4.7】行为型——备忘录模式
java·设计模式·备忘录模式
suixinger_lmh1 天前
功能结构整理
unity·设计模式·c#·源代码管理
冰茶_1 天前
建造者模式:优雅构建复杂对象
设计模式·微软·c#·.netcore·建造者模式·软件开发