代码改变世界

徒手撸设计模式-观察者模式

2022-06-19 12:12  hikoukay  阅读(470)  评论(0编辑  收藏  举报

概念

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

参考连接: https://www.runoob.com/design-pattern/observer-pattern.html

代码案例

新增观察者抽象类,引入通知类变量

/**
 * 观察者抽象类
 */
public abstract class Observer {
    protected Notification notification;
    public abstract String update();
}

 

新增通知类,引入观察者集合,监听状态变更,变更时通知各个观察者子类

/**
 * 观察者通知类
 */
@Data
@Slf4j
public class Notification {
    private List<Observer> observers= new ArrayList<Observer>();
    private int state;
    private String type;

    public int getState() {
        return state;
    }
    /**
     * 设置变更状态并通知各个观察者子类
     * @param state
     */
    public List<String> setState(int state) {
        this.state = state;
        return notifyAllObservers();
    }

    public String getType() {
        return type;
    }
    /**
     *设置变更类型
     * @return
     */
    public void setType(String type) {
        this.type = type;
    }

    /**
     * 绑定观察者-将具体实现类放到观察者管控范围内
     * @param observer
     */
    public void attach(Observer observer){
        observers.add(observer);
    }

    /**
     * 更新时通知各个观察者
     */
    public List<String> notifyAllObservers(){
        List<String> list = new ArrayList<>();
        for (Observer observer : observers) {
            list.add( observer.update());
        }
        return list;
    }
}

 

新增枚举值转换工具类

@Slf4j
public class TranslateUtil {
    public static String translateEnum(Notification notification, String buPaint) {
        int state = notification.getState();
        String type = notification.getType();
        if (StuEnum.PRODUCT.getKey().equals(type)) {
            type=StuEnum.PRODUCT.getValue();
        }else if (StuEnum.SELL.getKey().equals(type)) {
            type=StuEnum.SELL.getValue();
        }else if (StuEnum.PAINT.getKey().equals(type)) {
            type=StuEnum.PAINT.getValue();
        }
        String stateStr="";
        if (Integer.parseInt(StuEnum.START.getKey())==state) {
            stateStr=StuEnum.START.getValue();
        }else if (Integer.parseInt(StuEnum.STOP.getKey())==state) {
            stateStr=StuEnum.STOP.getValue();
        }else if (Integer.parseInt(StuEnum.WAIT.getKey())==state) {
            stateStr=StuEnum.WAIT.getValue();
        }
        String retStr = type + "===============" + stateStr+"==============="+buPaint+"收到";
        log.info(retStr);
        return retStr;
    }
}

 

完成三个观察者子类实现

PaintingObserver--喷漆子类

/**
 * 喷漆观察者子类
 */
@Slf4j
public class PaintingObserver extends Observer {
    /**
     * 将当前子类绑定到通知类中
     * @param notification
     */
    public PaintingObserver(Notification notification) {
        this.notification=notification;
        notification.attach(this);
    }

    @Override
    public String update() {
        log.info("------------------处理喷漆逻辑-------------------");
        return TranslateUtil.translateEnum(notification,StFlag.BU_PAINT);
    }
}

 

ProductObserver--生产子类

/**
 * 生产观察者子类
 */
@Slf4j
public class ProductObserver extends Observer {
    /**
     * 将当前子类绑定到通知类中
     * @param notification
     */
    public ProductObserver(Notification notification) {
        this.notification=notification;
        notification.attach(this);
    }

    @Override
    public String update() {
        log.info("------------------处理生产逻辑-------------------");
        return TranslateUtil.translateEnum(notification, StFlag.BU_PRODUCT);
    }
}

 

SellObserver--销售子类

/**
 * 销售观察者子类
 */
@Slf4j
public class SellObserver extends Observer {
    /**
     * 将当前子类绑定到通知类中
     * @param notification
     */
    public SellObserver(Notification notification) {
        this.notification=notification;
        notification.attach(this);
    }

    @Override
    public String update() {
        log.info("------------------处理销售逻辑-------------------");
        return TranslateUtil.translateEnum(notification, StFlag.BU_SELL);
    }
}

 

公共类

public final class StFlag {
    public StFlag() {
    }
    /**
     * 生产部门
     */
    public static final String BU_PRODUCT="生产部门";
    /**
     * 销售部门
     */
    public static final String BU_SELL="销售部门";
    /**
     * 喷漆部门
     */
    public static final String BU_PAINT="喷漆部门";
}

 

/**
 * 枚举类
 */
public enum StuEnum {
    PRODUCT("PRODUCT","生产工序"),
    SELL("SELL","销售工序"),
    PAINT("PAINT","喷漆工序"),
    START("1","开始"),
    STOP("2","停止"),
    WAIT("3","等一等");

    private final String key;
    private final String value;
    StuEnum(String key, String value) {
        this.key=key;
        this.value=value;
    }

    /**
     * 获取key
     * @return
     */
    public String getKey(){
        return key;
    }

    /**
     * 获取value
     * @return
     */
    public String getValue(){
        return value;
    }

}

 

测试主类

/**
 * 设计模式控制器
 */
@RestController
@RequestMapping("/designPattern")
@Slf4j
public class DesignController {
    @GetMapping("/observer")
    public ResponseModel observer(int state,String type) {
        Notification notification= new Notification();
        new ProductObserver(notification);
        new PaintingObserver(notification);
        new SellObserver(notification);
        notification.setType(type);
        return new ResponseModel("观察者模式完成", 200, notification.setState(state));
    }
}

 

测试案例

 

 

 

 

type:PRODUCT-生产工序,SELL-销售工序,PAINT-喷漆工序
state:1-开始,2-停止,3-等一等

state=3&type=PRODUCT
2022-06-19 11:40:24.123 INFO  ------------------处理生产逻辑------------------- 【http-nio-8081-exec-9】【ProductObserver:252022-06-19 11:40:24.124 INFO  生产工序===============等一等===============生产部门收到 【http-nio-8081-exec-9】【TranslateUtil:272022-06-19 11:40:24.124 INFO  ------------------处理喷漆逻辑------------------- 【http-nio-8081-exec-9】【PaintingObserver:252022-06-19 11:40:24.124 INFO  生产工序===============等一等===============喷漆部门收到 【http-nio-8081-exec-9】【TranslateUtil:272022-06-19 11:40:24.125 INFO  ------------------处理销售逻辑------------------- 【http-nio-8081-exec-9】【SellObserver:252022-06-19 11:40:24.125 INFO  生产工序===============等一等===============销售部门收到 【http-nio-8081-exec-9】【TranslateUtil:27】

state=1&type=PRODUCT
2022-06-19 11:40:29.811 INFO  ------------------处理生产逻辑------------------- 【http-nio-8081-exec-10】【ProductObserver:252022-06-19 11:40:29.812 INFO  生产工序===============开始===============生产部门收到 【http-nio-8081-exec-10】【TranslateUtil:272022-06-19 11:40:29.812 INFO  ------------------处理喷漆逻辑------------------- 【http-nio-8081-exec-10】【PaintingObserver:252022-06-19 11:40:29.812 INFO  生产工序===============开始===============喷漆部门收到 【http-nio-8081-exec-10】【TranslateUtil:272022-06-19 11:40:29.812 INFO  ------------------处理销售逻辑------------------- 【http-nio-8081-exec-10】【SellObserver:252022-06-19 11:40:29.813 INFO  生产工序===============开始===============销售部门收到 【http-nio-8081-exec-10】【TranslateUtil:27】

state=2&type=PRODUCT
2022-06-19 11:40:34.842 INFO  ------------------处理生产逻辑------------------- 【http-nio-8081-exec-1】【ProductObserver:252022-06-19 11:40:34.842 INFO  生产工序===============停止===============生产部门收到 【http-nio-8081-exec-1】【TranslateUtil:272022-06-19 11:40:34.842 INFO  ------------------处理喷漆逻辑------------------- 【http-nio-8081-exec-1】【PaintingObserver:252022-06-19 11:40:34.842 INFO  生产工序===============停止===============喷漆部门收到 【http-nio-8081-exec-1】【TranslateUtil:272022-06-19 11:40:34.843 INFO  ------------------处理销售逻辑------------------- 【http-nio-8081-exec-1】【SellObserver:252022-06-19 11:40:34.843 INFO  生产工序===============停止===============销售部门收到 【http-nio-8081-exec-1】【TranslateUtil:27】

state=3&type=PAINT
2022-06-19 11:40:41.011 INFO  ------------------处理生产逻辑------------------- 【http-nio-8081-exec-2】【ProductObserver:252022-06-19 11:40:41.012 INFO  喷漆工序===============等一等===============生产部门收到 【http-nio-8081-exec-2】【TranslateUtil:272022-06-19 11:40:41.014 INFO  ------------------处理喷漆逻辑------------------- 【http-nio-8081-exec-2】【PaintingObserver:252022-06-19 11:40:41.015 INFO  喷漆工序===============等一等===============喷漆部门收到 【http-nio-8081-exec-2】【TranslateUtil:272022-06-19 11:40:41.015 INFO  ------------------处理销售逻辑------------------- 【http-nio-8081-exec-2】【SellObserver:252022-06-19 11:40:41.015 INFO  喷漆工序===============等一等===============销售部门收到 【http-nio-8081-exec-2】【TranslateUtil:27】

state=2&type=PAINT
2022-06-19 11:40:47.334 INFO  ------------------处理生产逻辑------------------- 【http-nio-8081-exec-3】【ProductObserver:252022-06-19 11:40:47.334 INFO  喷漆工序===============停止===============生产部门收到 【http-nio-8081-exec-3】【TranslateUtil:272022-06-19 11:40:47.335 INFO  ------------------处理喷漆逻辑------------------- 【http-nio-8081-exec-3】【PaintingObserver:252022-06-19 11:40:47.335 INFO  喷漆工序===============停止===============喷漆部门收到 【http-nio-8081-exec-3】【TranslateUtil:272022-06-19 11:40:47.335 INFO  ------------------处理销售逻辑------------------- 【http-nio-8081-exec-3】【SellObserver:252022-06-19 11:40:47.335 INFO  喷漆工序===============停止===============销售部门收到 【http-nio-8081-exec-3】【TranslateUtil:27】

state=1&type=PAINT
2022-06-19 11:40:54.004 INFO  ------------------处理生产逻辑------------------- 【http-nio-8081-exec-4】【ProductObserver:252022-06-19 11:40:54.006 INFO  喷漆工序===============开始===============生产部门收到 【http-nio-8081-exec-4】【TranslateUtil:272022-06-19 11:40:54.006 INFO  ------------------处理喷漆逻辑------------------- 【http-nio-8081-exec-4】【PaintingObserver:252022-06-19 11:40:54.007 INFO  喷漆工序===============开始===============喷漆部门收到 【http-nio-8081-exec-4】【TranslateUtil:272022-06-19 11:40:54.007 INFO  ------------------处理销售逻辑------------------- 【http-nio-8081-exec-4】【SellObserver:252022-06-19 11:40:54.007 INFO  喷漆工序===============开始===============销售部门收到 【http-nio-8081-exec-4】【TranslateUtil:27】

state=3&type=SELL
2022-06-19 11:40:57.847 INFO  ------------------处理生产逻辑------------------- 【http-nio-8081-exec-5】【ProductObserver:252022-06-19 11:40:57.847 INFO  销售工序===============等一等===============生产部门收到 【http-nio-8081-exec-5】【TranslateUtil:272022-06-19 11:40:57.847 INFO  ------------------处理喷漆逻辑------------------- 【http-nio-8081-exec-5】【PaintingObserver:252022-06-19 11:40:57.847 INFO  销售工序===============等一等===============喷漆部门收到 【http-nio-8081-exec-5】【TranslateUtil:272022-06-19 11:40:57.850 INFO  ------------------处理销售逻辑------------------- 【http-nio-8081-exec-5】【SellObserver:252022-06-19 11:40:57.850 INFO  销售工序===============等一等===============销售部门收到 【http-nio-8081-exec-5】【TranslateUtil:27】

state=2&type=SELL
2022-06-19 11:41:02.659 INFO  ------------------处理生产逻辑------------------- 【http-nio-8081-exec-6】【ProductObserver:252022-06-19 11:41:02.659 INFO  销售工序===============停止===============生产部门收到 【http-nio-8081-exec-6】【TranslateUtil:272022-06-19 11:41:02.660 INFO  ------------------处理喷漆逻辑------------------- 【http-nio-8081-exec-6】【PaintingObserver:252022-06-19 11:41:02.662 INFO  销售工序===============停止===============喷漆部门收到 【http-nio-8081-exec-6】【TranslateUtil:272022-06-19 11:41:02.663 INFO  ------------------处理销售逻辑------------------- 【http-nio-8081-exec-6】【SellObserver:252022-06-19 11:41:02.663 INFO  销售工序===============停止===============销售部门收到 【http-nio-8081-exec-6】【TranslateUtil:27】

state=1&type=SELL
2022-06-19 11:41:08.188 INFO  ------------------处理生产逻辑------------------- 【http-nio-8081-exec-7】【ProductObserver:252022-06-19 11:41:08.188 INFO  销售工序===============开始===============生产部门收到 【http-nio-8081-exec-7】【TranslateUtil:272022-06-19 11:41:08.189 INFO  ------------------处理喷漆逻辑------------------- 【http-nio-8081-exec-7】【PaintingObserver:252022-06-19 11:41:08.190 INFO  销售工序===============开始===============喷漆部门收到 【http-nio-8081-exec-7】【TranslateUtil:272022-06-19 11:41:08.192 INFO  ------------------处理销售逻辑------------------- 【http-nio-8081-exec-7】【SellObserver:252022-06-19 11:41:08.192 INFO  销售工序===============开始===============销售部门收到 【http-nio-8081-exec-7】【TranslateUtil:27】