产品需求、系统架构设计经验篇
- 需求设计
- 思维导图
- UML 建模
- 原型
- 规范
- 什么样的需求该忽略
- 1.拍拍脑袋得来的想法,往往是没用的
- 2.用户反馈的信息,不应该直接纳入需求
- 3.扭改用户习惯的需求,一律不考虑
- 什么样的需求该重视
- 1.从运维系统中根据数据结果分析得出的结论
- 2.重视有洞见者的每一句话
- 产品设计
- 核心思想原则
- 安全 > **_并发性能_** > 用户体验(UE) > 用户界面(UI)
- 最简化可实行产品(MVP)原则
- 用户体验设计经验心得
- 体验重心不在于整体感觉,而在于细节处理
- 消费降级 ≠ 体验降级
- 系统架构设计
- 核心思想原则
- 分治法
- 高内聚,低耦合
- 前后端分离
- 项目实践
- 第一步:定位用户
- 第二步:系统功能设计
- 示例
- 第三步:设计数据库表结构
- 第四步:搭建系统框架
- 第五步:迭代
需求设计
思维导图
工具:
- Mindjet MindManager
UML 建模
流程图、时序图、用例图等,为基本技能。
工具:
- Microsoft Visio (Win)
- OmniGraffle (Mac)
原型
工具:
- Axure (必备)
- Pencil
- Balsamiq Mockups
- Sketch
规范
设计内容上的优劣,需要细看、深思才能知道。但规范上的问题,第一眼,就能发现。
所以输出的图表、文档都要规范。这是最基本要求。
以流程图为例:
- 必须有开始、结束,有且只有一个开始
- 箭头必须画在流程线的尖部
- 只有判断有两个分支流向,其余均为一个
等等其他细节也须注意。
需求收集与整理,可以多画画思维导图,因为部分需求之间是存在关联关系的,要将需求的关系、层级理顺。
什么样的需求该忽略
没有大量数据证明切实符合用户实际需要的。
1.拍拍脑袋得来的想法,往往是没用的
硬币皆有两面,要用批判的眼光去审视产品经理的点子。
当下这个阶段,人人都是产品经理,各种野路子如雨后春笋,导致好的产品经理凤毛麟角。
当产品经理拍拍脑袋提出了一个想法,该做的事情是,让他先去做一个详细的市场调研,给出报告和可行性分析。
举一个我见过的例子:
很早之前我们团队接到一个任务,设计一款新的网关产品。产品经理的想法是将受众用户群体定位在青年人。这样就跟小米——“为发烧而生”不谋而合,直面迎来了一个还算比较强大的竞争对手。
当时我提出了一个针对老龄化的设想,主题是傻瓜化、真智能,让中老年人都能轻松上手的产品。直到 2016 年,才出了“爱国者聚路由”这样稍微有点神似的产品。
2.用户反馈的信息,不应该直接纳入需求
根据二八原则,将 80%精力放在 20%最有价值产出的事情上。
用户的需求是需求,但不一定是大众需求。所以如果是一个只有三五十活跃用户的反馈组里,得到的反馈信息仅能作为参考。
举个例子:
假设有这样一个问题:智能门锁通过手机解锁是否需要输入密码。在用户群里,有一些用户反馈说手机 App 上开锁还要打密码很麻烦,不如去掉这一步的密码校验,得到了一批人的支持。
但这样的需求不可取。实际的需求依然需要大量的数据去支撑。一方面,方便和安全,都需要考虑。另一方面,如果大量的用户反馈觉得这样比较麻烦,最佳实践应该是,保留 App 上的密码解锁功能,但可以设置开启或关闭,默认开启,由用户去控制,为了方便可以将其关闭,但由于这种用户自发行为导致的安全隐患,就得交由用户自行承担。
3.扭改用户习惯的需求,一律不考虑
用户行为引导应该是个缓慢而循序渐进的过程。在做技术架构的时候可以稍微激进一点,采用一些新架构新技术去尝试,能提高系统性能;但是在做产品架构的时候,不可冒进。
举例说明:
原有用户账号体系中,不支持手机号注册、登录。在添加这项新功能后,应该是引导用户绑定手机,允许原有方式登录,并增加新的方式登录。尊重原有用户使用用户名的习惯,逐步培养绑定手机号的安全行为,但不能强制用户将登录习惯也改为用手机号进行登录。
因为假设我的用户名为 wzl
或者 willin
都会比手机号(11 位)输入更方便,所以这样的引导并不能帮助用户得到什么益处。不可取。
什么样的需求该重视
1.从运维系统中根据数据结果分析得出的结论
完善运维系统,采集更多需要的信息。根据信息分析得出的可靠结论,才是最重要的需求点。
这里就不举例展开了,一方面数据都是比较私密的,另外一方面,数据所展示出来的问题都是比较明显的。
2.重视有洞见者的每一句话
什么样的人输出什么样的创意。没有偏见,客观陈述。狗嘴里吐不出象牙,所以不要指望肤浅的人给出多么好的意见。而能给出好创意的人,能够源源不断地输出好的创意。
设计,主要来自于思想和经验。
思想这个东西,虽然有后天弥补的空间,但基本都是与生俱来的,可视为先天优势。而经验,则需要知识和实践相结合,可视为后天富足。只有两者都满足,才能成为一个好的设计者。很苛刻,但这是事实。
产品设计
核心思想原则
安全 > 并发性能 > 用户体验(UE) > 用户界面(UI)
这里强调一下并发性能,重于用户体验。原因很简单,因为并发性能直接导致了对服务器硬件环境的要求,所以可视为并发性能即归于成本。没有项目、产品可以不计成本去完善用户体验。
最简化可实行产品(MVP)原则
专注一个突破点。不盲目搞大。
冰冻三尺非一日之寒,一口吃不成胖子。所有庞大的系统,都是由一个个小的子系统逐步演化而来。
明确受众用户,明确核心功能,快速迭代。
用户体验设计经验心得
体验重心不在于整体感觉,而在于细节处理
显示密码按钮逻辑颠倒,像这种问题不仔细看可能都无法察觉。
弹窗中包含右上角关闭按钮,中间的取消按钮,以及屏幕点击空白处的自动关闭,共计 3 处关闭,“取消”按钮完全没有必要留下。
消费降级 ≠ 体验降级
- 交互中避免增加不必要的操作,简化复杂操作;
- 界面显示中,避免无关联的堆砌,数据直观减少用户思考。
以此处图表为反例教材,该图表反应的应该是项目实施进度。其中,中间着重显示的 70% 可能为已完成任务的比例,移动上每个具体项目显示的为个数(不显示比例)。虽然看似内容丰富,但实则没有任何帮助统计的意义。我既不知道完成了多少个任务,也不知道有空再看看的比例是多少。
系统架构设计
核心思想原则
分治法
即分而治之。
将庞大的计算、存储压力向下级分摊。又可以看做是去中心化的一种实践方式。
数据中心只承担一些核心数据的存储工作;每个服务器都可以存储部分非通用的数据,承担部分的计算及负载压力。下级路由、智能终端设备、智能移动设备等,都可以分摊服务器的压力。
高内聚,低耦合
耦合性与内聚性是模块独立性的两个定性标准,将软件系统划分模块时,尽量做到高内聚低耦合,提高模块的独立性,为设计高质量的软件结构奠定基础。
**对外低耦合,对内**高内聚
有个例子很容易明白:
一个程序有 50 个函数,这个程序执行得非常好;然而一旦你修改其中一个函数,其他 49 个函数都需要做修改,这就是高耦合的后果。一旦你理解了它,你编写概要设计的时候设计类或者模块自然会考虑到“高内聚,低耦合”。
- 耦合、内聚的评估标准是**强度**,耦合越弱越好,内聚越强越好;
- 所谓**过度**指的是由于错误理解导致的效果相反的设计;
- 耦合指的模块之间的关系,最弱的耦合设计是通过一个主控模块来协调 n 个模块之间的运作。还是举一个我举过的例子:客户要求在界面上增加一个字段,你的项目要修改几个地方呢?如果你只要修改项目文档,那么你的开发构架就是最低强度的耦合,而这种设计 成熟的开发团队都已经做到了,他们使用开发工具通过项目模型驱动数据库和各层次的代码,而不是直接修改那些代码;
- 内聚指的是模块内部的功能,最强的内聚就是功能单一到不能拆分,也就是原子化;
- 所以**强内聚和弱耦合是相辅相成的,一个良好的设计是由若干个强内聚模块以弱耦合的方式组装起来的。**
前后端分离
参考资料:
- https://segmentfault.com/a/1190000002978095
- http://2014.jsconf.cn/slides/herman-taobaoweb/index.html
注意点: 前后端分离不单指 Web 的前后端,也包括客户端(前)和服务器(后)的分离。
项目实践
一个开放平台的设计大概思路。
第一步:定位用户
开发者,分企业开发者和个人开发者。
第二步:系统功能设计
心中先有个梗概,列出列表。
最核心的功能模块:
- 提供开放接口
- 提供开放文档
- 提供 API 文档
- 提供 SDK
- SDK 下载,来源各个组,如嵌入式、移动开发、服务器端,提供各种语言的 SDK 版本
- 除了 SDK 下载还需要提供 SDK 使用说明,整合进文档中
其他功能模块:
- 用户中心
- 开发者认证
- 产品管理
然后可以搭配脑图、流程图、时序图、用例图等建模工具,设计核心业务模块的流程。
示例
思维导图(脑图):
系统结构图:
用例图:
时序图:
流程图:
第三步:设计数据库表结构
建库建表非常关键。主要原则为,减少冗余数据、避免表字段过多、提高查询性能。
最好是以数字 id 为主键,避免使用自增 id(影响数据同步),外键关系不用外键,关键字段设置索引。
首先第一张表,应该是用户表,虽然不是核心业务,但所有核心业务都与用户相关联,也需要注册登录才能进行。
所以先设计用户表。用户表应该至少两张表,一张是用户基本信息表,只存用户名、密码等或最常用字段,如登录信息;另一张是认证信息,当然也可以分别为企业开发者用户、个人开发者用户建两张表,因为不同的认证方式需要的字段也是不同的。通过用户 id 字段将用户其他信息表数据进行关联。
示例:
上图为 ER 图的一个示例,Windows 下有 PowerDesigner、Visio 等工具,Mac 下用 MySQLWorkbench。
(可以参考已有系统的用户体系设计,但开发者平台与用户产品系统存在一些细节差异。)
另外,前期也可以考虑加入一些日志表,如认证记录表,存一些历史的认证信息。根据项目时间预算,如果前期不考虑,后期也需要考虑加上。
第四步:搭建系统框架
先搭建一个大框架,配置缓存数据库,加入通用类,配置端口,并且能够运行。
(可以参考现有的项目以及项目章节的结构)
搭建测试框架(如果项目进度预算允许)。在项目实现过程中的细节,关注下一章节的内容中讲解。
第五步:迭代
重复上面的过程,完善新功能模块设计,加入到已有系统。
相关文章:

产品需求、系统架构设计经验篇
需求设计思维导图UML 建模原型规范什么样的需求该忽略1.拍拍脑袋得来的想法,往往是没用的2.用户反馈的信息,不应该直接纳入需求3.扭改用户习惯的需求,一律不考虑 什么样的需求该重视1.从运维系统中根据数据结果分析得出的结论2.重视有洞见者的…...
关于websocket的几点注意事项
第一、普通websocket直接集成即可 <!-- Spring Websocket 相关依赖 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency> 第二、web后端两点,创…...

go学习 4、复合数据类型
4、复合数据类型 数组、slice、map和结构体 如何使用结构体来解码和编码到对应JSON格式的数据,并且通过结合使用模板来生成HTML页面 数组和结构体是聚合类型;它们的值由许多元素或成员字段的值组成。数组是由同构的元素组成(每个数组元素都是完全相同的…...
Rust: Vec类型的into_boxed_slice()方法
比如,我们经常看到Vec类型,但取转其裸指针,经常会看到into_boxed_slice()方法,这是为何? use std::{fmt, slice};#[derive(Clone, Copy)] struct RawBuffer {ptr: *mut u8,len: usize, }impl From<Vec<u8>&g…...

Python - Opencv + pyzbar实时摄像头识别二维码
直接上代码: import cv2 from pyzbar.pyzbar import decodecap cv2.VideoCapture(0) # 打开摄像头while True: # 循环读取摄像头帧ret, frame cap.read()# 在循环中,将每一帧作为图像输入,使用pyzbar的decode()函数识别二维码barcodes …...

网络安全(黑客)就业分析指导
一、针对网络安全市场分析 市场需求量高;则是发展相对成熟入门比较容易。所需要的技术水平国家政策环境 对于国家与企业的地位愈发重要,没有网络安全就没有国家安全 更有为国效力的正义黑客—红客联盟 可见其重视程度。 需要掌握的知识点偏多 外围打点…...

MySQL 主从复制的认识 2023.07.23
一、理解MySQL主从复制原理 1、概念:主从复制是用来建立一个和 主数据库完全一样的数据库环境称为从数据库;主数据库一般是准实时的业务数据库。 2、作用:灾备、数据分布、负载平衡、读写分离、提高并发能力 3、原理图 4、具体步骤 (1) M…...

elasticsearch查询操作(API方式)
说明:elasticsearch查询操作除了使用DSL语句的方式(参考:http://t.csdn.cn/k7IGL),也可以使用API的方式。 准备 使用前需先导入依赖 <!--RestHighLevelClient依赖--><dependency><groupId>org.ela…...

Java版企业工程项目管理系统源码+java版本+项目模块功能清单+spring cloud +spring boot
工程项目各模块及其功能点清单 一、系统管理 1、数据字典:实现对数据字典标签的增删改查操作 2、编码管理:实现对系统编码的增删改查操作 3、用户管理:管理和查看用户角色 4、菜单管理:实现对系统菜单的增删改查操…...

理解Android中不同的Context
作者:两日的blog Context是什么,有什么用 在Android开发中,Context是一个抽象类,它是Android应用程序环境的一部分。它提供了访问应用程序资源和执行各种操作的接口。可以说,Context是Android应用程序与系统环境进行交…...

linux判断端口是否占用(好用)
netstat 一般的话使用 netstat -tunlp | grep xxx参数作用-t指明显示TCP端口-u指明显示UDP端口-l仅显示监听套接字(所谓套接字就是使应用程序能够读写与收发通讯协议(protocol)与资料的程序)-p显示进程标识符和程序名称,每一个套接字/端口都属于一个程序。-n不进行…...

springboot 自定义注解 ,实现接口限流(计数器限流)【强行喂饭版】
思路:通过AOP拦截注解标记的方法,在Redis中维护一个计数器来记录接口访问的频率, 并根据限流策略来判断是否允许继续处理请求。 另一篇:springboot 自定义注解 ,aop切面Around; 为接口实现日志插入【强行喂…...

istio安装部署总结
istio安装部署总结 大纲 istio基础概念版本选择安装istio核心主件卸载istiokiali安装 istio基础概念 https://istio.io/latest/zh/docs/ 中文文档 istio是一个服务治理平台,治理服务间的访问,(例如流量控制,安全策略…...
Linux操作系统~必考面试题⑨
1、rpm 命令 Linux rpm 命令用于管理套件。 rpm(redhat package manager) 原本是 Red Hat Linux 发行版专门用来管理Linux 各项套件的程序,由于它遵循 GPL 规则且功能强大方便,因而广受欢迎。逐渐受到其他发行版的采用。 RPM 套件管理方式的出现&…...

国标GB28181协议视频平台EasyCVR修改录像计划等待时间较长的原因排查与解决
音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、H.265自动转码H.264、平台级联等。为了便于用户二次开发、调用与集成&…...

线性代数(主题篇):第三章:向量组 、第四章:方程组
文章目录 第3章 n维向量1.概念(1)n维单位列向量 2.向量、向量组的的线性关系(线性相关性)(1)线性表示 :AXβ(2)线性相关、线性无关: AX0①线性相关②线性无关③线性相关性7大定理 3.极大线性无关组、等价向量组、向量组的秩1.极大线性无关组2.等价向量组…...

大数据课程C4——ZooKeeper结构运行机制
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Zookeeper的特点和节点信息; ⚪ 掌握Zookeeper的完全分布式安装 ⚪ 掌握Zookeeper的选举机制、ZAB协议、AVRO; 一、Zookeeper-简介 1. 特点…...
解决伪类元素‘after‘或者‘before‘遮挡父元素,导致鼠标移入或点击等事件不生效的问题
第一种调整css的index值 如果对显示没有影响的话,可以这么做 第二种设置css属性:pointer-event:none 原理是: 对一个元素设置 pointer-events: none,能让浏览器在处理鼠标操作时,忽视掉这个元素的存在&a…...

电动汽车市场的减速,正在让小鹏汽车付出代价
来源:猛兽财经 作者:猛兽财经 总结: (1)由于价格压力上升、竞争加剧和需求减弱,小鹏汽车的交付量出现了明显下滑,6月份的交付量已经同比下降了43%。 (2)小鹏汽车对2023年…...
Yarn上Streaming流自动调节资源设计
Streaming流自动调节资源 自动资源调节简单来说就是根据数据的输入速率和数据的消费速率来判断是否应该调节资源。如果输入速率大于消费速率,并且在输入速率还在攀升,则将该Job停止并调高Job的资源等级然后重启。如果消费速率大于输入速率,并…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...

【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...