分布式异步任务处理组件(九)

最近完成了网络通信模块的一些基本代码实现,这里记录一些关于类和接口设计的问题和思考;另外进度可能会受阻,之前不知道猴年马月投的简历现在开始邀约面试了,包括今天在内的三天都有一场面试--主要是今天中午的面试过后两分钟HR就电话说通过了一面,然后约了明天的二面,某网盘的go开发,之前没有怎么接触过go,但是确实蛮有兴趣~题外话;

关于代码实现中的类和接口设计,可能平时业务代码中确实不容易体现复杂性,做一些基本的封装和抽象就足以应对,加上本来具有的业务逻辑也会更容易帮助我们进行设计建模;但是真正设计实现这种框架级的代码的时候就会发现确实很重要,没有良好的设计代码看起来确实会非常糟糕;

因为同时面对很多复杂的对象包括线程交互,要思考如何处理代码之间的解耦和抽象,考虑扩展性,写出优美的代码真的不容易~后续持续会对实现的代码做重构优化,相关的详细思考也会记录下来;这里主要总结一下目前使用的几个设计模式,以及相关后续的一些设计;

说一下目前网络通信模块涉及到的几个设计模式--

每个节点在运行过程中需要向主节点发起投票,举证,心跳等操作,这里节点和主节点并不存在太大的差别--主节点本身在接受任务时进行投票举证等操作,这里考虑使用代理模式,任务调度对象只和主节点代理进行命令交互,不需要区分自己是否为主节点;这样在代码实现上就更容易做抽象化操作;对主节点代理对象的调用使用策略模式--根据自己是否是主节点从而判断调用不同的实现--最基本的区别非主节点在调用主节点代理的时候需要通过网络IO来和主节点进行通信,而主节点在调用主节点代理的时候则不需要,另外由于网络通信原因主节点在运行过程中可能出现重新选举,这里使用策略模式就可以很好的来处理重选举情况下的代码实现,上层任务调度对象不需要关心节点是否是主节点,只关心自己的调度逻辑就行;

另外对主节点代理对象的创建使用工厂模式--传入节点状态参数创建本地主节点代理或者远程主节点的代理对象;

这里区分一下工厂模式和策略模式的实现区别,概念上理解工厂模式会在节点不同状态下创建不同的代理对象来提供调用,而策略模式也是会根据节点身份的不同提供不同的行为;其实单纯从概念上理解确实差别不大,但是实际上在实现中这两种设计模式适用的其实是全完不同的场景,首先工厂模式描述的是代理对象的创建,影响到的是工厂方法,也就是我们如何去设计和实现Builder.build方法,而策略模式描述的是对代理对象的调用层,比如调用代理对象的send方法来向主节点发送命令,我们在设计使用代理对象的代码中不需要考虑该节点是否为主节点,我们只需要调用森send方法就好,其他的策略模式会使用实际不同的send实现;

代码说明如下:

public void doSometingWithLeader(){
        if(i am leader)
           leader=leaderProxyBuilder.build("i am leader");
        else if(i am not leader)
           leader=leaderProxyBuilder.build("i am not leader");
        //do someting before
        leader.send("hello leader");
        //do someting after
    }

send方法体现策略模式,或者说整个doSometingWithLeader()方法使用策略模式,在这个方法中我们不要需要关心leader的send方法具体是怎么实现的;只需要关注自己本身的逻辑就行,而工厂模式则是根据不同的条件创建不同的代理对象,在leader=leaderProxyBuilder.build()方法中创建我们实际需要的对象; 

另外一个策略模式的实现场景就是编解码器的实现,编解码器分开为两个线程处理,但是任务调度的逻辑是相同的,每个taskHadler对象维护自己的任务队列,执行任务处理方法,而具体的编码器调度器或者解码器调度器来实现具体的任务策略;

另外就是经典的缓存池技术--享元模式,这里主要对Buffer对象进行缓存,每次对web的IO操作都通过ByteBuffer对象进行读写,这里为了减少ByteBuffer对象的频繁创建和回收,每次对读写完的Buffer重置放回空队列缓存池中,只有缓存池中的对象不够时才会创建新的ByteBuffer对象。

状态模式--整个节点的运行都是通过状态驱动的,类似一个大的状态机对象;这里后续在节点工作流程中会说;

你可能感兴趣的:(分布式)