策略模式+工厂模式优化if-elseif结构

本文介绍了一种优化ZooKeeper事件监听的方法,通过引入策略模式和工厂模式,改进了原始监听逻辑中的if-else结构,使代码更清晰且易于维护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以监听zookeeper watcher监听事件处理逻辑为例,可以看出process监听方法中,不同事件触发处理逻辑中有很多if-elseif结构

public class ZkDemo implements Watcher {

    private static final String connectString = "localhost:2181";
    private static Stat stat = new Stat();
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    private static ZooKeeper zooKeeper;
    private static String path = "/node1";

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        zooKeeper = new ZooKeeper(connectString, 5000, new ZkDemo());
        countDownLatch.await();
        // 创建节点
        String ret  = zooKeeper.create(path, "11".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        // true继续监听
        zooKeeper.getData(ret, true, stat);
        // 修改节点
        Stat stat1 = zooKeeper.setData(ret, "222".getBytes(), 0);
        Stat stat2 = zooKeeper.setData(ret, "222".getBytes(), 1);
        // 删除节点
        zooKeeper.delete(path, 2);

    }


    @Override
    public void process(WatchedEvent watchedEvent) {
        // 监听连接状态,开放闭锁
        if (watchedEvent.getState().equals(Event.KeeperState.SyncConnected)) {
            countDownLatch.countDown();
            if (watchedEvent.getType().equals(Event.EventType.None) && null == watchedEvent.getPath()) {
                System.out.println("watcher监听事件的状态:" + watchedEvent.getState() + "-->watcher监听事件的类型:" + watchedEvent.getType());
            } else if (watchedEvent.getType().equals(Event.EventType.NodeDataChanged)) {
                try {
                    System.out.println("节点数据修改:" + watchedEvent.getPath() + "修改后的数据为" + zooKeeper.getData(watchedEvent.getPath(), true, stat) );
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else if (watchedEvent.getType().equals(Event.EventType.NodeDeleted)) {
                System.out.println("节点被删除:" + watchedEvent.getPath());
            }
        }
    }

    
}

优化思路,使用策略模式+工厂模式

策略模式:定义解决事件的接口EventStrategy,接口方法为handle(...),参数是所有事件处理时需要调用什么参数就传什么参数,可以看到上面的用到了

watchedEvent, zooKeeper, stat三个参数,所以事件策略类接口应该定义如下:

public interface EventStrategy {

    /**
     * 事件监听处理策略
     */
    void handle(WatchedEvent watchedEvent, ZooKeeper zooKeeper, Stat stat) throws Exception;

}

策略实现类,也就是针对每个事件的处理策略,直接针对每种if条件的处理逻辑复制到hadle方法即可

None事件策略类(连接后没有事件发生时)

public class NoneEventStrategy implements EventStrategy {

    @Override
    public void handle(WatchedEvent watchedEvent, ZooKeeper zooKeeper, Stat stat) throws Exception {
        System.out.println("watcher监听事件的状态:" + watchedEvent.getState() + "-->watcher监听事件的类型:" + watchedEvent.getType());
    }

}

 Modify事件策略类(节点数据修改时)

public class ModifyEventStrategy implements EventStrategy {
    @Override
    public void handle(WatchedEvent watchedEvent, ZooKeeper zooKeeper, Stat stat) throws Exception {
        System.out.println("节点数据修改:" + watchedEvent.getPath() + "修改后的数据为:" + zooKeeper.getData(watchedEvent.getPath(), true, stat) );
    }
}

Delete事件策略类(节点删除时)

public class DeleteEventStrategy implements EventStrategy {
    @Override
    public void handle(WatchedEvent watchedEvent, ZooKeeper zooKeeper, Stat stat) throws Exception {
        System.out.println("节点被删除:" + watchedEvent.getPath());
    }
}

工厂模式:根据不同的事件获取相应的事件策略

工厂类需要根据WatchedEvent.getType()来匹配具体的事件策略处理类。首先工厂类肯定需要先将所有的事件策略类对象放到工厂内部,这里使用Map实现。

public class EventStrategyFactory {
    public static final Map<Watcher.Event.EventType, EventStrategy> map = new HashMap<>();

    // 初始化工厂
    static {
        map.put(Watcher.Event.EventType.None, new NoneEventStrategy());
        map.put(Watcher.Event.EventType.NodeDataChanged, new ModifyEventStrategy());
        map.put(Watcher.Event.EventType.NodeDeleted, new DeleteEventStrategy());
    }

    // 从工厂类中的map中获取具体的事件策略
    public static EventStrategy getEventStrategy(WatchedEvent event) {
        return map.get(event.getType());
    }

}

使用策略模式+工厂模式后的版本,感觉清爽多了

核心是根据工厂类获取对应的事件策略类,事件策略类又由接口统一定义,不同实现类实现不同的处理策略(handle方法)

public class ZkDemo implements Watcher {

    private static final String connectString = "61.144.207.233:2191";
    private static Stat stat = new Stat();
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    private static ZooKeeper zooKeeper;
    private static String path = "/node1";

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        zooKeeper = new ZooKeeper(connectString, 5000, new ZkDemo());
        countDownLatch.await();
        // 创建节点
        String ret  = zooKeeper.create(path, "11".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        // true继续监听
        zooKeeper.getData(ret, true, stat);
        // 修改节点
        Stat stat1 = zooKeeper.setData(ret, "222".getBytes(), 0);
        Stat stat2 = zooKeeper.setData(ret, "222".getBytes(), 1);
        // 删除节点
        zooKeeper.delete(path, 2);

    }

    @Override
    public void process(WatchedEvent watchedEvent) {
        // 监听连接状态,开放闭锁
        if (watchedEvent.getState().equals(Event.KeeperState.SyncConnected)) {
            try {
                countDownLatch.countDown();
                EventStrategy eventStrategy = EventStrategyFactory.getEventStrategy(watchedEvent);
                eventStrategy.handle(watchedEvent, zooKeeper, stat);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值