高级程序员必会的程序设计原则 —— 普适性原则

2024-01-13 22:59

本文主要是介绍高级程序员必会的程序设计原则 —— 普适性原则,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

当我们开始准备创造一个伟大的项目时,势必会考虑到未来的扩展性,希望能够成为一个通用的解决方案来解决一类问题。从定制到通用,从特殊到一般的转变需要先从抽象层面去寻找不同项目的共性并提炼它们。

简记

一个模块在解决相同或类似需求时,它不应只局限于或受制于上层模块,应当可以很容易的被其他上层模块或其他项目引用。

如何让一个模块普适化

让程序普适化可以与具体实现解耦

图1、让程序普适化可以与具体实现解耦

比如我们在编写一个文本编辑器时,需要考虑打开一个文本文件,并自动判断它是gb2312编码还是utf-8编码,这段程序可能一开始会耦合在我们的业务代码中,入参也许是TextBox(文本框)、EditorContext(上下文)、OpenFileDialog(打开文件对话框)。这便要求了自动推断编码的这段程序只能放在当前项目里,当我们需要复用该模块时,要么下个项目也用同样的入参、构造其上层模块,要么就只能把入参改为String或者byte[],然后用上层对象的getText()或readAllBytes()之类的方法来耦合我们改造好的模块。

既然我们在做第二个项目的时候总是要改这个模块,为什么不在一开始写的时候就让这个模块只依赖编程语言自带的对象呢?

都说“众口难调”,我们在这里调的就是各个模块的“众口”。

有些时候我们可以通过定义恰当的参数列表来完成普适性。而有些时候我们可以通过依赖某个公共类、增加回调函数、添加生命周期钩子的方式来协调不同项目对相同模块的要求。

为了能够让模块更加普适,我们不一定非要让模块更加复杂,也许反而我们可以让它更简单一些,比如依赖接口开发而不是具体实现、像大多数JSON框架一样引入泛型机制,因此普适性和复杂度某种程度上并不具备相关性。

功能上,如果A模块比B模块判断的场景更多、功能更丰富,那么A模块便会比B模块更通用。如果一个模块是可配置的,那么配置式模块的普适性一定会大于约定式模块。

关于究竟是约定大于配置还是配置大于约定,在业内有过很激烈的讨论,但至今没有结论。这是因为二者都是为了实现普适性,但站的角度不同而已。约定大于配置会假定各方都是如此,没有必要显式声明,从而实现各种项目普适化的敏捷。配置大于约定会假定各方的情况都不一样,需要明确配置项,从而实现各种项目普适化的需求。

毕竟“小孩子才会做选择,成年人全都要”。如果既要普适化的敏捷又要完成普适化的需求,则一个很好的案例可以学习Spring框架,它用多套各自平行又能相互融合的解决方案解决了这一问题。我们可以深入地配置(比如XML、properties、yml或者写Class)、也可以只需遵守约定(比如注解)。

为了能够实现普适性,我们可以采用以下几种方法:1、使用配置文件,让模块可以通过配置来适应不同环境。2、使用上下文或参数化对象来适配不同需求。3、添加枚举或常量,并在恰当的地方让用户可以自行选择模块的行为。4、进行适当抽象或采用面向接口的方式开发。

但也要注意的是,普适性原则关注的是通用模块、平台模块,而非业务领域模块,如果我们非要在业务上做普适性,根据复杂度守恒原则,我们没有办法让得到普适性的模块更加纯粹,这便会导致平台内聚效应,底层平台的功能愈发强大,而我们在实现业务的层面没有得到任何的提升,只是增加了复杂性,但现实中由于架构师经验丰富,便容易因为恐惧而徒增了大量的普适性适配,因此好的架构应当是桶状结构,而非金字塔结构。它带来的另一个问题便是如果模块通用度极强,可以完成相当非常复杂的实现,但我们经常显而易见的简单功能,它却很难完成,我们不得不显式的排除各种干扰因素,使之符合一个明确的预期。
不合理的金字塔架构
图2、正金字塔型架构等于大炮打蚊子,倒金字塔型架构等于产品皆仅供演示

总结

当一名程序员开始考虑如何让手头的项目进行普适化改造时,他不知不觉中便开始进入了架构设计领域。一个好的软件架构其实是一种高度普适化的产品,它可以用来解决一类问题或称为跨越各行各业的通用解决方案。但当项目还未成型时过早的去普适化项目,会成为拖累项目进展甚至导致项目失败的一个重要原因。所以时机应当选择在项目结束以后,花费不少于项目研发的时间去做普适化,一个公司的技术积累其实就是用普适化了多少模块和产品来衡量的。但由于有些单位和企业做项目比较浮躁,因此就会呈现出做一个项目扔一个项目的现象,项目结束了便不再投入资源去凝练它,不仅白白浪费了研发人员的工作成果,更是浪费了社会资源。而我们作为研发人员唯一能做到的就是,如果接手了前人的项目,先不要着急全盘否定它,而是试图去增强和优化它,只有做到足够长时间的沉淀,项目才会成为产品,产品才会成为技术。

这篇关于高级程序员必会的程序设计原则 —— 普适性原则的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/603093

相关文章

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

JVM内存调优原则及几种JVM内存调优方法

JVM内存调优原则及几种JVM内存调优方法 1、堆大小设置。 2、回收器选择。   1、在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提供的内存查看工具,比如JConsole和Java VisualVM。   2、对JVM内存的系统级的调优主要的目的是减少

Java基础回顾系列-第七天-高级编程之IO

Java基础回顾系列-第七天-高级编程之IO 文件操作字节流与字符流OutputStream字节输出流FileOutputStream InputStream字节输入流FileInputStream Writer字符输出流FileWriter Reader字符输入流字节流与字符流的区别转换流InputStreamReaderOutputStreamWriter 文件复制 字符编码内存操作流(

Java基础回顾系列-第五天-高级编程之API类库

Java基础回顾系列-第五天-高级编程之API类库 Java基础类库StringBufferStringBuilderStringCharSequence接口AutoCloseable接口RuntimeSystemCleaner对象克隆 数字操作类Math数学计算类Random随机数生成类BigInteger/BigDecimal大数字操作类 日期操作类DateSimpleDateForma

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

C语言程序设计(选择结构程序设计)

一、关系运算符和关系表达式 1.1关系运算符及其优先次序 ①<(小于) ②<=(小于或等于) ③>(大于) ④>=(大于或等于 ) ⑤==(等于) ⑥!=(不等于) 说明: 前4个优先级相同,后2个优先级相同,关系运算符的优先级低于算术运算符,关系运算符的优先级高于赋值运算符 1.2关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式,逻辑表达式,赋值表达式,字符

Mysql高级篇(中)——索引介绍

Mysql高级篇(中)——索引介绍 一、索引本质二、索引优缺点三、索引分类(1)按数据结构分类(2)按功能分类(3) 按存储引擎分类(4) 按存储方式分类(5) 按使用方式分类 四、 索引基本语法(1)创建索引(2)查看索引(3)删除索引(4)ALTER 关键字创建/删除索引 五、适合创建索引的情况思考题 六、不适合创建索引的情况 一、索引本质 索引本质 是 一种数据结构,它用

LabVIEW程序员是怎样成长为大佬

成为一名LabVIEW编程领域的“大佬”需要时间、实践、学习和解决复杂问题的经验。尽管LabVIEW作为一种图形化编程语言在初期可能相对容易上手,但要真正成为精通者,需要在多个层面上深入理解。以下是LabVIEW程序员如何逐步成长为“大佬”的路径: 1. 打好基础 LabVIEW的大佬们通常在初期会打下非常坚实的基础,理解LabVIEW编程的核心概念,包括: 数据流编程模型:Lab

linux高级学习10

24.9.7学习目录 一.线程1.线程API 一.线程 线程与进程的关系: 线程是轻量级进程,也有PCB,只是各自不同,创建线程使用的底层函数和进程一样,都是clone进程可以蜕变成线程线程是最小的执行单位,进程是最小的分配资源单位 1.线程API (1)查看线程号 #include <pthread.h>pthread_t pthread_self(); (2)

智能工厂程序设计 之1 智能工厂都本俱的方面(Facet,Aspect和Respect)即智能依赖的基底Substrate 之1

Q1、昨天分别给出了三个智能工厂的 “面face”(里面inter-face,外面outer-face和表面surface) 以及每个“面face” 各自使用的“方”(StringProcessor,CaseFilter和ModeAdapter)  。今天我们将继续说说三个智能工厂的“方面” 。在展开之前先看一下三个单词:面向facing,取向oriented,朝向toword。理解这三个词 和