java系统设计实现部分记录

        做JAVA工作差不多五年,对系统实现积累了一些原则或经验,记录下来供以后翻阅,后续遇到、想到再修改补充。有不对的地方欢迎交流。

        作为程序员而言,开发的优秀的系统(单体或分布式),应具有但不限于:代码干净、易读且无冗余,系统健壮,实现完善,可维护性强等。为实现以上目标,以下原则或底线为工作、书中或与人交流所得。切勿随手写代码。

目录

目录

        1.功能可扩展

        2.每一步操作都要知道自己在做什么,产生什么后果

        3.边界/概念清晰

        4.代码格式和实现规范

        5.设计模式

        6.内存和数据量

        7.事情一步一步做

        8.是什么,为什么,怎么做

        9.知识面拓展


        1.功能可扩展

         可扩展,即多想一步,考虑过多易钻牛角尖,多想一步即可。需求告诉你status为1、2,实现时要考虑3、4、5怎么办。如果随手写代码就面临后续大幅的修改。

        曾做过一个需求,短信平台上游对接N个客户,下游对接N个短信通道,客户提交的短信下发到短信通道,通道返回的原生短信状状态码返回给客户。某个客户提出需求要求按他们给定的状态码返回并给了状态码列表。同事看到这个需求提出实现方式:通道返回状态码即转成这个客户的状态码拼接字段写库,然后返还状态给这个用户。但如果其他用户也有这个需求再给一套状态码怎么办,我给出的实现方案是:先做平台统一错误码,对不同通道错误码做归一处理。然后在用户侧封装一个可扩展的协议层,在协议层里面做转换,用户账号配置是否自定义协议和协议号。那么每个客户都可以自定义协议只要添加配置即可。实现了一个完善的功能,后续完全不需要修改代码。

      同理,现在的前后端分离项目,不止架构分离,数据也要分离,前端最好不要定义数据,写死数据。如状态等,后端转成字符串前端显示即可,菜单等等都如此。那么状态菜单数据等的扩展增删后台修改数据库记录即可,对前端无感,避免前后端都修改代码的不必要麻烦。即使做了分布式横向扩展的负载均衡,服务注册中心的下线上线依旧有延迟,对于请求频繁的系统丢失数据是不被允许的,产品的更新对客户无感是最好的。

        当然事情不是绝对的,设计模式的6大原则实现过程中也会被污染,但原则放进去原来污染10个现在只要污染三个。心里有没有这条线还是不一样的。

        2.每一步操作都要知道自己在做什么,产生什么后果

        服务器、数据库、git、每行代码等等,敲出来的每一个操作至少都要往下理解一层。因为解决服务器问题百度到解决方案,复制过来直接执行结果引出更严重的问题,这是血的教训。

        比如所有人知道数据库的DELETE、UPDATE会产生什么后果,那么在不确定结果是否符合的时候先执行BEGIN,再执行SQL,验证结果正确性再决定执行COMMIT或ROLLBACK。比如Git恢复之前版本的两种方法reset、revert,回退和反做有什么后果,每一步操作都在做什么事情。比如Spring注解的@service和@compent有什么区别,往下一层就知道@Service引入了@Compent注解封装了业务逻辑层,那么在看到混用的时候和自己选择的时候就很清晰了。知道了注解是交给Spring生命周期管理的单例Bean,那么在使用继承和实现时思维更清晰,多重继承和实现更好理解等等。比如jstack还原现场的时候会造成JVM停顿等后果。

        所以建议在操作服务器、数据库、redis、kafka等工具的时候使用原生命令行,知道每一步的原理灵活解决遇到的问题,依赖工具不利于思维的清晰梳理。

        3.边界/概念清晰

        涵盖很多概念。对于系统中涉及的每个主体概念都要理清。引入新的主体那么它是不同于你已有设计的主体概念,还是子分类,还是你已有概念的另一种描述。对数据库设计而言一件事情一个表征,思维混乱下也许会两个字段表达一个事情,那么对于系统的正确运行,理解和维护都造成麻烦。

        同理对于服务、模块、函数、成员变量等等等划清功能边界,明确知道每一行代码应该在什么位置做什么事情,那么就不会写出一个函数做多件事情等冗余混乱难以理解阅读的代码。

        4.代码格式和实现规范

        这方面一定要阅读并理解《阿里巴巴Java开发手册》和《代码整洁之道》。对于代码格式,变量函数的命名规约、数据库的设计、集合处理并发处理、异常等等都有较好的实现和约束,增强可读性和健壮性。阅读开源项目就可以看到别人和自己在这方面的差距。

        5.设计模式

        这方面的书很多,不用刻意追求为了设计模式而设计模式,可能也会让你的代码变得复杂,自己理解并选择。个人理解这是对于实现方式的范式和扩展,前人的思维经验并没有新的技术点,可能自己用到了某种而不自知。

        比如需求是:消息中包含省市、运营商等信息,想按省市、运营商统计某个时间段的成功失败率,写省市Sercive,运营商service实现统计方法,添加进列表,消息循环发送给列表。那这个就实现了观察者模式。只是观察者模式做了Observer和Observable工具类,提供了范式。比如你想按照不同的条件生成不同的实体,那这个就是工厂方法模式,还有一些变种。你把多个子类的公有方法提取到父类,那这个就是模版方法模式。

        了解设计模式对于场景下实现的选择会有好的思路。

        6.内存和数据量

        我理解这是设计和代码实现要考虑的重要两点。

        对于内存,线程的不正常管理、大量对象的异常生成、过多数据加载进内存(数据过多或不确定就要分页分批处理)等都会造成内存溢出等问题。这方面建议阅读《深入理解Java虚拟机:JVM高级特性与最佳实践》《java并发编程的艺术》,了解JVM中内存的存储区域、管理机制和造成内存溢出的情况,及jstack、jmap、jstat等调试工具。

        对于关系型和非关系型数据的选择设计。 了解索引机制和分区分表分片扩展机制等,当然不有些不要过早的做。交出去一个可以长期稳定运行没有后患的产品。数据量的激增会让你实现重构重做甚至数据库重新设计。

        7.事情一步一步做

        建议事情排序一件一件做。同时做多件事思维易混乱,实现不精细也不易调试问题所在。比如对一个功能的增减,随手写就易删一块加一块,思考调试起来并不省事。可以把删做好再做增,每一步做好事情也就好了。

        如果你有16核CPU脑子的天赋,事情堆在一起也能做完美,那尊重你,普通人还是不要这样。

        8.是什么,为什么,怎么做

             问题或需求到手,不要着急做,先看是什么,是bug?是全新的功能?是已实现模型下的一个分支?还是需要实现一个模型包含进这个需求(扩展的问题)?遇到过别人提出一个bug,但这是设计时考虑进的的一个正常现象。领导给一个需求,但这是已经考虑到的配置扩展问题,等等。所以先理清楚是什么的问题。第二个为什么,为什么有这个需求,是不是有另外的需求方式更好的实现这个问题。最后再考虑怎么实现,怎么做。

        9.知识面拓展

        这个没什么发言权,也一直在学。对于不同的框架、不同的组件、不同的消息中间件、不同的数据库、不同的缓存机制、不同的实现概念等等了解异同、拓展思维,对于不同的场景选择合适的技术实现,交出一个有成就感的系统。

        重点重申一下:思维 >= 技术

        

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值