抽奖系统设计⽅案
restful接口设计1,项⽬简介
  本课题主要是基于VUE和SpringBoot框架实现⼀个抽奖系统服务端,该抽奖平台是⼀个⽀持多种不同的抽奖⽅式且⽀持⾼并发的多种⽤户系统,抽奖系统⾓⾊共分为四类,包括基础的抽奖⽤户,抽奖发布者,进⾏数据信息管理的后端管理员以及⾃动执⾏抽奖的抽奖执⾏模块。普通⽤户可以查看并参加抽奖;抽奖发布者可以发布抽奖,管理⾃⼰发布的抽奖信息和参加该抽奖的⽤户,获取系统返回的中奖⽤户并发奖;管理员可以通过抽奖系统后端管理现有的抽奖及⽤户信息;抽奖执⾏模块则负责⾃动适时执⾏各类抽奖。
2,开发环境
  前台开发平台:web前端
 后台开发平台:IntelliJ IDEA
 数据库:MySQL & Redis
 服务器:云服务器(BAE或SAE)
 计算机硬件配置:
    抓取服务器:内存1.5G以上
    数据服务器:内存2G以上
3,使⽤的技术
 前端:vue
  后端
    web框架:Springboot
    持久层框架:JPA
    认证授权框架:Shiro
    分布式框架:Dubbo+Zookeeper
    搜索框架:ElasticSearch
  数据库:
    mysql+redis
4,设计模式
4.1 ⼋⼤设计原则
  提到设计模式,我们⾸先需要了解设计模式的设计原则。 
1. 依赖倒置原则(DIP)
⾼层模块(稳定)不应该依赖于低层模块(变化),⼆者都应该依赖于抽象(稳定)。
抽象(稳定)不应该依赖于实现细节(变化),实现细节(变化)应该依赖于抽象(稳定)。
2. 开放封闭原则(OCP)
对扩展开放,对更改封闭。
类模块应该是可以扩展的,但是不可修改。
3. 单⼀职责原则(SRP)
⼀个类应该仅有⼀个引起它变化的原因。
变化的⽅向隐含着类的责任。
4. Liskov替换原则(LSP)
⼦类必须能够替换它们的基类(IS-A)。
继承表达类型抽象。
5. 接⼝隔离原则(ISP)
不应该强迫客户程序依赖它们不⽤的⽅法。
接⼝应该⼩⽽完备。
6. 优先使⽤对象组合,⽽不是类继承
类继承通常为"⽩箱复⽤",对象组合通常为"⿊箱复⽤"。
继承在某种程度上破坏了封装性,⼦类⽗类耦合度过⾼。
⽽对象组合则只要求被组合的对象具有良好定义的接⼝,耦合度较低。
7. 封装变化点
使⽤封装来创建对象之间的分界层,让设计者可以在分界层的⼀侧进⾏修改,⽽不会对另⼀侧产⽣不良的影响,从⽽实现层次间的松耦合。
8. 针对接⼝编程,⽽不是针对实现编程
不将变量类型声明为某个特定的具体类型,⽽是声明为某个接⼝。
客户程序⽆需获知对象的具体类型,是需要知道对象所具有的接⼝。
减少系统中各部分的依赖关系,从⽽实现"⾼内聚,松耦合"的类型设计⽅案。 
重构关键技法 
4.2 重构关键技法
静态 -> 动态
早绑定 -> 晚绑定
继承 -> 组合
编译时依赖 -> 运⾏时依赖
紧耦合 -> 松耦合
4.3  本项⽬中运⽤的设计模式
  对象创建过程中使⽤new,new依赖具体类,耦合度⾼。为了避免new,减少依赖,提供封装机制避免直接new,降低耦合度。
  ⼀般的new 违背了依赖倒置原则(依赖抽象,⽽不依赖具体)
    例:A a = new A(); //此处的A是⼀个具体的类,⽽不是抽象
  根据依赖倒置原则,我们应该尽可能的使⽤抽象设计,减少具体(可以降低耦合),但是抽象类是不可以实例化的(new),此时就需要⼀种⽅式来解决实例化问题。提供⼀个⼯⼚接⼝,把创建对象的任务往后推给⼦类,使当前类与new隔离。该种设计模式就是⼯⼚模式。
  使⽤⼯⼚模式的好处:⼯⼚模式⽤于隔离类对象的使⽤者和具体类型之间的耦合关系。⾯对⼀个经常
变化的具体类型,紧耦合关系(new)会导致软件的脆弱。⼀旦更改具体类型,就要更改使⽤者中的代码,耦合度太⾼,⽽⼯⼚⽅法,降低了两者的耦合度,类型改变或增加时只需改变/增加⼯⼚⼦类即可,⽽使⽤者的源码不必改变。
  ⼯⼚模式的通⽤类图结构图:(附部分注释,希望可以帮助读者快速理解)
5,架构风格
5.1 微服务架构
  “微服务架构是⼀种架构模式,它提倡将单⼀应⽤程序划分成⼀组⼩的服务,服务之间相互协调、互相配合,为⽤户提供最终价值。每个服务运⾏在其独⽴的进程中,服务和服务之间采⽤轻量级的通信机制相互沟通(通常是基于HTTP的Restful API).每个服务都围绕着具体的业务进⾏构建,并且能够被独⽴的部署到⽣产环境、类⽣产环境等。微服务架构有如下优点:
    1,提升开发交流,每个服务⾜够内聚,⾜够⼩,代码容易理解;
    2,服务独⽴测试、部署、升级、发布;
    3,按需定制的DFX,资源利⽤率,每个服务可以各⾃进⾏x扩展和z扩展,⽽且,每个服务可以根据⾃⼰的需要部署到合适的硬件服务器上;每个服务按需要选择HA的模式,选择接受服务的实例个数;
    4,容易扩⼤开发团队,可以针对每个服务(service)组件开发团队;
    5,提⾼容错性(fault isolation),⼀个服务的内存泄露并不会让整个系统瘫痪;
    6,新技术的应⽤,系统不会被长期限制在某个技术栈上;
5.2 分布式架构
  ⽤最简单的⽅式定义,分布式系统就是让终端⽤户把⼀组⼯作在⼀起的计算机当做⼀个单独的机器来使⽤。这些机器共享状态,并发操作,并且单个机器出现问题不会影响到整个系统的正常⼯作。架构的优势是性能⾼,易扩展,容错,低延时。
5.3 Restful风格
  使⽤Restful风格可以项⽬的请求更加清爽,以管理员管理抽奖活动为例,说明部分请求使⽤Restful:
实验功能请求URI请求⽅式
查询所有活动activitys GET
查询某个活动(来到修改页⾯)activity/1GET
来到添加页⾯activity GET
添加活动activity POST
来到修改页⾯(查出活动进⾏信息回显)activity/1GET
修改活动activity PUT
删除活动activity/1DELETE
6,接⼝设计
6.1 ⽤户界⾯
  在⽤户抽奖界⾯以及抽奖发布者的界⾯,应充分考虑展⽰信息与⽤户的可交互性,在需求分析的基础上,合理展⽰抽奖系统为⽤户提供的各种信息,包括根据⽤户推荐的各类抽奖活动。由于前端确定采⽤VUE框架,因此可以基于VUE对信息进⾏简单排布形成基本的展⽰界⾯,再在此基础上进⼀步优化,尽可能降低界⾯和操作的学习成本。
6.2 软件接⼝
  前端⽅⾯,可以提供前端数据接⼝⽤于接收抽奖系统服务端发送的⽤于显⽰的信息,提⾼前端界⾯的可扩展性,也易于更换或者直接扩展前端界⾯。服务器端则提供基本的数据库的连接接⼝,⽅便数据库的迁移、升级和更换;另外还可以提供抽奖执⾏模块、发奖模块的接⼝,实现模块化,模块之间进⾏解耦以提⾼维护性和可扩展性。
7,UML类图
8,视图
8.1,分解视图
  分解是构建软件架构模型的关键步骤,分解视图也是描述软件架构模型的关键视图,⼀般分解视图呈现为较为明晰的分解结构(breakdown
structure)特点。分解视图⽤软件模块勾划出系统结构,往往会通过不同抽象层级的软件模块形成层次化的结构。
8.2,依赖视图
  依赖视图展现了软件模块之间的依赖关系。⽐如⼀个软件模块A调⽤了另⼀个软件模块B,那么我们说软件模块A直接依赖软件模块B。如果⼀个软件模块依赖另⼀个软件模块产⽣的数据,那么这两个软件模块也具有⼀定的依赖关系。依赖视图在项⽬计划中有⽐较典型的应⽤。⽐如它能帮助我们到没有依赖关系的软件模块或⼦系统,以便独⽴开发和测试,同时进⼀步根据依赖关系确定开发和测试软件模块的先后次序。依赖视图在项
⽬的变更和维护中也很有价值。⽐如它能有效帮助我们理清⼀个软件模块的变更对其他软件模块带来影响范围。
8.3,泛化视图
  泛化视图展现了软件模块之间的⼀般化或具体化的关系,典型的例⼦就是⾯向对象分析和设计⽅法中类之间的继承关系。值得注意的是,采⽤对象组合替代继承关系,并不会改变类之间的泛化特征。因此泛化是指软件模块之间的⼀般化或具体化的关系,不能局限于继承概念的应⽤。泛化视图有助于描述软件的抽象层次,从⽽便于软件的扩展和维护。⽐如通过对象组合或继承很容易形成新的软件模块与原有的软件架构兼容。
8.4,执⾏视图
  执⾏视图展⽰了系统运⾏时的时序结构特点,⽐如流程图、时序图等。执⾏视图中的每⼀个执⾏实体,⼀般称为组件(Component),都是不同于其他组件的执⾏实体。如果有相同或相似的执⾏实体那么就把它们合并成⼀个。执⾏实体可以最终分解到软件的基本元素和软件的基本结构,因⽽与软件代码具有⽐较直接的映射关系。在设计与实现过程中,我们⼀般将执⾏视图转换为伪代码之后,再进⼀步转换为实现代码。