当前位置: 首页 > news >正文

从公共业务提取来看架构演进——功能设置篇

1.引言

上一篇文章我们以帐号权限的提取为例,介绍了当架构跟不上业务发展时及时调整架构的一种思路。这篇文章我们以功能设置为例,进一步讨论公共业务提取这个话题。

功能设置在本文中是指产品开放给企业和用户的一些功能设置项,以视频会议产品为例示意如下:

上面示意的只是一小部分,实际场景中长期需求迭代下来的设置项很多,并且不同产品中的设置项也有所不同,但形式基本一致。

就功能设置的理解达成一致后,接下来我们进入正文,讨论下这块业务在产品多元化的过程中出现的一些问题。

2. 问题

最开始,当只有一个产品时,功能设置可能是这样:

  • 产品有自己的管理中心,负责管理产品下的相关设置项;
  • 具体的设置项存放在产品自己的系统中;
  • 客户端访问产品系统来操作功能设置项;

这时候挺清晰的,并没有什么明显的问题。

随着产品多元化的发展,企业又上线了一些其它产品系统,系统模型演变如下:

  • 每个产品维护一个功能设置模块,并存储自己产品范围内的设置数据;
  • 每个产品开发一套管理中心,来管理自己产品范围内的功能设置项;
  • 客户端访问用户的设置项,需要跨越多个产品系统,才能拼凑出一份完整的数据;
    <抽取前的业务架构模型>

各个产品分别做自己的功能设置,这样带来的问题是:

  • 各产品研发团队在功能设置上做的工作是相似又重复的;
  • 不同产品间功能设置数据隔裂,访问和修改数据都平添了多次网络IO,同时也给维护带来了很多不便;
  • 数据分散在各个产品中,管理中心也只能跟着做多套,给管理中心的统一带来障碍;

那如何解决呢?

3. 优化思路

我们从功能设置的业务模型、管理中心、产品研发思路几个角度来谈谈如何演进。

3.1 业务模型演进

同前文一样,我们一样可以用公共业务提取的思路来优化局部架构,思路描述如下 :

  • 所有产品的设置数据都提取到一个服务,暂且称为统一权限配置服务
  • 设置项的增删改查维护工作只做一遍,不再区分产品;
  • 客户端直接访问统一权限配置服务,一次IO就能访问和操作用户所有设置数据;
    在这里插入图片描述

逻辑和数据统一后,能方便业务需求的后续扩展,例如:

  • 企业级设置和用户级设置需要做的合并工作;
  • 产品要强制开关某些功能的需求;
  • 设置项要受帐号权限控制的需求;
  • 功能试用要联动设置项的需求;
  • ……

这些需求是不区分产品的,都可以分别抽象成一套逻辑或配置,并且各个产品包括客户端其实都不用关心,这样基本就解决了功能设置的数据隔裂和重复开发问题。

3.2 管理中心演进

之前帐号权限和功能配置都割裂在不同的产品系统中,所以管理中心只能对接不同的产品系统来实现管理,也间接导致每个产品都做了一套自己的管理中心。

当我们把功能设置和前文中的帐号权限提取并统一后,可以做进一步的思考:多个产品的管理中心有没有可能合并成一套?

可以分析下管理中心的业务范围,大概就是:

  • 管理用户帐号;
  • 管理功能配置;
  • 管理各种业务功能数据,像会议、直播、会议室、白名单之类的;
  • 管理各种使用统计数据,像会议统计、观众参会统计之类;

这些业务有跨产品通用的,也有各个产品中独有的,并且每个产品多多少少有一些自己的特性。如果要合并就要从设计层面下一些功夫,比如能按模块和功能特性为各个产品作配置。

如果能按模块来设计,那管理中心基本就是把各个业务的数据管理组合到一起,类似下图所示:
<管理中心系统模型图>

管理员进入时可能要允许选择产品,并在不同产品形态下呈现不同的业务模块,例如:

  • 云会议管理中心,可能呈现的是会议、会议室、会议统计;
  • 云直播管理中心,可能呈现的是直播、白名单、观众统计;
  • 各个产品都有的是帐号权限和产品功能设置,但不同产品呈现的配置项可能有所不同;

而这些功能模块的差异,就要区分产品做不同的可见范围配置来实现,也就是上图中比较基础的模块权限配置

管理中心的统一,主要工作在于前端和产品交互层面的统一,这里只是讨论了一种思路,仅供参考。

3.3 产品开发模式演进

最近在回顾公司做过的产品,有IM类的,有任务类的,有文档类的,有视频类的,有呼叫类的等等,总结下来失败的居多,成功的则偏少。所以这里想讨论的问题是:公司投入大量资源和时间来研发一款产品,如果这款产品没有成功,那么公司能从这款产品的研发过程中获得什么?

这是最近一直在思考的问题,做产品不应该是孤注一掷,一旦失败,就团队解散,产品下线,投入打水漂。不论产品成败,企业都应该要从产品的研发过程中获得一些东西,比如:

  1. 相关业务领域的技术研究和文档积累;
  2. 独立可复用的业务模块和组件;
  3. 这个产品研发过程中,走错了哪些方向,做错了哪些事情,能获得什么教训;

可能第一点大家都会做,第三点偏经验类,那第二点呢?

上面讨论的管理中心演进方向,应该是能带来一些启发和思考的,就是产品不应该是一座座孤岛,而应该是业务的组合体,就像下面图示一样。
<功能组合快速迭代一个产品的模型图>

如果我们把每个产品的开发都当做独立的业务模块来做,那不论产品结局如何,我们都能沉淀出一些可以复用的功能模块和业务组件。这样在下一次产品的开发时,就有可能通过复用或扩展来大大降低二次投入的成本,甚至基于积累的业务组件快速组合出一个新的产品。

小结

本文通过对功能设置的业务提取,讨论了一种局部架构的系统演进思路。与前文的帐号权限篇有相似之处(例如功能重复的提取),也有不同之处(如数据割裂问题的讨论),算是同类话题的深入和补充,并进一步讨论了多个产品的管理中心从项目上统一的可能性。

在本文最后,介绍了一种产研效能提升思路。一款产品的成功和失败我们是无法预言的,但能不能从一款产品的研发过程中有所沉淀和收获,以及能取得多大的收获,却是我们能做的,而且这里说的沉淀与收获基本与产品成败没有关系。

既然产品允许失败,并且失败的可能性还不小,那我们要思考的就不仅仅是怎么把产品做出来,而是如果产品失败我们能从中沉淀出哪些可复用的东西,以便下一个产品能在之前的基础上快速搭起来。

所以失败并不要紧,要紧的是能不能快速爬起来。

延伸阅读

  • 从帐号权限提取来看架构如何演进:https://blog.csdn.net/xiaojia1001/article/details/134147088
  • 一个功能试用模块的抽取案例:https://blog.csdn.net/xiaojia1001/article/details/132959395

相关文章:

从公共业务提取来看架构演进——功能设置篇

1.引言 上一篇文章我们以帐号权限的提取为例&#xff0c;介绍了当架构跟不上业务发展时及时调整架构的一种思路。这篇文章我们以功能设置为例&#xff0c;进一步讨论公共业务提取这个话题。 功能设置在本文中是指产品开放给企业和用户的一些功能设置项&#xff0c;以视频会议…...

Java基础-015-System.java常用类

Java基础-015-System.java常用类 1、标准输入输出2、获取属性3、System.java初始化4、设置标准输出System.out java/lang/System.java 1、标准输入输出 System.in、System.out public class Test {public static void main(String[] args) {String charsetName String.valueOf…...

Flutter笔记:发布一个模块 scale_design - (移动端)设计师尺寸适配工具

Flutter笔记 发布一个模块scale_design设计师尺寸适配工具与常用组件库 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/a…...

torch增加维度操作

使用none作为占位符 在Python中&#xff0c;None 表示空值或占位符。 在masked_pos[:, :, None]这个切片操作中&#xff0c;None 被用作一个占位符&#xff0c;以改变张量的维度。这通常用于将一维张量变为二维张量&#xff0c;或者改变张量的形状。 具体来说&#xff0c;ma…...

软件测试面试题及答案2024

1、你们的缺陷等级如何划分的&#xff1f;☆☆☆☆☆ 我们的缺陷一般分为四个等级&#xff0c;致命级&#xff0c;严重级&#xff0c;一般级和轻微级。致命级指能够导致软件程序无法使用的缺陷&#xff0c;比如宕机&#xff0c;崩溃&#xff0c;手机APP的闪退&#xff0c;数据…...

C现代方法(第18章)笔记——声明

文章目录 第18章 声明18.1 声明的语法18.2 存储类型18.2.1 变量的性质18.2.2 auto存储类型18.2.3 static存储类型18.2.4 extern存储类型18.2.5 register存储类型18.2.6 函数的存储类型18.2.7 小结 18.3 类型限定符18.4 声明符18.4.1 解释复杂声明18.4.2 使用类型定义来简化声明…...

Spring Data Redis + RabbitMQ - 基于 string + hash 实现缓存,计数(高内聚)

目录 一、Spring Data Redis 1.1、缓存功能(分析) 1.2、案例实现 一、Spring Data Redis 1.1、缓存功能(分析) hash 类型存储缓存相比于 string 类型就有更多的更合适的使用场景. 例如,我有以下这样一个 UserInfo 信息 假设这样一个场景就是:万一只想获取其中某一个…...

【四、http】go的http的文件下载

一、日常下载图片到本地 //下载文件func downloadfile(url, filename string) {r, err : http.Get(url)if err ! nil {fmt.Println("err", err.Error())}defer r.Body.Close()f, err : os.Create(filename)if err ! nil {fmt.Println("err", err.Error())…...

Java web(六):FilterListenerAJAX

文章目录 一、Filter1.1 基本介绍1.2 过滤器的执行流程1.3 拦截路径配置1.4 过滤器链1.5 案例 二、Listener三、AJAX3.1 快速入门3.2 Axios异步框架 四、 JSON4.1 JSON基础语法4.2 Fastjson 五、 案例JSONAxiosServlet Java web的三大组件&#xff1a;Servlet、Filter、Listene…...

初识jQuery

文章目录 一、jQuery介绍二、Jquery优势三、jQuery版本四、jQuery对象jQuery的引用js代码与jQuery代码对比标签对象与jQuery对象 五、jQuery查找标签1.基本选择器2.组合选择器3.层次选择器4.属性选择器5.基本筛选器6.表单筛选器 六、筛选器方法七、操作标签1.class操作2.文本操…...

MATLAB算法实战应用案例精讲-【图像处理】计算机视觉(最终篇)

目录 知识储备 线阵相机调试 1.相机型号参数 2.相机软件安装 3.编码器连接方式 4.采集卡说明...

repo执行出现/usr/bin/env: ‘python’: No such file or directory问题

下载 Repo 工具&#xff0c;并确保它可执行&#xff1a; curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repochmod ax ~/bin/repo 执行 repo version报错&#xff1a; $ repo version /usr/bin/env: ‘python’: No such file or directory查看c…...

算法模板之单调栈解密 | 图文详解

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;算法模板、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. ⛳️单调栈讲解1.1 &#x1f514;单调栈的定义1.2 &#x1f514;如何维护一个单…...

187.重复的 DNA 序列

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;187. 重复的DNA序列 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 使用两个哈希表&#xff0c;一个存放已遍历过的长度为 10 的字符串&#xff0c;另一个存放重复的长度为 10 的字符串。顺…...

Sentinel黑白名单授权规则解读

目录 基本介绍 代码实战 架构说明 RequestOriginParser的实现类 网关添加请求头 配置授权规则 基本介绍 授权规则可以对请求方来源做判断和控制。 很多时候&#xff0c;我们需要根据调用来源来判断该次请求是否允许放行&#xff0c;这时候可以使用 Sentinel 的来源…...

Spring底层原理学习笔记--第二讲--(BeanFactory实现与ApplicaitonContext实现)

BeanFactory实现 package com.lucifer.itheima.a02;import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.fac…...

云原生|kubernetes |kubelet服务加入系统守护进程supervisor(centos7系统下演示通过)

前言&#xff1a; kubelet 是 Kubernetes 集群中的一个重要组件&#xff0c;运行在每个节点上&#xff0c;负责管理该节点上的容器和Pod。它与控制平面&#xff08;如 API Server 和 kube-controller-manager&#xff09;通信&#xff0c;确保节点上的容器与期望的状态保持一致…...

onnx 模型加载部署运行方式

1.通过文件路径的onnx模型加载方式: 在onnxruntime下面的主要函数:session Ort::Session(env, w_modelPath.c_str(), sessionOptions); 这里的文件路径是宽字节的&#xff0c;通过onnx文件路径直接加载模型。 在opencv下使用dnn加载onnx模型的主要函数: std::string model…...

第68讲:MySQL触发器的核心概念以及常见的触发类型应用案例

文章目录 1.触发器的概念2.触发器操作的语法结构3.各类触发器的典型应用案例3.1.需求描述以及实现思路3.2.创建日志表3.3.INSERT类型的触发器3.4.UPDATE类型的触发器3.5.DELETE类型的触发器 1.触发器的概念 触发器是与表中数据相关的数据库对象&#xff0c;当表中的数据产生in…...

VS Code 开发 Spring Boot 类型的项目

在VS Code中开发Spring Boot的项目&#xff0c; 可以导入如下的扩展&#xff1a; Spring Boot ToolsSpring InitializrSpring Boot Dashboard 比较建议的方式是安装Spring Boot Extension Pack&#xff0c; 这里面就包含了上面的扩展。 安装方式就是在扩展查找 “Spring Boot…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...