您现在的位置是:首页 >技术教程 >【八股学习】设计模式网站首页技术教程

【八股学习】设计模式

illus10n_CHOU 2025-02-15 00:01:02
简介【八股学习】设计模式

本文将介绍几种常用于项目中的设计模式和SpringBoot使用到的设计模式

行为模式

策略模式

将不同的算法封装在独立的类中,并且抽取出一个独立的接口来约束其策略,使得他们之间可以相互替换。
需要用到的类/接口如下:
1、Strategy 接口,里面定义一个策略应该实现的方法

public interface DiscountStrategy {
    // 计算折扣额度:
    BigDecimal getDiscount(BigDecimal total);
}

2、Strategy 实现类,实现Strategy 接口中的所有方法,可以定义多个不同的策略供选择

public class UserDiscountStrategy implements DiscountStrategy {
    public BigDecimal getDiscount(BigDecimal total) {
        // 普通会员打九折:
        return total.multiply(new BigDecimal("0.1")).setScale(2, RoundingMode.DOWN);
    }
}

public class OverDiscountStrategy implements DiscountStrategy {
    public BigDecimal getDiscount(BigDecimal total) {
        // 满100减20优惠:
        return total.compareTo(BigDecimal.valueOf(100)) >= 0 ? BigDecimal.valueOf(20) : BigDecimal.ZERO;
    }
}

3、Context 类,可以持有某一个策略,或者指定一个默认策略

DiscountContext ctx = new DiscountContext();

```java
public class DiscountContext {
    // 持有某个策略:
    private DiscountStrategy strategy = new UserDiscountStrategy();

    // 允许客户端设置新策略:
    public void setStrategy(DiscountStrategy strategy) {
        this.strategy = strategy;
    }

    public BigDecimal calculatePrice(BigDecimal total) {
        return total.subtract(this.strategy.getDiscount(total)).setScale(2);
    }
}

4、调用方式:

// 默认使用普通会员折扣:
BigDecimal pay1 = ctx.calculatePrice(BigDecimal.valueOf(105));
System.out.println(pay1);

// 使用满减折扣:
ctx.setStrategy(new OverDiscountStrategy());
BigDecimal pay2 = ctx.calculatePrice(BigDecimal.valueOf(105));
System.out.println(pay2);

// 使用Prime会员折扣:
ctx.setStrategy(new PrimeDiscountStrategy());
BigDecimal pay3 = ctx.calculatePrice(BigDecimal.valueOf(105));
System.out.println(pay3);

模版方法

定义一个操作的一系列步骤,对于某些暂时确定不下来的步骤,就留给子类去实现,这样不同的子类就可以定义出不同的步骤。

Spring中很多以Template结尾的对数据库操作的类,都使用到了模版方法

需要使用的类如下:
1、一个抽象的模板方法,定义好了主要的执行流程,但是流程中部分方法的具体实现并没有被实现、并且可以有不同的实现:
为了让子方法可以更改,我们需要将待实现方法抽象,自然也就要将方法变成抽象方法

public abstract class AbstractSetting {
    public final String getSetting(String key) {
        String value = lookupCache(key);
        if (value == null) {
            value = readFromDatabase(key);
            putIntoCache(key, value);
        }
        return value;
    }

    protected abstract String lookupCache(String key);

    protected abstract void putIntoCache(String key, String value);
}

2、继承抽象类的子类,进行抽象方法的具体实现,不关心具体的流程,只关心方法实现

// 我们希望用一个Map做缓存,那么可以写一个LocalSetting
public class LocalSetting extends AbstractSetting {
    private Map<String, String> cache = new HashMap<>();

    protected String lookupCache(String key) {
        return cache.get(key);
    }

    protected void putIntoCache(String key, String value) {
        cache.put(key, value);
    }
}

3、调用方法:

AbstractSetting setting1 = new LocalSetting();
System.out.println("test = " + setting1.getSetting("test"));
System.out.println("test = " + setting1.getSetting("test"));

观察者模式

观察者模式(Observer)又称发布-订阅模式(Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方(被观察方)和接收通知的一方(观察者)能彼此分离,互不影响。

观察者模式就是要分离被观察者和观察者之间的耦合关系,因为发送消息的人不想知道接受消息的人具体是谁。

这里我们介绍 Spring 事件驱动模型中的角色:
1、事件角色
ApplicationEvent (org.springframework.context包下)充当事件的角色,这是一个抽象类。

2、事件监听者对象
ApplicationListener 充当了事件监听者角色,它是一个接口,里面只定义了一个 onApplicationEvent()方法来处理ApplicationEvent

package org.springframework.context;
import java.util.EventListener;
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
    void onApplicationEvent(E var1);
}

3、事件发布者角色
ApplicationEventPublisher 充当了事件的发布者,它也是一个接口。

@FunctionalInterface
public interface ApplicationEventPublisher {
    default void publishEvent(ApplicationEvent event) {
        this.publishEvent((Object)event);
    }

    void publishEvent(Object var1);
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。