互联网人35岁送外卖?Dirty Flag Pattern 竟“助纣为虐”!

104 阅读2分钟

今天这个设计模式名字有点意思——脏标记模式( Dirty Flag Pattern )

**01**
**目的**

避免不必要的耗时的重复计算。

**02**
**例子代码**

福报厂实现 P1—P7全员小于35岁, 菊花厂清理 35 岁以上员工......裁员、优化、末位淘汰、不得超过 35 岁等, 各种真真假假的新闻让我们这种互联网人如坐针毡, 危机感满满😨

像我,刚满18 岁就要担心 35 岁的日子了。貌似每个到了 35 岁的互联网人都要转行做快递小哥了(咱这么年迈也不知道能不能应聘得上😢)。

比如,这天公司的老板叫你每天给他统计一下公司的平均年龄, 来作为优 ( cai ) 化 ( yuan ) 的依据, 我们目前只有一个组织结构树和一个根据员工工号查询年龄的接口, 所以我们的代码可能会这么写:

先定义一个根据员工 ID 查询员工年龄的接口:

public class EmployeeWebService {        public static Integer        queryEmployeeAge(String userId) {                return Integer.valueOf(userId);    }}

定义一个树节点来存储员工结构:

@Datapublic class TreeNode<T> {        private T value;        private List<TreeNode<T>>        children = new ArrayList<>();        public TreeNode(T value) {                this.value = value;    }}

计算员工的平均年龄:

public static Integer queryEmployeeAvgAge    (TreeNode<String> employeeUserTree) {    Integer totalAge = 0;    Integer employeeCount = 0;        if (employeeUserTree == null) {        System.out.println("公司倒闭了");                return 0;    }    Queue<TreeNode> queue = new LinkedList<>();    queue.offer(employeeUserTree);        while (!queue.isEmpty()) {        TreeNode<String> node = queue.poll();        totalAge += EmployeeWebService.            queryEmployeeAge(node.getValue());        employeeCount++;                for (TreeNode<String> child :                        node.getChildren()) {            queue.offer(child);        }    }            return (totalAge / employeeCount);}
**03**
**脏标记模式**

因为是个树层结构, 遍历很耗时, 每个员工还发生了一次 RPC 调用来查询年龄, 但是如果每天都需要计算, 如果这个公司的人员变动不大, 一天内没有人入职和离职, 可以使用前一天的数据, 这个就是使用脏标记模式。

我们先来定义二个变量, 实际应用中可能存储在数据库, 文件或者缓存中:

public class Constant {        public static Boolean        IS_EMPLOYEE_CHANGED = false;        public static Integer        LASTDAY_EMPLOYEE_AVG_AGE = 0;}

比如定义了一个员工入职离职的接口:

public static void changeEmploy(String userId) {    Constant.IS_EMPLOYEE_CHANGED = true;}

这些改动之后我们的代码:

public static Integer queryEmployeeAvgAge(TreeNode<String> employeeUserTree){            if(!Constant.IS_EMPLOYEE_CHANGED) {                return Constant.LASTDAY_EMPLOYEE_AVG_AGE;    }    //一样的计算年龄的代码    int age = totalAge / employeeCount;    Constant.LASTDAY_EMPLOYEE_AVG_AGE = age;        return age;}

类图👇:

**04**
**脏标记模式课后作业**

1. 找出例子程序中的风险点代码

2. 找出生产场景下可使用本模式的例子

3. 使用模板方法模式实现脏标记模式

微信: