一、观察者模式
观察者模式的应用场景非常广泛,小到代码层面的解耦,大到架构层面的系统解耦,再或者一些产品的设计思路,都有这种模式的影子,比如,邮件订阅、RSS Feeds,本质上都是观察者模式。不同的应用场景和需求下,这个模式也有截然不同的实现方式,有同步阻塞的实现方式,也有异步非阻塞的实现方式;有进程内的实现方式,也有跨进程的实现方式。
public interface RegObserver{
void handleRegSuccess(long userId);
}
public class RegPromotionObserver implements RegObserver{
private PromotionService promotionService;
// 依赖注入
@Override
public void handleRegSuccess(long userId){
promotionService.issueNewUserExperienceCash(userId);
}
}
public class RegNotificationObserver implements RegObserver{
private NotificationService notificationService;
@Override
public void handleRegSuccess(long userId){
notificationService.sendInboxMessage(userId, "Welcome...");
}
}
public class UserController{
private UserService userService;
// 依赖注入
private List<RegObserver> regObservers = new ArrayList<>();
// 一次性设置好,之后也不可能动态的修改
public void setRegObservers(List<RegObserver> observers){
regObservers.addAll(observers);
}
public Long register(String telephone, String password){
// 省略输入参数的校验代码
// 省略userService.register()异常的try-catch代码
long userId = userService.register(telephone, password);
for (RegObserver observer : regObservers) {
observer.handleRegSuccess(userId);
}
return userId;
}
}
参考:https://www.cnblogs.com/adamjwh/p/10913660.html
模版模式
模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。
抽象父类(AbstractClass):实现了模板方法,定义了算法的骨架。
具体类(ConcreteClass):实现抽象类中的抽象方法,即不同的对象的具体实现细节。
比如我们做菜可以分为三个步骤 (1)备料 (2)具体做菜 (3)盛菜端给客人享用,这三部就是算法的骨架 ;然而做不同菜需要的料,做的方法,以及如何盛装给客人享用都是不同的这个就是不同的实现细节
public abstract class DodishTemplate {
/**
* 具体的整个过程
*/
protected void dodish(){
this.preparation();
this.doing();
this.carriedDishes();
}
/**
* 备料
*/
public abstract void preparation();
/**
* 做菜
*/
public abstract void doing();
/**
* 上菜
*/
public abstract void carriedDishes ();
}
/**
* 西红柿炒蛋
* @author aries
*/
public class EggsWithTomato extends DodishTemplate{
@Override
public void preparation() {
System.out.println("洗并切西红柿,打鸡蛋。");
}
@Override
public void doing() {
System.out.println("鸡蛋倒入锅里,然后倒入西红柿一起炒。");
}
@Override
public void carriedDishes() {
System.out.println("将炒好的西红寺鸡蛋装入碟子里,端给客人吃。");
}
}
/**
* 红烧肉
* @author aries
*
*/
public class Bouilli extends DodishTemplate{
@Override
public void preparation() {
System.out.println("切猪肉和土豆。");
}
@Override
public void doing() {
System.out.println("将切好的猪肉倒入锅中炒一会然后倒入土豆连炒带炖。");
}
@Override
public void carriedDishes() {
System.out.println("将做好的红烧肉盛进碗里端给客人吃。");
}
}
public class App {
public static void main(String[] args) {
DodishTemplate eggsWithTomato = new EggsWithTomato();
eggsWithTomato.dodish();
System.out.println("-----------------------------");
DodishTemplate bouilli = new Bouilli();
bouilli.dodish();
}
}
引用自:https://www.cnblogs.com/qq-361807535/p/6854191.html
三、策略模式
定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它们的客户端(这里的客户端代指使用算法的代码)。
public interface Strategy {
public int doOperation(int num1, int num2);
}
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubtract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
}
}
四、责任链模式
将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。
在职责链模式中,多个处理器(也就是刚刚定义中说的“接收对象”)依次处理同一个请求。一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。
参考:https://blog.csdn.net/pange1991/article/details/81182958
五、状态模式
有限状态机,英文翻译是 Finite State Machine,缩写为 FSM,简称为状态机。状态机有3 个组成部分:状态(State)、事件(Event)、动作(Action)。其中,事件也称为转移条件(Transition Condition)。事件触发状态的转移及动作的执行。不过,动作不是必须的,也可能只转移状态,不执行任何动作。
那么我们如何实现这样的状态机呢?
状态机实现方式一:分支逻辑法
分支逻辑法是指,用最简单直接的实现方式,参照状态转移图,将每一个状态转移,原模原样地直译成代码。这样编写的代码会包含大量的 if-else 或switch-case 分支判断逻辑,甚至是嵌套的分支判断逻辑。但是这种方式可读性和可维护性都很差,违背“开闭原则”。
状态机实现方式二:查表法
除了用状态转移图来表示之外,状态机还可以用二维表来表示,如下所示。在这个二维表中,第一维表示当前状态,第二维表示事件,值表示当前状态经过事件之后,转移到的新状态及其执行的动作。
public enum Event {
GOT_MUSHROOM(0),
GOT_CAPE(1),
GOT_FIRE(2),
MET_MONSTER(3);
private int value;
private Event(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
}
public class MarioStateMachine{
privateint score;
private State currentState;
private static final State[][] transitionTable = {
{SUPER, CAPE, FIRE, SMALL},
{SUPER, CAPE, FIRE, SMALL},
{CAPE, CAPE, CAPE, SMALL},
{FIRE, FIRE, FIRE, SMALL}
};
private staticfinalint[][] actionTable = {
{+100, +200, +300, +0},
{+0, +200, +300, -100},
{+0, +0, +0, -200},
{+0, +0, +0, -300}
};
public MarioStateMachine(){
this.score = 0;
this.currentState = State.SMALL;
}
public void obtainMushRoom(){
executeEvent(Event.GOT_MUSHROOM);
}
public void obtainCape(){
executeEvent(Event.GOT_CAPE);
}
public void obtainFireFlower(){
executeEvent(Event.GOT_FIRE);
}
public void meetMonster(){
executeEvent(Event.MET_MONSTER);
}
private void executeEvent(Event event){
int stateValue = currentState.getValue();
int eventValue = event.getValue();
this.currentState = transitionTable[stateValue][eventValue];
this.score = actionTable[stateValue][eventValue];
}
public int getScore(){
return this.score;
}
public State getCurrentState(){
return this.currentState;
}
}
状态机实现方式三:状态模式
状态模式通过将事件触发的状态转移和动作执行,拆分到不同的状态类中,来避免分支判断逻辑。我们还是结合代码来理解这句话。
public interface IMario{
//所有状态类的接口
State getName();
//以下是定义的事件
void obtainMushRoom();
void obtainCape();
void obtainFireFlower();
void meetMonster();
}
public class SmallMario implements IMario{
private MarioStateMachine stateMachine;
public SmallMario(MarioStateMachine stateMachine){
this.stateMachine = stateMachine;
}
@Override
public State getName(){
return State.SMALL;
}
@Override
public void obtainMushRoom(){
stateMachine.setCurrentState(new SuperMario(stateMachine));
stateMachine.setScore(stateMachine.getScore() + 100);
}
// 其他方法省略
}
// 其他状态省略
public class SuperMario implements IMario{
...
}
public class MarioStateMachine{
private int score;
private IMario currentState;
// 不再使用枚举来表示状态
public MarioStateMachine(){
this.score = 0;
this.currentState = new SmallMario(this);
}
public void obtainMushRoom(){
this.currentState.obtainMushRoom();
}
public void obtainCape(){
this.currentState.obtainCape();
}
public void obtainFireFlower(){
this.currentState.obtainFireFlower();
}
public void meetMonster(){
this.currentState.meetMonster();
}
public intgetScore(){
return this.score;
}
public State getCurrentState(){
return this.currentState.getName();
}
public void setScore(int score){
this.score = score;
}
public void setCurrentState(IMario currentState){
this.currentState = currentState;
}
}