Coder Social home page Coder Social logo

mblog's People

Contributors

luhui avatar

Stargazers

 avatar

Watchers

 avatar  avatar

mblog's Issues

UML-用例图

概念

先看官网怎么说的:

Use case diagrams are usually referred to as behavior diagrams used to describe a set of actions (use cases) that some system or systems (subject) should or can perform in collaboration with one or more external users of the system (actors). Each use case should provide some observable and valuable result to the actors or other stakeholders of the system.

简单来说,用例图是用于描述行为的图,他用于描述一系列角色(actors)与用例(use case)之间的关系。因此,通过用例图,我们能够知道系统中涉及到的角色、以及每个角色都能通过这个系统做什么。
一般我们描述事件,可能会使用 5W1H 的方式来表达,对应来看,用例图便是从 who&what 的维度来表达设计。

使用场景

从概念我们得知,用例图用于描述系统中的角色对应的行为,因此比较适合通过用例图来表达产品需求,确定系统边界。
用例图和用户故事(user story)表达的模式是相似的,作为 xx (actor),我希望通过 xx 方式(use case),以便我可以 xx (用户原始诉求)。
当然,在表达产品需求时,用户故事和用例并不完全是一一对应的关系,我们可能会对用例进行归类,不过这就是需求分析的维度了,不在这篇文章阐述的范围。

用例图元素

元素的具体表达方式,请参考官网,本篇文章重点在于说明每个元素具体的含义

角色(actor)

An actor is behaviored classifier which specifies a role played by an external entity that interacts with the subject (e.g., by exchanging signals and data), a human user of the designed system, some other system or hardware using services of the subject.

角色代表的是直接或间接使用这个系统的用户或系统、设备。在面向用户的产品中,角色可能是人,比如学生,在面向技术的产品中(比如 broker,mq),则角色可能是客户端,业务系统。

在实践的过程中,我碰到一些同学会把具体的人名作为将角色,比如王大胖,这是不正确的。actor 表示的是 role(角色),即一类用户的标识,比如学生、厨师、客户端、系统等等。

角色

用例(use case)

Use cases allow to capture requirements of systems under design or consideration, describe functionality provided by those systems, and determine the requirements the systems pose on their environment.

用例就是角色能够执行的动作,描述了角色能够怎么使用我们提供的系统。他表达的是一个系统的功能,比如用户注册、添加购物车、支付等等。

用例

包含关系(include relationship)

Use case include is a directed relationship between two use cases which is used to show that behavior of the included use case (the addition) is inserted into the behavior of the including (the base) use case.

包含关系,顾名思义,即表达一个用例(基础用例)包含另一个用例(新增用例)的场景。一般是某个用例包含很大的范围,专门抽出子用例来着重表达,又或者是复用用例。

强化表达子用例的例子:
强化说明子用例

复用用例的例子:
复用用例

扩展关系 (extend relationship)

Extend is a directed relationship that specifies how and when the behavior defined in usually supplementary (optional) extending use case can be inserted into the behavior defined in the extended use case.

扩展关系表明的是一个用例(基础用例)执行过程中的可选过程,基础用例本身可以完整的场景,扩展用例作为一个**可选(optional)**�过程插入到基础用例中。比如用户注册的场景,注册本身可以作为一个单独的用例,但是在注册的过程中,用户可以寻求帮助,查看注册指引,那么获取帮助就是一个可选的流程,整个用例场景我们就可以这么表达:
扩展用例

注意,**可选(optional)**是一个很主观的描述,比如丰巢的取件过程,取件是一个基础用例,取件时,如果快递放置的时间长,可能要扫码支付费用,那么支付费用这个用例到底是包含用例还是扩展用例,则取决于产品定义,是 optional 还是 alternative,直观的来看,就是看弹出支付窗口时,能不能跳过,如果能跳过,则是 optional,属于扩展用例,否则属于包含用例

小技巧

神秘的 7

<<金字塔原理>>里提到的说法,大脑的短期记忆无法一次容纳7个以上的记忆项目,当发现需要处理项目超过7个时,应该对其进行归纳,方便记忆。

在用例图上也适用,当一个角色能够进行超过 7 个的用例时,应该对用例进行归纳,利用归纳法、包含关系、扩展关系来优化用例图的表达

用例完整性

我们通常使用用例图来表达需求,在表达之后,应该把用例图与产品经理的用户故事,或者交互原型等等由相关方输出的结果进行比对,确认我们分析的需求是否完整,是否能够覆盖需求。

思考题

通常我们拿到的需求是产品经理的用户故事,或者交互设计的交互稿,我们要如何根据这些具象、零散的需求,整理成易于阅读的用例图呢?

认识 UML

概念

UML 全称为统一建模语言(Unified Modeling Language),主要是用于软件开发领域,对业务进行建模的结果进行图形化表达的规范。

为什么要使用 UML?

主要是为了避免下面的场景:
image

看起来很滑稽,但是实际上就是实际开发过程中的放大版,最终可能在程序里体现的就是代码扩展性差,新需求可能会受旧功能的影响,原有的设计难以支撑新需求的开发。

为什么会造成这样的困难呢?实际上是因为表达的问题。很多人都玩过(或见过)一种游戏,叫传声筒,需要传递的内容到最后一位可能会差之千里,游戏中我们可以直观的感受到,每次内容的传递,可能都会损失一些信息(理解出错或者是遗忘),为了补充这些损失的信息,又会脑补一些自己理解的信息上去,最终导致最后一位理解的内容和实际相差很大。在这个游戏过程中,如果能以文字信息传达,效果必然会大不相同。
在软件领域,单纯是文字很难说明问题,因为软件开发的本质是一种创造性的活动,他通过对需求进行建模,构建出一个抽象的,系统性的结构,因而我们如果尝试用文字去表达,会显得非常复杂难以理解。UML 便是基于此而诞生的,他希望通过图形化的表达,让原本抽象的结构变得具象,方便人们沟通与理解。

UML 定位为一门统一的建模语言,表示其用途是用于软件领域的建模,语言表示其是一种表达方式,和英语、中文平级的一种语言,适用于表达软件领域的建模。

因此学习 UML 本身,并不是为了提高我们的设计能力,而是利于 UML 来表达我们的设计,方便与其他包括工程师、产品经理、交互设计等等岗位的同事进行交流。

常用的 UML 图形

在日常的工作中,根据项目的复杂度,我们可能只会使用部分、甚至是不需要使用到 UML 进行表达,在我的工作经验中,最常用的 UML 包含以下几个:

  1. 用例图
  2. 活动图
  3. 类图
  4. 时序图
  5. 包图
  6. 组件图
  7. 部署图

接下来的系列文章,我会与大家分享最常用的这 7 种图的含义以及其适用的场景。对这几个图的定义,都是使用官网的说明,翻译可能有不准确的地方,请大家以官网为准

思考题

我们通常用 UML 来表达设计,那么我掌握了 UML 这门语言,能够提高我的设计能力吗?

参考资料

UML官网

相关工具

startUML(仅供学习使用)
wps(可商用)

UML-时序图

概念

Sequence diagram is the most common kind of interaction diagram, which focuses on the message interchange between a number of lifelines.

Sequence diagram describes an interaction by focusing on the sequence of messages that are exchanged, along with their corresponding occurrence specifications on the lifelines.

时序图是一种动态图,表明对象(lifelines)之间的消息交换顺序,它关注的是消息交换的方式,消息交换的时机、顺序以及执行的时间。

使用场景

时序图一般配合组件图、类图一起使用,表明对象之间的通讯流程。
我们在 #3 讲到的活动图也是一种动态图,也描述的是流程,但是他们之间关注点会有所区别。活动图粒度比较粗,它只关注 activity 之间是怎么流传的,因此比较适合在需求分析的阶段来表达需求场景。而时序图关注点在于消息交换,转换成代码就是代码调用的流程,因此更适合在程序设计阶段,表达更细节的,更接近程序实现的流程场景。
比如 jQuery 的 ajax 请求,请求时会通过创建一个代理对象,由代理对象来实现 http 请求,这部分用活动图表达就相对困难。
因此虽然活动图与时序图都是表达流程的图,但是由于两种图关注的点有所差别,因而适用于不同的场景。

时序图示例

时序图基本元素

对象(lifeline)

Lifeline is a named element which represents an individual participant in the interaction. While parts and structural features may have multiplicity greater than 1, lifelines represent only one interacting entity.

对象表示一个具体的实例对象,敲重点,时序图只表达其中一个实例对象的交互流程,因此如果系统中有多个实例对象,每个实例对象流程有所区别,那么应该画多个时序图。因此时序图表达的是系统某一时段,对象的交互过程。这个对象不仅是一个 class 的实例,也有可能是一个子系统,分布式集群里的某个节点。

对象示例

系统边界(gate)

A gate is a message end, connection point for relating a message outside of an interaction fragment with a message inside the interaction fragment.

一个时序图并不一定要求从流程的最开始画起,也不一定会涉及到流程的终点,因此在这个流程里,我们不关注的部分称之为系统边界(gate),表明消息从外部对象产生,最终返回给外部对象。

系统边界示例

控制焦点(execution specification,informally called activation)

Execution (full name - execution specification, informally called activation) is interaction fragment which represents a period in the participant's lifetime when it is

executing a unit of behavior or action within the lifeline,
sending a signal to another participant,
waiting for a reply message from another participant.

控制焦点表明该对象执行某些方法的过程,或者是进行其他方法调用、等待消息回复的过程。我们可以简单的理解为调用了该对象的某个方法,该方法终止的标志为执行完相关的过程,完成方法调用,并且收到了相关的消息。

如下面的方法 a,控制焦点从a被调用开始,到 callOtherFunction 返回,并且收到了 waitingSomeMessage消息标记结束

function a() {
    //doSomething()
   event.on('waitingSomeMessage', () => {})
   callOtherFunction()
}

消息(interaction message)

Message is a named element that defines one specific kind of communication between lifelines of an interaction. The message specifies not only the kind of communication, but also the sender and the receiver. Sender and receiver are normally two occurrence specifications (points at the ends of messages).

消息不代表通讯的协议,只是表明了发送者向接收者进行了一次通讯,可能会代表一次 http 请求,也可能代表一个函数调用。
消息分为同步消息异步消息返回消息、创建消息(https://www.uml-diagrams.org/interaction-message.html#create)、删除消息(https://www.uml-diagrams.org/interaction-message.html#delete)等

同步消息

顾名思义,就是消息发送后,等待消息的回复。从代码的角度来说,就是执行了一个函数调用,并且等待函数的返回。

同步消息示例

异步消息

是指发送了消息后不等待返回,立即处理后续的事情。从代码的角度来说,就是开了另一个线程执行函数调用,不等待函数的返回结果

异步消息示例

返回消息

表明消息接受者已经处理完消息,把结果返回给发送者。从代码的角度来说,就是 A 调用了 B,B 返回了结果(无论是通过函数返回或函数回调的方式)

返回消息示例

创建消息

即创建对象,A 给 B 发送了创建消息,从代码的角度来说就是在 A 的方法里,执行了 new B() 的操作

创建消息示例

删除消息

和创建对象相反,A 给 B 发送了删除的消息,从代码的角度来说就是在 A 的方法里,执行了 release B 的操作,在 C++等手动内存管理的场景会比较好举例,等价于释放了对象的内存

删除消息示例

异步信号

即创建一个信号发送给接收端,常用于响应式的设计

引用(Interaction use)

Interaction use is an interaction fragment which allows to use (or call) another interaction. Large and complex sequence diagrams could be simplified with interaction uses. It is also common to reuse some interaction between several other interactions.

引用是表示在现有时序图里嵌入一个子流程,主要是用于简化时序图的表达。因为有些流程相对复杂,如果都画在一起,显得复杂,不好阅读。另一种场景就是复用流程。

引用示例

小结

  1. 时序图是一种动态图,一般配合组件图、类图使用,表达程序设计过程中的业务流程
  2. 时序图与活动图都是表达流程的动态图,但是由于其关注的点不同,因此适用于不同的场景
  3. 时序图主要关注消息的交互顺序和类型,适合在程序设计过程中表达对象的交互流程,活动图关注的是 activity 之间的流转过程,适合表达需求层面的业务场景
  4. 对象(lifeline)是一个具体的实例,因此时序图表达的是系统在一个特定时间范围内几个特定对象之间的交互过程

UML-组件图

概念

Component diagram shows components, provided and required interfaces, ports, and relationships between them. This type of diagrams is used in Component-Based Development (CBD) to describe systems with Service-Oriented Architecture (SOA).

Component-based development is based on assumptions that previously constructed components could be reused and that components could be replaced by some other "equivalent" or "conformant" components, if needed.

The artifacts that implement component are intended to be capable of being deployed and re-deployed independently, for instance to update an existing system.

组件图适用于基于组件的开发模式(Component-Based Development, CBD),它通过组件,及组件的接口、端口来表达组件的构成及其关系。当我们使用 CBD 进行开发时,其实是对行为进行了抽象,一个组件提供了若干的行为,组件图通过接口、端口的方式来表达组件间的连接,很形象的表达出组件是可被替换的概念,一个组件可以被另一个提供了相同接口的组件替换。因此,当我们通过组件进行建模时,能够设计出一个扩展性良好的系统。

使用场景

组件图是用于描述系统的物理、逻辑结构的,他关注组件间的关联(使用什么接口,通过什么端口通讯),强调通过接口来描述组件行为,因此,
对于后端来说,组件图比较适用于 SOA 架构、微服务架构的表达,描述整个系统的结构以及子系统间的通讯方式,或者表达一些基础设施,比如脚手架,消息中间件等等。
对于前端来说,组件图适合在使用类似 react、vue 这样组件化的前端技术框架时,表达对组件的设计,比如一个页面会有个骨架组件,骨架组件包含了导航组件,列表组件等等。

组件图元素

组件图包含的基本元素可以参考下图:

image

组件

A component is a class representing a modular part of a system with encapsulated content and whose manifestation is replaceable within its environment.

A component has its behavior defined in terms of provided interfaces and required interfaces (potentially exposed via ports).

组件图示例

组件 描述的是系统的其中一个组成部分,它是包含了行为描述的,通过提供接口(provided interfaces)与需求接口(required interfaces)来表述接口对外提供的行为以及所需的接口,一般这些接口都通过端口来暴露,比如 http 端口,react的 props 等

提供接口 (provided interfaces)

组件图示例

提供接口表明该组件实现的接口,表示该组件能够提供的行为,即该组件可对外提供的服务。
比如上图的例子中,表明了天气服务组件,提供了天气预报的接口,即说明天气服务组件拥有天气预报的行为(能力)

需求接口(required interfaces)

组件图示例

需求接口表明该组件执行过程中,需要使用到具有某个行为的组件,即声明该组件依赖的行为。
比如上图的例子中,表明了用户服务组件依赖订单服务的接口,映射到具体的需求场景,可能是用户服务里需要通过用户的年度账单,分析并设定用户的年度消费标签。

需求接口(半圈)和提供接口(圆圈)的图设计得很有意思,一般两个组件连接,即一个组件的提供接口连接另一个组件的需求接口,这样表现出来的就是一个半圆半包裹着一个圆圈,很形象的表明类似插座,或者可互相嵌入的接口,所以从图中我们能够很直观的感受到组件之间是通过接口连接的,只要使用相同的接口,组件间可以随意替换。

需求接口与提供接口

端口 (port)

端口 表明组件对外提供接口的交互点,和网络中的端口概念相似,它定义了组件对外的出口。通过端口,我们可以限制组件的外部可见性,其他组件与该组件交流,只能通过对应的端口,因此我们通过端口了解到一个组件能够支撑的功能范围。

端口示例

连接器(connector)

Connector is feature which specifies a link that enables communication between two or more instances playing some roles within a structured classifier. This link may be an instance of an association, or it may represent the possibility of the instances being able to communicate because their identities are known by virtue of being passed in as parameters, held in variables or slots, or because the communicating instances are the same instance.

连接器是表示两个组件之间可以互相通讯的表达方式,而组件之间具体是通过什么方式通讯连接器并没有强调,有可能是组件间通过比如 http 通讯,也有可能共享变量、传参的方式通讯。
在本章节开头的组件图示例中,即包含了 connector,也包含了 dependency,他们之间表达的维度不一样,connector 表示组件可以通讯,通过特定的端口和接口,而 dependency 则表示组件间的关系是依赖关系,表示组件 A 的需求接口,依赖组件 B 的提供接口。在示例中,系统内的组件使用了 connector,即不特别强调组件关系,子系统间使用了 dependency,强调系统间的依赖关系。

连接器与依赖

小结

  1. 组件图的基本元素很少,都是围绕组件以及组件的关系展开。
  2. 核心的元素即组件,用于表达系统的物理或逻辑结构。
  3. 组件通过接口来描述自己对外暴露的行为及依赖,接口包含需求接口(required interfaces)以及提供接口(provided interfaces)。
  4. 端口是组件对外的交互点,我们约定组件间的交互仅能通过端口,因此端口限制了组件的可见性,通过端口我们可以了解到组件能够支撑的功能范围。
  5. 连接器表示的是组件间是通过哪个端口、接口进行通讯的,表明的不是组件关系,而是表明组件间建立通讯的标志。
  6. 一般我们通过组件图来描述系统架构、基础架构、前端组件等。

UML-活动图

概念

Activity diagram is UML behavior diagram which shows flow of control or object flow with emphasis on the sequence and conditions of the flow. The actions coordinated by activity models can be initiated because other actions finish executing, because objects and data become available, or because some events external to the flow occur.

活动图和我们在 #2 谈到的用例图类似,也是描述行为的图,不同在于活动图描述的是活动(activity)的流程。他从 when 和 how 的维度来表达对应的事件。

使用场景

一般活动图会配合用例图一起使用,我们通常使用用例图表达产品需求,确定功能的系统边界,接着通过活动图来表达用例之间的流程。
用例图是需求结构化的表达,能够比较容易的看到系统包含哪些功能,是静态的,单纯从用例图没办法了解用例之间是怎么流通的,因此我们会通过活动图来配合,表达出用例的流程

活动图元素

活动(activity)

Activity is a parameterized behavior represented as coordinated flow of actions.

官网的描述很抽象,我们可以简单的理解为流程中的一个环节,配合用例图来表达产品需求时,activity 即代表用例。最简单的活动图,即是两个 activity 通过箭头,表示出两个 activity 的顺序。

活动示例

起点与终点(Initial Node & Activity Final Node)

活动图必须有起点和终点,因为一个业务流程,必然会包含开始和结束,这样的限制能够很好的辅助我们去识别业务的关键点。

活动图起点

活动图终点

决策与合并(decision node & merge node)

一个简单的活动图,可以由起点、终点、活动三个要素组成,但是仅仅这三个元素,没办法表达出类似下边的复杂场景:
网购时,用户查看物品,可以选择先添加到购物车,后在购物车进行付款,也可以选择直接付款。
因此 UML 引入了决策与合并的模型,用于表达分支流程。

决策与合并

这里有一点需要注意,一个 activity node,当使用 decision node 来实现分支流程时,如果多个分支流程最终都走向同一个流程,需要引入 merge node 来表达,如上图的支付流程。

分叉与加入(fork node & join node)

有了决策与合并,看似能覆盖多数场景了,但是还是有一些场景没办法满足,还是看网购的场景,当用户支付成功后,同时进行微信提醒和短信提醒。已知的图例没办法表达出同时的场景,因此 UML 使用了分叉与加入( fork&join) 的方式来进行表达。分叉(for)表示流程从这里开始并行出多个子流程,加入(join) 表示子流程从这里汇集,所有子流程完成之后,开始进行下一个流程。
分叉与加入

泳道(partitions)

有了决策与合并、分叉与加入,活动图已经基本满足大多数场景了,但是似乎还不够完美,特别是当我们使用活动图配合表达用例图中的用例流程时,会发现单一的活动图,很难看出角色之间是如何交互的,比如下图:

复杂流程

这个活动图中,我们没法看出这个流程有几个角色参与了,每个角色所处的流程在哪。

为了解决这个问题,UML 引入了泳道的概念,把 activity 进行分组。对应在用例图时,每个泳道就可以代表一个角色,泳道里的活动即对应角色的用例。

泳道图优化流程

对比不难发现,用了泳道图之后,角色之间如何互动就清晰很多了。

小结

活动图涉及的元素比较多,这里简单做个小结

  1. 活动图必须有起点和终点
  2. 活动图的流程节点叫做 activity,起点、终点与 activity 已经可以组成最简单的活动图
  3. 决策用于实现分支流程,当分支流程最终走向同一个流程时,应使用合并(merge node)
  4. 分叉用于实现并行流程,加入用于表达多个子流程结束后,再执行下一个流程的场景
  5. 使用泳道可以为 activity 分类,配合用例图表达需求时,每个泳道可以作为一个角色

思考题

活动图如何配合用例图完整的表达产品需求?

OAuth2 简介

写在前面

本篇文章主要是简单介绍 OAuth2.0 的一些概念和授权模式,不会涉及到具体的实现或者参数细节。这篇文章旨在让对 OAuth 不了解的人有一些基本的概念,了解了这些概念之后就能清楚各个授权模式应该在什么场景下使用,以及使用过程中一些重点要注意的细节。

概念

The OAuth 2.0 authorization framework enables a third-party
application to obtain limited access to an HTTP service, either on
behalf of a resource owner by orchestrating an approval interaction
between the resource owner and the HTTP service, or by allowing the
third-party application to obtain access on its own behalf. This
specification replaces and obsoletes the OAuth 1.0 protocol described
in RFC 5849.

OAuth2是一种认证框架(authorization framework),他是用于允许第三方应用经用户授权后访问对应的http 服务或资源。
基于上述概念,我们需要明确的是 OAuth2 是一种认证框架,不仅是一种狭义的协议(狭义的协议指双方互相沟通应遵守的规则),OAuth2 作为一种框架,他定义了多个角色、授权类型以及对应的使用场景。
另外,我们可以看到 OAuth2 推出的核心场景是用于对第三方应用的授权访问。有些项目中会使用 OAuth 协议在自己的客户端上鉴权,这是使用了密码模式。因为我们认为即使是自己开发的客户端,其实也是属于第三方应用,因为客户端是分散在外部的,实际上服务端并不完全可控。因此使用 OAuth 协议密码模式的客户端,有责任保障安全性。

OAuth Roles

OAuth 定义了四种角色,分别是:

  • 资源拥有者(Resource Owner),也就是真实的用户
  • 客户端(Client),即第三方应用
  • 资源服务器(Resource Server),即管理资源的服务
  • 授权服务器(Authorization Server),顾名思义,即用于授权客户端访问的服务

在 OAuth 中,所有操作实际上是以人为本,任何模式下,都需要用户的授权,可能是显示的,也可能是隐式的。授权服务器的作用就是为经由 Resource Owner 确认过的客户端颁发令牌(可以理解为是一个通行证),客户端带着令牌向资源服务器(Resource Server)访问请求资源。这里的资源不限于数据,也可能包含某些服务。在现实场景中,资源服务器即我们的业务服务器。

image

授权模式

授权模式有以下几种:

每个授权模式都适用于不同的场景,如 web app、native app、没有浏览器的设备、服务器之间的鉴权等等。接下来会分别介绍每一种授权模式以及应用场景

授权码模式(Authorization Code)

授权码模式是 OAuth2 授权最广泛的方式,其能保障安全的核心原因是用户在浏览器中授权,并且分两步获得 token。

image

详细说明下流程:

  1. app(即客户端,无论是 web app 还是 native app) 想要获得授权,首先通过浏览器打开授权页面
  2. 授权页面需要用户亲自操作,允许 app 获得授权
  3. 服务端返回给app授权码(一般实现的方案是通过 URL 重定向)
  4. app 使用授权码向授权服务器获取 access token

这里值得考究的是授权码的模式,为什么不在第 3 步返回 token,而是需要额外的授权码再次去获取 token 呢?
这么做的用意主要是从安全性方面考虑。假设直接在第 3 步返回 token,如果是 web 应用,那么 token 是通过 url 返回的,浏览器可能会缓存url 历史导致 token 泄露。另外整个过程没有校验 app 的合法性,那么就很容易导致CSRF 攻击。
当然,如果我们能够确保客户端是合法的,那么直接在第 3 步返回 token 也是可以的,这就是 implicit 模式。

隐式授权(Implicit)

image

从流程图中不难看出,与授权码模式区别在于第三步就把 access token 返回了。因此这个模式只适用于授信的客户端,否则完全性难以保证。并且由于是通过回调返回 access token,因此隐式授权不支持 refresh token。

用户密码模式(Password)

顾名思义,就是用户直接将密码交由 app(比如直接在 app 上让用户输入账号密码),app 直接通过账号密码获取 token。我们在概述时也提到,这种模式通常用于一个企业不同服务之间的账号互联互通。

客户端模式(Client Credentials)

这种授权方式主要就是用于校验客户端的合法性,app 把由授权服务器分配的 id 和密码交由后端校验,获取到对应的 access token。流程与密码模式相似。

设备码模式(Device Code)

设备码模式一般用于一些没有浏览器,缺少输入条件的设备上,比如 Apple TV,可穿戴设备等。

image

设备令牌的流程和其他流程稍有不同,首先设备需要从授权服务器获取一个 uri 和一个用户码,接着用户需要通过浏览器打开 uri,输入这个用户码。在这个过程中,设备会一直循环,尝试去获取 token,直到拿到 token 或者用户码过期。

我们现在常用的二维码扫码登录流程,可以使用这个模式实现。

刷新令牌(Refresh Token)

拥有了 token,就等于拥有了对应的资源访问权限,因此为了保障安全性,token 都会设置一个有效期,减少因为 token 泄露造成的危害。但是从用户体验上来说,我们不希望app每隔一段时间就去要求用户授权,因此OAuth 设计了一个更长期限的 refresh token,这个 token 的作用是换取 新的access token。为什么增加 refresh token 就更安全了呢?其实是一个权衡的过程,refresh token 只会在换取 access token 时返回,在换取新的 access token 时使用,换句话来说即 refresh token 的暴露在网络的机会不多,因此 refresh token 泄露的可能性相对较小,这样安全性相比使用一个长时间的 access token 会安全得多

参考资料

OAuth2详解 by 知乎老码农不上班

What is the OAuth2.0 Authroization Code Grant Type by Aaron Parecki

Why does server return a authroization code instead of access token in first step

How the OAuth 2.0 Device Flow Works

UML-类图

概念

Class diagram is UML structure diagram which shows structure of the designed system at the level of classes and interfaces, shows their features, constraints and relationships - associations, generalizations, dependencies, etc.

类图是用于描述接口这一层次的图形,他表达了接口功能约束以及他们之间的关系。

使用场景

类图是适用于面向对象进行建模的场景,通过类图,我们能够知道我们对系统被抽象成了哪些类,以及他们之间的关系。因此,类图适用于使用面向对象的方法进行设计的系统、应用。

对于后端来说,一般类图常用于单一的系统内,对于微服务这类分布式架构的表达,更适用于组件图或者部署图。
对于前端来说,由于 js 的语言特性,以及react、vue 这类组件化框架大行其道,简单的业务场景就不需要使用到类图了,基于面向对象建模反而是过度设计,此时用组件图表达即可。但是当业务复杂到到一定程度,不得不使用面向对象对业务层进行建模时,类图就有意义了。

类图元素

类(class)

是面向对象的概念,是描述一系列对象共有的功能约束
对于类来说,功能即类的属性以及方法,约束即属性及方法的可见性。

image

接口(interface)

接口描述的是功能的合集,一般我们会对功能进行分类,同一类别的功能统一放在一个接口里,用接口来描述功能的抽象,以此来增强接口的可复用性。
比如 cloneable 接口,表述实现了这个接口的类是支持 clone 相关的行为的。接口和类最大的不同在于接口只描述行为,表达的是能力,比如 cloneable 接口,表达的是 clone 的能力,具体怎么 clone (如何实现)是在类的范畴,因此接口的抽象程度更高。

接口声明

因为接口是一个高度的抽象,因此接口需要有实际的载体,也就是类,所以接口是需要配合类来一起表达才能有实际的含义,因此声明了接口后,还需要表明谁来实现,或者相关的依赖。

接口实现

接口使用

类图关系

类的基本元素比较简单,难点在于关系的表达。业务之所以复杂,不是因为业务中可以抽象出多个类,而是类之间的关系,每个类的变动都可能牵扯到其他部分,业务行为正是通过这些”牵扯“组成的。因此我们使用面向对象建模,核心的目的在于让关系变得简单,简单意味着可控,业务行为便可预测。

本章节不会把所有的关系全部说清楚,只会讲到平时开发过程中常见的 5 种关系线,他们的含义以及用法。

依赖(dependency)

两个对象间最弱的关系,表示一个类的某些行为与另一个类有相关性。
敲黑板!依赖关系是行为之间产生关联

A 依赖 B 的三种场景:

class A {
  function fn(B b) { }
  function fn2() {
    B b = new B()
  }
  function fn3() {
    return new B()
  }
}

依赖关系

泛化(generalization)

通常指一个类(或接口)继承另一个类(或接口),并可以增加它自己的新功能的能力。

A 继承类 B 实现 IC 接口:

class A extends B implements IC { }

泛化关系

关联(association)

二元关系,表示对象与对象之间有持有关系

单向关联关系,A 关联 B :

class A {
  B b
}
class B { }

关联关系

双向关联关系,A 与 B 互相关联:

class A {
  B b
}
class B {
  A a
}

关联关系

聚合(aggression)

含义更明确的单向关联关系,表示群体与个体的关系。群体解散了,个体可能还会存活。
聚合关系强调了对象间生命周期的关系,聚合的对象是有各自独立的生命周期的。

class A {
  B b
  constructor(B _b) {
    this.b = _b
  }
  setB(B b) {
    this.b = b
  }
}

聚合关系

组合(composition)

和聚合关系类似,属于更明确的关联关系,表示全体和局部的关系。全体不存在了,局部也不存在了(或没有意义了),和聚合的区别在于声明周期的不同。

class A {
  B b
  constructor() {
    this.b = new B()
  }
}

组合关系

小结

我们讲的 5 种关系,都属于二元关系,区别在于使用的时机与生命周期的不同。依赖与关联的区别在于依赖仅是在行为上会使用到另一个类,而关联则是需要持有对象,会影响对象的生命周期。
聚合与组合是提出了更明确含义的关联关系,区别在于聚合的对象,生命周期是各自独立的,组合的对象,生命周期跟随整体。

要注意的是,关系是对现实事务的表达,因此关系本身也是有语义的。为了方便理解,我们使用对象声明周期的影响来区分依赖与关联,聚合与组合,但是这个只是充分非必要条件,不能狭隘的通过生命周期来反推关系

关系小结

总结

  • UML的类图是从程序逻辑层面上来表达系统设计的方法
  • 类图是一种静态图,描述的是系统的静态结构
  • 依赖关系,表达的是基于对象行为上的关联
  • 关联关系,表达的是对象间的持有关系,影响对象的生命周期
  • 聚合关系表达的是群体和个体的关系,删除了群体,可能不影响个体的生命周期
  • 组合关系表达的是整体和局部的关系,删除了整体,局部随之消亡

思考题

  • 企业与员工是什么关系?
  • 企业与个人是什么关系?
  • 工厂类与被生成的类是什么关系?如果是支持缓存的工厂类呢?

UML-包图

概念

Package diagram is UML structure diagram which shows structure of the designed system at the level of packages. The following elements are typically drawn in a package diagram: package, packageable element, dependency, element import, package import, package merge.

包图是从包的层级来对系统进行抽象描述。所谓包(package)是指一个命名空间(namespace),用于组织语义上相似的、可能会因为业务变动而一起变动的元素。因此相对于类图来说,包图是更高层次的抽象。
一些语言天然的拥有包的概念,比如 c++的 namespace,java 的 package 等。对于前端工程来说,我们可以定义一个文件夹为一个包。

使用场景

通常我们使用包图来对复杂的类图进行抽象,把含义相似的类组织在同一个包里,然后从包的层面来描述业务关系。因此包图适用于描述复杂的业务场景(会出现很多相似类、或者可能会派生很多相似类的场景)的逻辑关系,或者用于表达领域模型,如 MVC,MVVM 等分层设计的表达。

包图元素

包图的元素很少,就是包与依赖关系。因为包是一个命名空间,因此它不像类图一样,可以有很多种的关系,通常情况下我们只需要声明包与包之间的依赖关系即可,不需要像官网一样,为每一种依赖关系明确具体的场景。
包图元素

总结

包图可以理解为一个独立的命名空间、组织,是系统高度抽象的一个模型。包图主要用于建模,并不完全代表代码的表现形式。

思考题

我们在 #4 讲到了组件图,那么什么时候用组件图,什么时候合适使用包图呢?他们之间可以相互替换吗?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.