您现在的位置是:首页 >技术教程 >【八股学习】设计模式网站首页技术教程
【八股学习】设计模式
本文将介绍几种常用于项目中的设计模式和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);
}