让我们一起 回忆:

原则 基本认识
S 应该仅有一个引起它变化的原因
O 在不被修改的前提下被扩展
L 尽量从抽象类继承
I 应该依赖于抽象
D 倾向瘦接口

让我们开始 新课:

[Design Patterns] 03. Practice UML in project 的文档列表其实就是”过程模式“的一种。

设计模式”会在将来单独讲解

这里主要学习“体系结构模式”和“分析模式”。

《体系架构模式》


Ref: 10种常见的软件架构模式

Ref: 软件架构模式 (30页的书)

黑板模式

这种模式对于没有确定解决方案策略的问题是有用的。黑板模式由3个主要组成部分组成。

    • 黑板——包含来自解决方案空间的对象的结构化全局内存
    • 知识源——专门的模块和它们自己的表示
    • 控制组件——选择、配置和执行模块

所有的组件都可以访问黑板。

组件可以生成添加到黑板上的新数据对象。

组件在黑板上查找特定类型的数据,并通过与现有知识源的模式匹配来查找这些数据。

使用场景:

    • 语音识别
    • 车辆识别和跟踪
    • 蛋白质结构识别
    • 声纳信号的解释

利用数据库

高频率的访问数据库,不利于实时

利用发布—订阅模式

【这其实就是聊天功能】
这种实现方式通常采用消息队列作为黑板,队列工作在主题模式(Topic),专家作为队列的订阅者,同时可以向队列发送消息,消息会被发送至所有订阅者。以上过程实现了专家间的信息交流。
特点:
1 可以有效应用于实时性要求较高的系统,这种实现工作在“推模式”下。
2 难于实现信息的统计分析,不像实现方式一那样可以通过SQL支持,这些工作必须开发者自己完成。

MVC模式(模型-视图-控制器)

Ref: Android Module] 03 - Software Design and Architecture

一个小的项目且无需频繁修改需求就不用MVC框架来设计了,那样反而觉得代码过度设计,代码臃肿。

一般在大的项目中,且业务逻辑处理复杂,页面显示比较多,需要模块化设计的项目使用MVC就有足够的优势了。

【是不是还有更大的项目,那该如何?】

在MVC模式中我们发现,其实控制器Activity主要是起到解耦作用,将View视图和Model模型分离。

    • View 视图和Activity 控制器并不是完全分离的
    • 虽然Activity起到交互作用,但是找Activity中有很多关于视图UI的显示代码

【需要清除掉activity中的视图代码残渣,但还是先把业务逻辑分离开来才是要紧之事】

MVP模式(模型-视图-控制器)

Ref: Android Module] 03 - Software Design and Architecture

链接已讲。把业务逻辑从Activity中挪出来,挪到Presenter中去,让Activity回归View的角色,从此Presenter专注于业务,View专注于显示。

业务逻辑不再受Activity生命周期的影响,Activity也摆脱了业务逻辑无法复用的囧境。
【先搞定了业务独立,下一个阶段再搞定view和controller的完全分离】

View恳求Presenter帮忙问问Model是否能给点数据。

Model通过实现回调函数对外提供了一个接口给Presenter。

简单的讲:View调用Presenter的函数,该函数内部调用Model的一个回调函数实现的接口。

[Android Module] 08 - MVP by Mosby

其他

* MVVM - [Android Module] 06 - DataBinding and MVVM

* 起源于React的Flux框架。

From: 10种常见的软件架构模式

分层模式

一般信息系统中最常见的是如下所列的4层。

    • 表示层(也称为UI层)
    • 应用层(也称为服务层)
    • 业务逻辑层(也称为领域层)
    • 数据访问层(也称为持久化层)

Jeff:其实就是传统模型。

客户端-服务器模式

典型场景:邮件服务器和浏览器的关系

主从设备模式

主设备组件在相同的从设备组件中分配工作,并计算最终结果,这些结果是由从设备返回的结果。

管道-过滤器模式

管道-过滤器模式的体系结构是面向数据流的软件体系结构。它最典型的应用是在编译系统。一个普通的编译系统包括词法分析器,语法分析器,语义分析与中间代码生成器,优化器,目标代码生成器等一系列对源程序进行处理的过程。

Jeff: 有点生僻

代理模式

此模式用于构造具有解耦组件的分布式系统。

使用场景:消息代理软件,如Apache ActiveMQ,Apache Kafka,RabbitMQ和JBoss Messaging

点对点模式

在这种模式中,单个组件被称为对等点。对等点可以作为客户端,从其他对等点请求服务,作为服务器,为其他对等点提供服务。对等点可以充当客户端或服务器或两者的角色,并且可以随时间动态地更改其角色。

使用场景:

    • 像Gnutella和G2这样的文件共享网络
    • 多媒体协议,如P2PTV和PDTP
    • 像Spotify这样的专有多媒体应用程序

Jeff: 有点生僻

事件总线模式

类似于消息广播。

模型-视图-控制器模式

已阅。

黑板模式

已阅。

解释器模式

这个模式用于设计一个解释用专用语言编写的程序的组件。它主要指定如何评估程序的行数,即以特定的语言编写的句子或表达式。其基本思想是为每种语言的符号都有一个分类。

使用场景:

    • 数据库查询语言,比如SQL
    • 用于描述通信协议的语言

  • 每种体系架构模式的优缺点

名称 优点 缺点
分层模式 一个较低的层可以被不同的层所使用。层使标准化更容易,因为我们可以清楚地定义级别。可以在层内进行更改,而不会影响其他层。 不是普遍适用的。在某些情况下,某些层可能会被跳过。
客户端-服务器模式 很好地建立一组服务,用户可以请求他们的服务。 请求通常在服务器上的单独线程中处理。由于不同的客户端具有不同的表示,进程间通信会导致额外开销。
主从设备模式 准确性——将服务的执行委托给不同的从设备,具有不同的实现。 从设备是孤立的:没有共享的状态。主-从通信中的延迟可能是一个问题,例如在实时系统中。这种模式只能应用于可以分解的问题。
管道-过滤器模式 展示并发处理。当输入和输出由流组成时,过滤器在接收数据时开始计算。轻松添加过滤器,系统可以轻松扩展。过滤器可重复使用。 可以通过重新组合一组给定的过滤器来构建不同的管道。 效率受到最慢的过滤过程的限制。从一个过滤器移动到另一个过滤器时的数据转换开销。
代理模式 允许动态更改、添加、删除和重新定位对象,这使开发人员的发布变得透明。 要求对服务描述进行标准化。
点对点模式 支持分散式计算。对任何给定节点的故障处理具有强大的健壮性。在资源和计算能力方面具有很高的可扩展性。 服务质量没有保证,因为节点是自愿合作的。安全是很难得到保证的。性能取决于节点的数量。
事件总线模式 新的发布者、订阅者和连接可以很容易地添加。对高度分布式的应用程序有效。 可伸缩性可能是一个问题,因为所有消息都是通过同一事件总线进行的。
模型-视图-控制器模式 可以轻松地拥有同一个模型的多个视图,这些视图可以在运行时连接和断开。 增加复杂性。可能导致许多不必要的用户操作更新。
黑板模式 很容易添加新的应用程序。扩展数据空间的结构很简单。 修改数据空间的结构非常困难,因为所有应用程序都受到了影响。可能需要同步和访问控制。
解释器模式 高度动态的行为是可行的。对终端用户编程性提供好处。提高灵活性,因为替换一个解释程序很容易。 由于解释语言通常比编译后的语言慢,因此性能可能是一个问题。
 
 

微内核架构

可以理解为插件模式。
 

微服务架构

难点在于粒度的确定,分解项目后各个组件提供独立的服务。
那么问题来了,独立的服务怎么写?

微服务常常伴随的REST API:[Node.js] 08 - Web Server and REST API

 

[1] SOA和微服务架构的区别?

如果一句话来谈SOA和微服务的区别,即微服务不再强调传统SOA架构里面比较重的ESB企业服务总线,同时SOA的思想进入到单个业务系统内部实现真正的组件化。

ESB
企业服务总线,即ESB全称为Enterprise Service Bus,指的是传统中间件技术与XML、Web服务等技术结合的产物。ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。
面向服务的体系结构已经逐渐成为IT集成的主流技术。面向服务的体系结构(service-oriented architecture,SOA)是一种软件系统设计方法,通过已经发布的和可发现的接口为终端用户应用程序或其它服务提供服务。
作者:徐兵元

首先,可以肯定的是SOA和微服务的确是一脉相承的,大神Martin Fowler提出来这一概念可以说把SOA的理念继续升华,精进了一步。其核心思想是在应用开发领域,使用一系列微小服务来实现单个应用的方式途径,或者说微服务的目的是有效的拆分应用,实现敏捷开发和部署 ,可以是使用不同的编程语言编写。而SOA可能包含的意义更泛一些,更不准确一些。
其次,从实现方式上,两者都是中立性,语言无关,协议跨平台,相比SOA,微服务框架将能够带来更大的敏捷性,并为你构建应用提供更轻量级、更高效率的开发。而SOA更适合大型企业中的业务过程编排、应用集成。另外还有微服务甚至是去ESB、去中心化、分布式的,而SOA还是以ESB为核心,大量的WS标准实现。
再次,从服务粒度上,既然是微,必然微服务更倡导服务的细粒度,重用组合,甚至是每个操作(或方法)都是独立开发的服务,足够小到不能再进行拆分。而SOA没有这么极致的要求,只需要接口契约的规范化,内部实现可以更粗粒度,微服务更多为了可扩充性、负载均衡以及提高吞吐量而去分解应用,但同时也引发了打破数据模型以及维护一致性的问题。
最后,从部署方式上,这个是最大的不同,对比Monolithic(有人翻译为单体)的Java EE部署架构,通过展现层打包WARs,业务层划分到JARs最后部署为EAR一个大包,而微服务则打开了这个黑盒子,把应用拆分成为一个一个的单个服务,应用Docker技术,不依赖任何服务器和数据模型,是一个 全栈应用,可以通过自动化方式独立部署,每个服务运行在自己的进程中,通过轻量的通讯机制联系,经常是基于HTTP资源API,这些服务基于业务能力构建,能实现集中化管理(因为服务太多啦,不集中管理就无法DevOps啦)。
 

[2] 我所理解的SOA和微服务

微服务其实就是随着互联网的发展,复杂的平台、业务的出现,导致SOA架构向更细粒度、更通过化程度发展,就成了所谓的微服务了。以这种说法做为根据,我觉得SOA与微服务的区别在于如下几个方面:

  1. 微服务相比于SOA更加精细,微服务更多的以独立的进程的方式存在,互相之间并无影响;
  2. 微服务提供的接口方式更加通用化,例如HTTP RESTful方式,各种终端都可以调用,无关语言、平台限制;
  3. 微服务更倾向于分布式去中心化的部署方式,在互联网业务场景下更适合;

[3] 谁能用通俗的语言解释一下什么是 RPC 框架?

RPC就是要像调用本地的函数一样去调远程函数。

Netty框架不局限于RPC,更多的是作为一种网络协议的实现框架,比如HTTP,由于RPC需要高效的网络通信,就可能选择以Netty作为基础。

除了网络通信,RPC还需要有比较高效的序列化框架,以及一种寻址方式。

如果是带会话(状态)的RPC调用,还需要有会话和状态保持的功能。

Dubbo的网站架构发展图

  • 单一应用架构

    • 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
    • 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。
  • 垂直应用架构
    • 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
    • 此时,用于加速前端页面开发的 Web框架(MVC) 是关键。
  • 分布式服务架构
    • 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
    • 此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。
  • 流动计算架构
    • 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。
    • 此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。

平台随着业务的发展从 All in One 环境就可以满足业务需求(以Java来说,可能只是一两个war包就解决了);发展到需要拆分多个应用,并且采用MVC的方式分离前后端,加快开发效率;

在发展到服务越来越多,不得不将一些核心或共用的服务拆分出来,其实发展到此阶段,如果服务拆分的足够精细,并且独立运行,我觉得就可以将之理解为一个微服务了。

[Arch] 04. Software Architectural Patterns的更多相关文章

  1. [Arch] 01. Before Design Patterns - UML

    From: 史上最全设计模式导学目录 设计模式,这是软件设计过程中的一个环节. 在这个环节之上,需要overview的事业,就是UML,一种通用的建模语言. Ref: 软件设计之UML—UML的构成[ ...

  2. [Code::Blocks] Install wxWidgets & openCV

    The open source, cross platform, free C++ IDE. Code::Blocks is a free C++ IDE built to meet the most ...

  3. 本人SW知识体系导航 - Programming menu

    将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...

  4. [Code] 变态之人键合一

    目的也比较单纯,选一门语言,走向人键合一. 选了两本书作为操练场:<精通Python设计模式>.<Data Structure and Algorithm in Python> ...

  5. Architecture Patterns

    This chapter provides guidelines for using architecture patterns. Introduction Patterns for system a ...

  6. iOS Architecture Patterns

    By Bohdan Orlov on 21 Mar 2016 - 0 Comments iOS FYI: Slides from my presentation at NSLondon are ava ...

  7. Catalog of Patterns of Enterprise Application Architecture

    Catalog of Patterns of Enterprise Application Architecture Last Significant Update: January 2003 A s ...

  8. 微软职位内部推荐-Software Engineer II_VS

    微软近期Open的职位: Job Title: Software Engineer II Division: Visual Studio China – Developer Division Work ...

  9. JavaScript Patterns 1 Introduction

    1.1 Pattern "theme of recurring events or objects… it can be a template or model which can be u ...

随机推荐

  1. 十大要避免的Ext JS开发方法

    原文地址:http://www.sencha.com/blog/top-10-ext-js-development-practices-to-avoid/ 作者:Sean LanktreeSean i ...

  2. Android文档 - 账户管理器概述

    账户管理器概述 这个类提供了访问到 用户在线账户的集中式注册中心 的能力.用户为每账户输入一次 认证信息(credentials,包含用户名和密码),过过 点击一次(one-click)完成认证的方式 ...

  3. JQ 点击指定文本框显示div。点击其他区域隐藏DIV

    <input id="username" type="text" style="width:90%;margin-top: 40px;" ...

  4. IIS字体文件添加MIME映射

    在前端经常会做这样一件事情,页面会加载一些特殊的字体或者是图标文件,常用的比如:.woff.woff2..ttf..svg..otf..eot...如果没有添加MIME映射会报404的错误,IIS错误 ...

  5. C#注册表读写完整操作类

    1.注册表基项静态域 /// <summary> /// 注册表基项静态域 ///1.Registry.ClassesRoot 对应于HKEY_CLASSES_ROOT 主键 ///2.R ...

  6. Python __all__系统变量

    #__all__系统变量的使用 ''' __all__可以赋值一个字符串列表,列表中的元素表示外界调用该py文件可以使用的函数或者类 如果使用了__all__系统变量,并且调用该py文件使用的是fro ...

  7. CentOS执行ping命令报错 name or service not know

    在虚拟机上安装的CentOS,但是当执行ping命令的时候,提示name or service not known 解决方法如下: 1. 添加DNS服务器 vi /etc/resolv.conf 1 ...

  8. numpy的排序

  9. MBR:主引导记录:

    下面内容严重参考:百度百科: Main Boot Record)是位于磁盘最前边的一段引导(Loader)代码.它负责磁盘操作系统(DOS)对磁盘进行读写时分区合法性的判别.分区引导信息的定位,它由磁 ...

  10. 浅谈main(),int main(),void main(),int main(void)四者之间的区别

    1,main():相当于 int main() 2,int main():int 是main() 函数的返回类型.这表明main()函数返回的值是整数且授受任何数量的参数. 3,void main() ...