使用vuex管理用户信息

介绍

本文介绍如何使用vuex管理用户信息,封装相关方法,为所有页面提供接口,并将其应用在路由检测中的方法。

Vuex 结构

前置工作

新建一个store.js文件,将以下代码复制到文件

1
2
3
4
5
6
7
8
9
10
11
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
getters: {}
})

在main.js中添加

1
2
3
4
5
6
7
import store from './store'

new Vue({
...
store,
...
)}

这样我们就能在任意页面使用vuex store了

结构说明

从上面的代码可以看出,vuex store的结构分为四个部分:state,mutation,actions,getter

  • state:存储变量的地方,可以理解成是vuex store的公有成员变量;
  • mutations:是更新state的地方;
  • actions:触发mutation的地方,同时也是定义vuex store方法的地方;
  • getter:提供计算属性的地方,主要作用是提高便捷性;

vuex store的一般用法为:在state中存储信息,外部通过调用action中的方法来触发mutation,在mutation中对state进行修改,最终外部页面通过state或者getter获取数据。

使用vuex进行登录

现在以用户登录为例说明vuex store的用法。

我们先在state里定义要存储的内容,在这里存储用户登录状态与用户信息。需要注意的是,vuex存储的变量是非持久化的,刷新页面、退出页面都会丢失state中的值。我们就需要使用localStorage辅助,进行变量持久化存储。这样下一次用户打开页面时,如果用户的cookie还有效,用户就能直接进入主页,无需再次登录。

1
2
3
4
5
6
7
const STATUS_ID = "status"

state:
{
status: localStorage.getItem(STATUS_ID),
user : {},
}

在mutation中定义两个改变state的mutaions,一个用于登录成功的情况,另一个用于登录失败的情况

1
2
3
4
5
6
7
8
9
signin_success(state, user)
{
state.status = 'success'
state.user = user
},
signin_error(state)
{
state.status = 'error'
},

在action中编写signin函数,供外部调用。在action中,我们应该返回一个promise,支持调用者处理成功或失败的情况。

1
2
3
4
5
6
7
8
9
10
11
signin({commit, dispatch}, user)
{
return new Promise((resolve, reject) =>
{
//网络请求('/signin', user)
// if 成功
commit('signin_success', response.user)
// else
commit('signin_error')
})
},

最后完成getter部分,返回一个bool值,提供用户是否登录成功的信息,免去外部页面使用字符串判断的麻烦。

1
2
3
4
getters :
{
isSignedIn: state => state.status == 'success',
}

在登陆页面只需简单地分发任务(dispatch),就能完成登陆功能。(在前置工作中已经让store全局化了)

1
this.$store.dispatch("signin", form).then(...).catch(...)

执行这一语句后发生的事情如下

vuex应用

提供用户信息

获取登录状态

1
this.$store.getters.isSignedIn

获取用户信息

1
this.$store.state.user

辅助路由检测

在vue应用中,有一些页面需要登陆才能访问,这个功能可以通过vuex与vue router的beforeEach来实现。

通过匹配router目标路径,并使用vuex store判断用户是否已经登陆,来实现阻止跳转和重定向的功能。以下代码的逻辑时,未登陆的用户只能访问登陆注册页,登陆用户能访问所有页面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
router.beforeEach((to, from, next) =>
{
// router guard

if (to.path != '/signin' && to.path != '/signup')
{
if (store.getters.isSignedIn)
next()
else
// if the user has not signen in,
// he can only visit signin and signup
next('/signin')
}
else
next()
})

源代码

包含了登陆、注册、登出逻辑的完整代码(省去的网络请求部分)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const STATUS_ID = "status"

export default new Vuex.Store({
state:
{
status: localStorage.getItem(STATUS_ID),
user : {},
},
mutations:
{
signin_request(state)
{
state.status = 'loading'
},
signin_success(state, user)
{
state.status = 'success'
state.user = user
},
signin_error(state)
{
state.status = 'error'
},
signout(state)
{
state.status = localStorage.removeItem(STATUS_ID)
state.user = {}
},
},
actions:
{
signin({commit, dispatch}, user)
{
return new Promise((resolve, reject) =>
{
commit('signin_request')

//网络请求
// if 成功
commit('signin_success', response.user)
// else
commit('signin_error')

})
},
signup({commit}, user)
{
return new Promise((resolve, reject) =>
{
//网络请求
})
},
signout({commit})
{
return new Promise((resolve, reject) =>
{
//网络请求
commit('signout')
})
},
},
getters :
{
isSignedIn: state => state.status == 'success',
}
})

用例图模型&用例活动图

根据订旅馆建模文档,

一、根据订旅馆建模文档,Asg-RH.pdf

  • 绘制用例图模型(到子用例)

  • 给出 make reservation 用例的活动图

二、根据课程练习“投递员使用投递箱给收件人快递包裹”的业务场景

  • 分别用多泳道图建模三个场景的业务过程

    1. x科技公司发明了投递柜,它们自建了投递柜以及远程控制系统。注册的投递员在推广期免费使用投递柜。由于缺乏资源,仅能使用y移动平台向客户发送短信通知。

    2. 随着产品推广,x公司与各大快递z公司达成协议。x公司在快递柜上添加了二维码扫描装置,z公司的快递员不仅可在快递柜上登陆(由z公司提供认证服务),且可扫描快递单号,投递入柜后自动由z公司发短信给客户。客户取件后,自动发送给z公司投递完成。

    3. x公司进一步优化服务,开发了微信小程序实现扫码取快递。如果用户关注了该公司公众号,直接通过过公众号推送给用户取件码等信息。不再发送短信。

  • 根据上述流程,给出快递柜系统最终的用例图模型

    • 用正常色彩表示第一个业务流程反映的用例
    • 用绿色背景表述第二个业务场景添加或修改的用例,以及支持 Actor
    • 用黄色背景表述第三个业务场景添加或修改的用例,以及支持 Actor

用例

一、简答题

  1. 用例的概念

  用例是描述一个参与者有目的地使用系统的成功和失败情景的集合。

  1. 用例和场景的关系?什么是主场景或 happy path?

  场景是参与者和系统交互的一系列动作的集合,是用例的实例。用例是一系列场景的集合。主场景描述的是参与者与系统最主要的交互过程,一般情况下是成功的场景。

  1. 用例有哪些形式?

  用例有概要(Brief)、简便(Casual)和完整(Fully)形式。概要形式通常为一段总结性的文字,简便形式则是以非正式的格式描述不同场景,而完整形式则会详细描述所有步骤和分支情况。

  1. 对于复杂业务,为什么编制完整用例非常难?

  复杂业务的交互比较多,容易在每个交互步骤出现不同的分支,完整用例要考虑所有可能的情景,分支使得要考虑的情景异常多,很难被完全覆盖,因此编制完整用例非常难。

  1. 什么是用例图?

  用例图是使用绘图的方式描述系统用例的方法。

  1. 用例图的基本符号与元素?

  用例图的基本符号包括Actor、system框、Neighbour system框、用例、actor与use case、use cases之间的关系,具体如图所示:

  1. 用例图的画法与步骤

    • 确定研讨的系统
        使用用例图 System框、正确命名系统或子系统

    • 识别 Actors
        识别使用系统的主要参与者,使用用例图 actor符号表示

    • 识别系统依赖的外部系统
        使用用例图Neighbour system框表示用例依赖的外部系统、服务、设备,并使用构造型(Stereotype)识别

    • 识别用例(服务)
        识别用户级别用例、识别子功能级别的用例

    • 建立 Actor 和 Use Cases 之间的关联
        使用无方向连线,表示两间之间是双向交互的协议

       

  2. 用例图给利益相关人与开发者的价值有哪些?

    • 明确系统的业务范围、服务对象(角色)、外部系统与设备
    • 帮助识别技术风险,提前实施关键技术原型公关与学习
    • 易于评估项目工作量,合理规划迭代周期,规划人力需要

二、建模练习题(用例模型

  • 选择2-3个你熟悉的类似业务的在线服务系统(或移动 APP),如定旅馆(携程、去哪儿等)、定电影票、背单词APP等,分别绘制它们用例图。并满足以下要求:

    • 请使用用户的视角,描述用户目标或系统提供的服务

    • 粒度达到子用例级别,并用 include 和 exclude 关联它们

    • 请用色彩标注出你认为创新(区别于竞争对手的)用例或子用例

    • 尽可能识别外部系统和服务

百词斩app 用例图:

多邻国app 用例图:

  • 然后,回答下列问题:

    1. 为什么相似系统的用例图是相似的?

        因为相似的系统的主要目的是一致的,如背单词系统的核心就是为了让用户有兴趣地背单词,这导致了很多情景都类似,使得用例图的结构相似。

    2. 如果是定旅馆业务,请对比 Asg_RH 用例图,简述如何利用不同时代、不同地区产品的用例图,展现、突出创新业务和技术

        同为订旅馆业务,主用例大致相同,故创新点一般出现在子用例。在子用例处可以添加能创新的业务,如去哪儿的用例图中可以添加预测用户中文输入的子用例,突出创新业务。

    3. 如何利用用例图定位创新思路(业务创新、或技术创新、或商业模式创新)在系统中的作用

        根据创新点在用例图中的层次(从左到右)定位创新思路,例如创新点出现在与参与者直接相连的用例时,说明创新点为业务创新。

    4. 请使用 SCRUM 方法,选择一个用例图,编制某定旅馆开发的需求(backlog)开发计划表

      选择去哪儿用例图,编制backlog:

ID Title Est Iter Imp
10101 make reservation 5 1 5
10102 find hotel 10 2 5
10103 predict input 5 1 3
10110 manage basket 2 1 3
10111 pay 10 2 5

  1. 根据任务4,参考 使用用例点估算软件成本,给出项目用例点的估算
用例 # 事务 # 计算 原因 UC 权重
make reservation 10 7 包含了选择旅馆、挑选房间、确认订单等子事务 复杂
find hotel 5 5 包含了查找地图、地点、运维等子事务 一般
predict input 2 3 简单
manage basket 5 3 简单
pay 5 5 涉及支付失败、支付超时等意外情况处理 一般

软件生命周期模型

1. 简述瀑布模型、增量模型、螺旋模型(含原型方法),并分析优缺点。从项目特点、风险特征、人力资源利用角度思考

瀑布模型:

  瀑布模型将软件生命周期分为需求分析、设计、实现、验证、维护五个阶段,每个阶段按顺序执行,完成了一个阶段后随即进入下一个阶段。

优点:

  • 降低软件开发的复杂程度,提高软件开发过程的可管理性。

  • 强调分析和设计的重要性

  • 以阶段成果评估产品,保证阶段之间的正确衔接,使最终产品的质量得到保证。

缺点:

  • 阶段的线性顺序缺乏灵活性,无法进行阶段回溯。

  • 难以控制风险

  • 瀑布模型中的软件活动是以文档驱动的,当文档过多时,工作量也随之增加;以文档来评估项目进度的管理人员也容易产生错误判断。

  • 容易造成项目延期、不可控

增量模型:

  增量模型首先对系统最核心或最清晰的需求进行分析、设计、实现、 测试并集成到系统中,再按优先级逐步实现后续需求。

优点:

  • 保证系统最核心的功能,降低系统失败的风险,提高系统可靠性、稳定性、可维护性

缺点:

  • 难以准确界定系统核心

  • 难以选定增量的粒度

螺旋模型:

  螺旋模型结合了瀑布模型和快速原型方法,是风险驱动的迭代过程。在多个迭代过程中,实现瀑布模型的多个阶段,但每一次迭代只包含一个或两个阶段

优点:

  • 强调可选方案和约束条件从而支持软件的重用,有助于将软件质量作为特殊目标融入产品 开发之中

  • 引入了明确的风险管理机制,降低项目风险

  • 能有效应对需求功能复杂、开发周期长、用户需求经常变化等问题

缺点:

  • 风险分析需要花费较大的成本,且错误的风险分析会带来更大的风险
  • 难以确定迭代次数,无法确定发布日期
  • 不适用于大规模团队运作

2. 简述统一过程三大特点,与面向对象的方法有什么关系?

统一过程的三大特点:

  • 具有伸缩性:只需要使用对当前项目有效的过程,而不需要使用整个框架的每个过程

  • 有效性:统一过程在很多大项目里被证明是有效的

  • 提高生产效率:提供了可能已经使用过的实用方法

与面向对象方法的关系:

  统一过程是一个面向对象的程序开发方法论,是面向对象方法的一个应用实例。面向对象分析确定了问题的范围,因此统一过程提供的方法能在不同的情景下具有伸缩性,而面向对象设计提供了分析提出的问题的有效解决方案,因此统一过程具有有效性,能提高生产效率。

3. 简述统一过程四个阶段的划分准则是什么?每个阶段关键的里程碑是什么?

  我认为统一过程的四个阶段划分准则是在每个阶段对统一过程的核心工作流的着重程度。

  统一过程的核心工作流为:Business Modeling,Requirements analysis,Design,Implementation,Test and Integration

  Inception阶段着重业务建模与需求分析,以此来确定系统的可行性,并给出生命周期目标

  Elaboration阶段着重分析设计,给出具体的文件规范,同时进行初始阶段开发实现

  Construction阶段的主要工作为开发与测试,在构建阶段末期,尝试进行部署,以得到一个具备雏形的系统

  Transition阶段着重于部署,同时进行测试修改,最终得到一个可交付的产品

里程碑:

  • Inception:生命周期目标

  • Elaboration:生命周期体系结构

  • Construction:一个具备初始运行能力的系统

  • Transition:一个能交付给客户的具有全部需求功能的系统

4. 软件企业为什么能按固定节奏生产、固定周期发布软件产品?它给企业项目管理带来哪些好处?

  软件公司能根据能力成熟度模型集成(CMMI)评估自身的成熟度,确定自己的定位,并以此为依据选择企业的主营软件类型,继而通过软件的规模、稳定程度确定软件生命周期模型。在固定的软件生命周期模型的指导下,软件企业的项目团队只需要根据计划就能按期生产出可交付的软件产品。这样软件企业就能按固定节奏生产、发布软件,并从中有效地控制了软件风险,获得稳定的利润来源。软件生命周期模型还能很好地引导项目管理,为项目管理提供了明确的实施方法和度量规则,大大减轻了项目管理的难度。

分析、设计与UML

分析、设计与UML

[TOC]

1、简答题

1.1 用简短的语言给出对分析、设计的理解。

 分析明确了应该做什么事才是对的,着重于对问题与需求的考察。

 设计明确了怎样才能把事情做对,着重于在概念层面上提出解决方法。

1.2 用一句话描述面向对象的分析与设计的优势。

 面向对象的分析与设计能为软件的具体实现、编码提供清晰的对象模型。

1.3 简述 UML(统一建模语言)的作用。考试考哪些图?

 UML是一种能把分析与设计的结果可视化的语言。

 考试考以下图:

  • 用例图:用户角度:功能、执行者
  • 静态图:系统静态结构
    • 类图:概念及关系
    • 对象图:某种状态或时间段内,系统中活跃的对象及其关系
    • 包图:描述系统的分解结构
  • 行为图:系统的动态行为
    • 交互图:描述对象间的消息传递
      • 顺序图:强调对象间消息发送的时序
      • 合作图:强调对象间的动态协作关系
    • 状态图:对象的动态行为。状态-事件-状态迁移-响应动作
    • 活动图:描述系统为完成某功能而执行的操作序列
  • 实现图:描述系统的组成和分布状况
    • 构件图:组成部件及其关系
    • 部署图:物理体系结构及与软件单元的对应关系

1.4 从软件本质的角度,解释软件范围(需求)控制的可行性

  软件本身具有复杂性、不可见性、不一致性、可变性,80%的软件范围内容对客户与开发者都是模糊的。根据2/8 法则,细化 20% 有效需求,往往可满足 80% 客户需要。因此,只需找到客户最感兴趣的内容,细化20%的需求,给出严格的需求约定,就能使软件范围保持在可控范围内。

2、项目管理实践

2.1 看板使用练习

UML绘图工具练习

《UML和模式应用》第3版,第9页,图1-6 UML的不同透视图

软件的本质与软件工程科学

软件的本质与软件工程科学

[toc]


1. 软件工程的定义

­  软件工程是指应用系统的、规范的和可量化的方法去开发、操作与维护软件,即是将工程应用在软件上,以及对这些方法的研究。

2. Software Crisis

2.1 本质原因

­  因为计算机性能的高速发展以及相应的软件所需处理的问题日益复杂,使得软件难以高效地开发,导致了软件危机。

2.2 表现

­软件危机表现为

  • 软件项目超预算

  • 软件项目逾期

  • 软件低效

  • 软件质量低

  • 软件不能满足预期需求

  • 软件项目难以管理,代码难以维护

  • 软件夭折

2.3 克服方法

­  使用SWEBoK定义的知识域培训软件工程师,使用CMMI评估改进公司自身的软件开发过程,使用软件质量监管(SQM)保证软件的质量等

3. 软件生命周期

­  软件生命周期是指将软件开发任务分解成若干独立阶段,以提升软件设计、产品管理、项目管理的效果,从而使复杂的软件开发过程变得可控与便于管理。软件生命周期一般分为六个阶段:可行性分析与计划阶段、需求分析阶段、设计阶段、实现阶段、测试阶段与运行与维护阶段。

4. SWEBoK的15个知识域

  1. Software Requirements:

    ­  软件需求;软件需求明确了软件需要解决怎样的实际问题

  2. Software Design:

    ­  软件设计;软件设计定义了架构、组件、接口过程以及系统与组件特性

  3. Software Construction:

    ­  软件构建;软件构建是关于设计、编码、测试、验证的详细过程

  4. Software Testing:

    ­  软件测试;软件测试是评价产品质量并改进产品缺点的活动

  5. Software Maintenance:

    ­   软件维护;软件维护包括增强现有产品功能,使软件在新的环境中运行,以及改进缺点。

  6. Software Configuration Management:

    ­  软件配置管理;软件配置管理明确了系统在特定时间、情景下的配置规则以及维护整个生命周期系统配置的可追溯性与完整性

  7. Software Engineering Management:

    ­  软件工程管理;软件工程管理设计计划、定位、测量、报告与控制项目来确保软件开发与维护的系统性、规范性与可量化性。

  8. Software Engineering Process:

    ­  软件工程过程;软件工程过程涉及对于软件生命周期过程的定义、实现、评估、测量、管理与改进。

  9. Software Engineering Models and Methods:

    ­  软件工程模型与方法;软件工程模型与方法提出包含多个生命周期阶段的方法

  10. Software Quality:

    ­  软件质量;软件质量知识域包括软件质量的基础、软件质量的管理过程与实际考虑。

  11. Software Engineering Professional Practice:

    ­  软件工程专业实践;软件工程专业练习是关于软件工程师必须具备的知识、技能与态度,以专业、负责与热情的态度进行软件工程实践

  12. Software Engineering Economics:

    ­  软件工程经济;软件工程经济是基于商业考虑的决策,以使技术决策与商业目标一致。

  13. Computing Foundations :

    ­  计算基础;计算基础包括了软件工程所需的计算知识背景

  14. Mathematical Foundations:

    ­  数学基础;数学基础包括了软件工程所需的数学知识背景

  15. Engineering Foundations:

    ­  工程基础;工程基础包括了软件工程所需的工程知识背景

5. CMMI的五个级别

  1. 初始级:软件过程是无序的,自发生产软件。
  2. 可管理级:制定了必要的过程纪律;有基本的配置、需求管理,制定了工作计划,有工作监管与控制,指定了测评与分析措施
  3. 已定义级:已将软件工程与管理过程文档化、标准化;有容量与可使用性管理,具备决策分析、解决能力,具有事故应急预防机制,集成化的工作管理、危机管理、策略,制定了组织的各种标准,具有服务系统。
  4. 量化管理级:对软件过程和产品都有定量的理解与控制,具有可量化的工作管理、组织过程绩效
  5. 优化管理级:具备因果分析与解决能力,组织绩效管理

6. 我对CMMI的简单理解

­  CMMI指能力成熟度模型集成,我认为这个模型集成能帮助公司评价自身的成熟度,来成立各种适应自身所需的部门,制定相应的规则制度,从而帮助公司按时、高效并且在既定预算内完成软件开发。CMMI为公司的每个过程提供了一个基础框架,减少了过程之间的重叠部分,从而使每个过程高效地进行,而所有过程的框架又能作为一个整体发挥作用,使得开发的软件的质量得到保证。CMMI的最终目的就是帮助公司克服软件危机,找到符合公司实际情况的软件开发模式。

幽蓝星球的雨季精灵

幽蓝星球的雨季精灵

1

  再次确认闹钟被关掉后,我心满意足地倒向枕头。周末的早晨,要自然醒来才算完美。

  冷冷的风扑进房间里,把梦境捏碎。落地窗被风刮得砰砰作响,活像有一双大手摇晃它似的。“五时二十七分”几个字僵化在手机屏幕上,“冬木市发布暴雨黄色预警信号”。荧屏渐渐变暗,意识如水蒸气般聚回梦的形状。

  眼前出现了一个模糊的白色气团,有一种非现实性色调掺杂进来。空气如果冻一般浓稠,冷冻过的香草气味缓慢移动着。梦里的场景一层层被剥开,意识里的什么被慢慢抽离身体。

  醒来时,处于一片空白。弄不清自己在什么地方,好半天像一棵蔫菜——一棵长时间被遗忘在黑乎乎的餐橱里头的青菜——一样麻木不仁。

  继而像收集散落在地板上的豆粒似的,一个个拾回自己的意识,让身体适应现实。

2

  铃声响过三遍,渡边急急忙忙跑进教室,在窗边的位置坐下,渡边似乎更喜欢窗外的景色。踏进教学楼就能让上课铃响起,是渡边与生俱来的特异功能。

  课后我和渡边一起去吃晚饭。餐厅坐落在湖畔,湖面被雨滴激起的波纹与餐厅里餐具碰撞的声音对上了节拍。

  鱼肉的清新气味在口中扩散开来,我可以清楚感觉出不折不扣的清甜肥美正被吮吸到身体的每一个角落。我将最后一片鱼夹进嘴里。餐厅里也荡出清新味儿。

  收拾好餐具后,我和渡边撑伞走向课室。爱上步行是从雨季开始。路边的自行车如废弃不用的词语乱七八糟地停在那里,其中就有我自己的一辆。

  “你听说过雨季精灵吗?”,渡边突然问我。

  “没听说过”,我摇摇头,“为什么问这个”

  “最近总是在下雨,一口气下了快一个星期,我都快忘了上次看到太阳是多久之前的事情。据说雨季精灵会偷走人的睡眠,来制造一场又一场不停歇的雨”。

  我将信将疑地看着渡边,继续向前走去。真的有这种精灵吗,我想。

3

  宿舍灯熄灭了,渡边的床马上传出了鼻鼾声,彷佛灯开关同他的意识之间有电线连在一起。

  我在透进窗户的微光中寻找着名为困意的东西。我可以在指尖略微感觉出类似睡眠边缘的东西,我试图把它抓住,却被它从指缝中逃脱。我的身体像是进入了浅浅的睡眠,但我的意识在近在咫尺的地方十二分清醒地注视着自己。我既是渴望入睡的肉体,又是无比清晰的意识。自雨季精灵,如果真的存在,来过之后,我再也无法入睡。

  假如雨季精灵是真实存在的,那睡精灵[^1]是不是也存在于现实呢。即使存在,睡精灵也只会眷顾渡边这样的人吧。

4

  扬声器里的弦乐逐层推进,音乐声沁入房间的每一个角落、墙壁的每一处小小的凹坑以及窗帘的每一道褶。

  天空一片灰暗,房间里的台灯发出惨白的光芒。

  几滴雨从天空中漏出,滴在行色匆匆的行人的肩膀。乌云渐渐变厚,终于,云层再也掌不住雨水的重量,大雨倾盆而下。落在空旷的草坪上,落在生活着清甜肥美的鱼的池塘里,落在刚刚倒满牛奶的陶瓷杯中。

  每个晚上依然毫无困意。一到晚上,我的脑袋就远离现实几百年几万公里。各种情景在脑海中的影院轮番上映,有关过去的画面,预想未来的镜头,还有关于雨季精灵的幻想。直到天亮影院才打烊。

5

  周围没有能称得上是高楼的建筑,站在通向顶层的楼梯转角处能把整片天空收揽眼底。雨云连绵到天际,把整个城市笼罩起来。

  云层裂开一道缝隙,透出微弱的光,又马上变黑了。

  一股天旋地转的困意向我袭来,我踉踉跄跄地走回房间,钻进被窝。

  无法入睡的记忆正以一百五十码的速度离我远去,一切都像发生在天荒地老的往昔。我正被包裹在睡眠的胶囊当中。无法入睡的困扰像一道门永远在我身后关上了。对未来的不安也好,对过去的悔恨也好,都伴随着大脑影院轰然倒塌,此时此刻我只想活在这一时刻,体会这纯粹的睡眠。

  醒来时,我仿佛躺在草地上。树枝上不知名的鸟在鸣啭。晾在阳台上的雨伞还散发冰冻的香草气味。[^2]


[^1]: The Sandman is a mythical character in Western and Northern European folklore who puts people to sleep and brings good dreams by sprinkling magical sand onto the eyes of people while they sleep at night——wikipedia
[^2]: 本文纯属虚构,部分文字借用了村上春树先生的句子。