今晚好冷啊,回去的路上,我突然想到一件关于系统拆分的事情。举的例子很极端,仅供参考,不一定有实际的意义
我感觉拆分系统,和拆分代码,本质上是一样的。小到一个方法,大到几个系统,都是一个从输入到输出的序列
Level 1:
public void doSomething(){
System.out.println("111");
System.out.println("222");
System.out.println("333");
}
这种情况是最简单的,所有的代码都在一个方法里,没有任何拆分
Level2:
public void m2(){
System.out.println("222");
}
public void doSomething(){
System.out.println("111");
m2();
System.out.println("333");
}
效果和Level 1是一样的,只是中间多了一次方法的调用,实际上是内存指针偏移。但比起将所有代码写在一个方法里,这里已经做了最简单的拆分
Level3:
public class Class2{
public static void m2(){
System.out.println("222");
}
}
public class Class1{
public void doSomething(){
System.out.println("111");
Class2.m2();
System.out.println("333");
}
}
还是很简单,但是比Level2又多了一层,将部分代码拆分到了另一个类里
直到目前为止,无论拆分与否,所有的代码都在同一个进程里,所以都是
本地调用(仅需要偏移内存指针即可),过程类似下图:
这里要补充一点,就JAVA平台来说,凡是要调用的代码在同一个JVM里,且classloader可见,都可以认为是本地调用。不管它是打包在.jar文件里,还是直接存放在classpath里,也不管其源码是否来自一个地方
Level4:
现在,输出222这段逻辑,被拆分到了另外一个系统里
所以,只有通过
远程调用(RPC),才能111->222->333了,但是本质并没有改变,还是从输入到输出的一串序列,只是本地调用,和远程调用的区别
事实上,这种区别对调用者来说,常常是透明的
public void doSomething(){
System.out.println("111");
Proxy proxy = getProxy();// Proxy是一个interface
proxy.print222ForMe();
System.out.println("333");
}
对这个调用者来说,它并不需要知道proxy的实现来自哪里。这是一次本地调用还是一次远程调用,对调用者来说是透明的。只有在上面的部署图里,才能看出区别
通过这个例子,我想说明的是:核心的问题是逻辑,而不是怎么拆分系统。逻辑不会因为放在一个方法里,或者放在10个不同的系统里,就发生变化。最终的结果都是一样的。同时,当需要思考“为什么要拆分系统”的时候,某种程度上和“为什么要拆分代码”是类似的
实际的设计中,拆分系统一般都是必要的,我认为至少有以下3个方面的好处:
1、复用服务
前面举的例子过于简单了,可能有点无法说明问题。但是想象中间那行
System.out.println("222");
是一段非常重要的代码,其他很多逻辑都需要它。那么如果它是混杂在一个方法中,应用的其他部分就无法重复地调用它了(复用);而把它抽取出来之后,就可以实现复用
系统拆分也是一样,比如我画的这两张示意图,是用QQ截图功能截成JPG的。为了截这2张图,我只好把QQ给打开了。如果QQ截图被抽取为单独的模块,我就可以单独打开截图功能了;如果腾讯其他的应用也需要实现截图,就可以复用这部分功能了
当然,系统之所以被称为“系统”,而不是“应用”、“模块”、“方法”,是因为它比较大(我认为除此之外,完全是一回事,有输入、输出、逻辑的都是系统)
所以,作为系统,复用的往往不是截图这么小的功能,一般希望能够复用一个完整的服务。比如独立出“用户权限管理系统”,就可以在多个业务系统中,复用“用户校验和鉴权”的服务了。我想这就类似几年前比较流行的一个大词SAAS
2、性能考虑
一个大的系统,往往其中的某个部分,承担了很大的并发压力,或者逻辑运算特别复杂,因此成为系统的性能瓶颈
这时就可以考虑将这部分独立出来,从而实现单独部署,再通过负载均衡等手段,来解决性能的问题
3、逻辑清晰
根据业务上、流程上的不同环节,将整个系统拆分为不同的子系统,在逻辑上会更加清晰,从而更容易在架构上说清楚,或者进一步做优化
暂时想到这3点,欢迎补充
PS:至于源码工程的管理,完全是另一回事了。一个工程可以构建出N个系统;N个工程也可以构建出一个系统。是架构的2个不同角度的视图
- 大小: 12 KB
- 大小: 18 KB
分享到:
相关推荐
【电商信息化:浅谈OMS订单管理系统】 在电商领域,订单管理系统的角色至关重要,它连接着前端销售与后端运营的桥梁。OMS(Order Management System)订单管理系统就是这样一个核心工具,它负责处理从订单创建到...
Oracle数据库系统性能优化是数据库管理中的重要环节,它涉及到数据库设计、硬件配置、操作系统设置、数据库参数调整以及应用程序优化等多个方面。在设计阶段进行性能优化是最经济且效果最佳的策略,因为一旦系统上线...
微服务化是IT行业中SOA概念的一种具体实践,特别是在云服务领域,它通过将大型应用拆分为一系列小型、独立的服务,提高了系统的灵活性、可扩展性和可维护性。微服务架构与传统的总线服务架构相比,具有更高的自治性...
2. 模块化建设:将系统拆分为多个模块,分步实施,便于管理和调试。 3. 培训与技术支持:对工作人员进行系统操作和维护培训,提供持续的技术支持。 4. 规划与评估:制定详细实施计划,并定期评估项目进展和效果。 ...
本压缩包文件“浅谈技工学校的智能楼宇自动化模块化学习.pdf”可能包含以下核心知识点: 1. 智能楼宇概述:智能楼宇是指运用现代通信技术和自动化技术,实现楼宇设备的智能化管理和控制,提高楼宇的安全性、舒适性...
《ESB项目需求分析和方案设计浅谈》 企业服务总线(Enterprise Service Bus,简称ESB)是企业级集成的关键技术,它提供了一种灵活、可扩展的方式来连接和协调分布在不同系统中的服务。本文主要探讨ESB项目的需求...
本文《浅谈面向信息时代的机械产品现代设计理论与方法研究进展》由韩艳霞撰写,探讨了在信息时代背景下,机械产品现代设计理论与方法的研究现状及其发展趋势。作者强调,现代化机械设计的核心在于动态性、科学性和...
计算机无法直接理解连续的汉字串所代表的语义,因此需要通过分词将文本拆分为可理解的词汇单位。其次,中文分词是中文信息处理的基础性工作。随着互联网的发展,信息量剧增,如何高效地处理和检索信息成为关键。分词...
其中包括应用服务和数据服务的分离、缓存的使用、应用服务器集群的建设、数据库读写分离、反向代理和CDN的利用、分布式文件系统和数据库系统的采用、NoSQL和搜索引擎的引入、业务拆分、微服务架构的形成等多个关键...
- 微服务架构:将大型应用程序拆分为小型、独立的服务,每个服务都可以独立部署和扩展,降低了复杂性,提高了可扩展性。 - 容器化:使用容器技术可以快速部署和运行应用程序,同时确保环境一致性,方便在不同服务器...
总结来说,微服务架构是一种以业务为导向、技术为支撑的软件开发模式,通过将大型系统拆分为一系列小而专注的微服务和微应用,实现了开发效率、可维护性和业务敏捷性的提升。随着互联网技术和需求的不断演进,微服务...
本文将浅谈OpenCV的基础知识,包括常见的图片格式、图片的本质以及如何使用OpenCV进行基本操作。 首先,我们来了解一下常见的图片格式。JPEG(jpg)是一种广泛使用的有损压缩格式,它能在较小的磁盘空间内保持较高...
逻辑分解将全局查询拆分成子查询,评估转换将这些子查询转换为适合各站点的查询,优化组合则考虑如何有效地组合这些局部查询结果,以实现全局查询的高效处理。 在数据本地化阶段,常用的关系代数等价变换算法被用来...
3. 为了减少外部属性数据或行数据的开支,可以通过拆分实体(表)来分离频繁访问和不常访问的数据,如按属性或行进行拆分,有助于并行处理和减少I/O操作。 【物理数据库实现】选择正确的物理实现策略对查询性能至关...
在并行编程中,任务分解模式是至关重要的,它涉及到如何将一个大型任务拆分为可并行执行的子任务。以下是关于任务分解模式的详细解释: 1. 设计线程 传统编程模式通常遵循单线程、顺序执行的逻辑,而并行编程则...
【单一职责原则】 单一职责原则(Single ...它们帮助我们构建出松耦合、高内聚的系统,降低代码复杂性,提高软件的可扩展性和可维护性。在实际开发过程中,理解和应用这些原则有助于创建出更加健壮、灵活的应用程序。
- 为了克服单体应用的局限性,开发者开始将其拆分成多个垂直的服务或应用程序。 - 这种方式提高了各个组件的可扩展性和可维护性,但也引入了数据一致性和业务逻辑重复等问题。 3. **分布式SOA架构**: - 通过...
在`spider_v2.js`中,我们看到了这种改进,通过拆分`spider()`函数,使其职责更加明确,同时减少了回调的嵌套。 3. **使用流(Stream)**:Node.js的Stream API是处理异步数据的强大工具。它允许数据以流的形式传递...
模块化设计法可以将复杂系统拆分成独立模块,便于管理和优化;面向对象设计法强调实体和模块的分解,增强设计的灵活性和可操作性;数据结构设计则通过图形化方式,简化设计过程,提高问题解决效率。 同时,注重软件...
Linux Shell编程中的函数是将复杂任务拆分成小模块的有效方式,可以提高代码的复用性和可读性。本文将深入探讨Shell函数的基本概念、定义、参数传递以及如何使用它们。 一、函数概述 Shell函数是一组命令的集合,...