Go语言学习13-常见软件架构的实现

Go语言学习13-常见软件架构的实现

架构模式

An architectural pattern is a general, reusable solution to a commonly occurring problem in software architectural within a given context. ——wikipedia

Pipe-Filter 架构

Pipe-Filter 模式
  • 非常适合于数据处理及数据分析系统

  • Filter 封装数据处理的功能

  • 松耦合: Filter只跟数据(格式) 耦合

  • Pipe用于连接 Filter 传递数据或者在异步处理过程中缓冲数据流

    进程内同步调用时, pipe 演变为数据在方法调用间传递

Filter和组合模式

示例
// filter.go
// Package pipefilter is to define the interfaces
// and the structures for pipe-filter style implementation
package pipefilter// Request is the input of the filter
type Request interface{}// Response is the output of the filter
type Response interface{}// Filter interface is the definition of the data processing components
// Pipe-Filter structure
type Filter interface {Process(data Request) (Response, error)
}// split_filter.go
package pipefilterimport ("errors""strings"
)var SplitFilterWrongFormatError = errors.New("input data should be string")type SplitFilter struct {delimiter string
}func NewSplitFilter(delimiter string) *SplitFilter {return &SplitFilter{delimiter}
}func (sf *SplitFilter) Process(data Request) (Response, error) {str, ok := data.(string) // 检查数据格式/类型, 是否可以处理if !ok {return nil, SplitFilterWrongFormatError}parts := strings.Split(str, sf.delimiter)return parts, nil
}// to_int_filter.go
package pipefilterimport ("errors""strconv"
)var ToIntFilterWrongFormatError = errors.New("input data should be []string")type ToIntFilter struct {
}func NewToIntFilter() *ToIntFilter {return &ToIntFilter{}
}func (tif *ToIntFilter) Process(data Request) (Response, error) {parts, ok := data.([]string)if !ok {return nil, ToIntFilterWrongFormatError}ret := []int{}for _, part := range parts {s, err := strconv.Atoi(part)if err != nil {return nil, err}ret = append(ret, s)}return ret, nil
}// sum_filter.go
package pipefilterimport "errors"var SumFilterWrongFormatError = errors.New("input data should be []int")type SumFilter struct {
}func NewSumFilter() *SumFilter {return &SumFilter{}
}func (sf *SumFilter) Process(data Request) (Response, error) {elems, ok := data.([]int)if !ok {return nil, SumFilterWrongFormatError}ret := 0for _, elem := range elems {ret += elem}return ret, nil
}// straight_pipeline.go
package pipefilter// StraightPipeline is composed of the filters, and the filters are piled as a straight line.
type StraightPipeline struct {Name    stringFilters *[]Filter
}// NewStraightPipeline create a new StraightPipelineWithWallTime
func NewStraightPipeline(name string, filters ...Filter) *StraightPipeline {return &StraightPipeline{Name:    name,Filters: &filters,}
}// Process is to process the coming data by the pipeline
func (f *StraightPipeline) Process(data Request) (Response, error) {var ret interface{}var err errorfor _, filter := range *f.Filters {ret, err = filter.Process(data)if err != nil {return ret, err}data = ret}return ret, err
}

Micro Kernel架构

  • 特点
    • 易于扩展
    • 错误隔离
    • 保持架构一致性
  • 要点
    • 内核包含公共流程或通用逻辑
    • 将可变或可扩展部分规划为扩展点
    • 抽象扩展点行为, 定义接口
    • 利用插件进行扩展
示例

package microkernelimport ("context""errors""fmt""strings""sync"
)const (Waiting = iotaRunning
)var WrongStateError = errors.New("can not take the operation in the current state")type CollectorsError struct {CollectorsErrors []error
}func (ce CollectorsError) Error() string {var strs []stringfor _, err := range ce.CollectorsErrors {strs = append(strs, err.Error())}return strings.Join(strs, ";")
}type Event struct {Source  stringContent string
}type EventReceiver interface {OnEvent(evt Event)
}type Collector interface {Init(evtReceiver EventReceiver) errorStart(agtCtx context.Context) errorStop() errorDestroy() error
}type Agent struct {collectors map[string]CollectorevtBuf     chan Eventcancel     context.CancelFuncctx        context.Contextstate      int
}func (agt *Agent) EventProcessGroutine() {var evtSeg [10]Eventfor {for i := 0; i < 10; i++ {select {case evtSeg[i] = <-agt.evtBuf:case <-agt.ctx.Done():return}}fmt.Println(evtSeg)}
}func NewAgent(sizeEvtBuf int) *Agent {agt := Agent{collectors: map[string]Collector{},evtBuf:     make(chan Event, sizeEvtBuf),state:      Waiting,}return &agt
}func (agt *Agent) RegisterCollector(name string, collector Collector) error {if agt.state != Waiting {return WrongStateError}agt.collectors[name] = collectorreturn collector.Init(agt)
}func (agt *Agent) startCollectors() error {var err errorvar errs CollectorsErrorvar mutex sync.Mutexfor name, collector := range agt.collectors {go func(name string, collector Collector, ctx context.Context) {defer func() {mutex.Unlock()}()err = collector.Start(ctx)mutex.Lock()if err != nil {errs.CollectorsErrors = append(errs.CollectorsErrors,errors.New(name+":"+err.Error()))}}(name, collector, agt.ctx)}if len(errs.CollectorsErrors) == 0 {return nil}return errs
}func (agt *Agent) stopCollectors() error {var err errorvar errs CollectorsErrorfor name, collector := range agt.collectors {if err = collector.Stop(); err != nil {errs.CollectorsErrors = append(errs.CollectorsErrors,errors.New(name+":"+err.Error()))}}if len(errs.CollectorsErrors) == 0 {return nil}return errs
}func (agt *Agent) destroyCollectors() error {var err errorvar errs CollectorsErrorfor name, collector := range agt.collectors {if err = collector.Destroy(); err != nil {errs.CollectorsErrors = append(errs.CollectorsErrors,errors.New(name+":"+err.Error()))}}if len(errs.CollectorsErrors) == 0 {return nil}return errs
}func (agt *Agent) Start() error {if agt.state != Waiting {return WrongStateError}agt.state = Runningagt.ctx, agt.cancel = context.WithCancel(context.Background())go agt.EventProcessGroutine()return agt.startCollectors()
}func (agt *Agent) Stop() error {if agt.state != Running {return WrongStateError}agt.state = Waitingagt.cancel()return agt.stopCollectors()
}func (agt *Agent) Destroy() error {if agt.state != Waiting {return WrongStateError}return agt.destroyCollectors()
}func (agt *Agent) OnEvent(evt Event) {agt.evtBuf <- evt
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/757129.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Qt学习笔记]Qt下使用Halcon实现采图时自动对焦的功能(Brenner梯度法)

目录 1、介绍2、实现方法2.1 算法实现过程2.2 模拟采集流程 3、总结4、代码展示 1、介绍 在机器视觉的开发中&#xff0c;现在有很多通过电机去做相机的聚焦调节&#xff0c;对比手工调节&#xff0c;自动调节效果更好&#xff0c;而且其也能满足设备自动的需求&#xff0c;尤…

HCIA ——VLAN实验

一 、 实验需求 1.PC1和PC3所在接口为access接口&#xff1b;属于vlan 2 PC2-4-5-6处于同一网段&#xff1b;其中PC2可以访问PC4-5-6 PC4可以访问PC5不能访问PC6 PC5不能访问PC6 3.PC1-PC3与PC2-4-5-6不在同一个网段 4.所有PC均使用DHCP获取IP地址&#xff0c;且PC1可以正常访问…

mysql之基本概念与安装

一 数据库的基本概念 1.1 数据 记录个体的信息 1.2 表 存放信息的集合&#xff0c;行于与列 1.3 数据库 数据库就是表的集合。它是以一定的组织方式存储的相互有关的数据集合 1.4 数据库管理系统 数据库管理系统&#xff08;DatabaseManagementSystem&#xff0c;DBMS&…

Flutter 初始WidgetState 简单应用案例分析

本系列文章主要整理Flutter的知识汇总&#xff0c;由浅入深&#xff0c;从Widget的搭建到其中的原理。本文还是围绕Widget在开发中应用和理解。 关于Flutter环境配置和首次创建可以参考前面文章。链接如下&#xff1a; Flutter 安装部署与认识Dart语言 Flutter 使用AndroidS…

MySQL 搭建双主复制服务 并 通过 HAProxy 负载均衡

一、MySQL 搭建双主复制高可用服务 在数据库管理中&#xff0c;数据的备份和同步是至关重要的环节&#xff0c;而双主复制&#xff08;Dual Master Replication&#xff09;作为一种高可用性和数据同步的解决方案&#xff0c;通过让两个数据库实例同时充当主服务器和从服务器&…

Tomcat(Win+Linux)安装教程

Windows环境安装 Tomcat安装及配置教程主要分为四步&#xff1a; 步骤一&#xff1a;确认自己是否已 安装JDK&#x1f50d; 步骤二&#xff1a;下载安装Tomcat 步骤三&#xff1a;Tomcat配置环境变量 步骤四&#xff1a;验证Tomcat配置是否成功 OK&#xff0c;我们开始&#x…

python 中 float 和 decimal 的区别

decimal --- 十进制定点和浮点运算 — Python 3.11.8 文档请参考官方说明文档&#xff1a; decimal --- 十进制定点和浮点运算 — Python 3.11.8 文档 举例&#xff1a; # 使用 Decimal 类型进行计算 from decimal import Decimaltotal_float 0.1 0.2 total_decimal Decim…

CMU 10-414/714: Deep Learning Systems --hw3

实现功能 在ndarray.py文件中完成一些python array操作 我们实现的NDArray底层存储就是一个一维向量&#xff0c;只不过会有一些额外的属性&#xff08;如shape、strides&#xff09;来表明这个flat array在维度上的分布。底层运算&#xff08;如加法、矩阵乘法&#xff09;都…

[LeetCode][LCR170]交易逆序对的总数

题目 LCR 170. 交易逆序对的总数 在股票交易中&#xff0c;如果前一天的股价高于后一天的股价&#xff0c;则可以认为存在一个「交易逆序对」。请设计一个程序&#xff0c;输入一段时间内的股票交易记录 record&#xff0c;返回其中存在的「交易逆序对」总数。 示例 1&#xf…

【VUE】前端阿里云OSS断点续传,分片上传

什么是OSS&#xff1a; 数据以对象&#xff08;Object&#xff09;的形式存储在OSS的存储空间&#xff08;Bucket &#xff09;中。如果要使用OSS存储数据&#xff0c;您需要先创建Bucket&#xff0c;并指定Bucket的地域、访问权限、存储类型等属性。创建Bucket后&#xff0c;您…

React - 实现菜单栏滚动

简介 本文将会基于react实现滚动菜单栏功能。 技术实现 实现效果 点击菜单&#xff0c;内容区域会自动滚动到对应卡片。内容区域滑动&#xff0c;指定菜单栏会被选中。 ScrollMenu.js import {useRef, useState} from "react"; import ./ScrollMenu.css;export co…

线程和进程的区别和联系

一、什么是进程 进程(Process), 是一个具有独立功能的程序关于某个数据集合的一次运行活动&#xff0c;是系统进行 【资源分配和调度】 的一个独立单位。 进程是【程序】的【一次执行】(是计算机中程序的执行过程&#xff0c;而不是计算机中的程序)进程是系统进行【资源分配和…

[LeetBook]【学习日记】排序算法——归并排序

主要思想 归并排序是一种分治算法&#xff0c;其排序过程包括分和治分是指将要排序的序列一分为二、二分为四&#xff0c;直到单个序列中只有一个数治是指在分完后&#xff0c;将每两个元素重新组合&#xff0c;四合为二、二合为一&#xff0c;最终完成排序 图片作者&#xf…

Gitlab部署及使用

1. 简介 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用 Git 作为代码管理工具&#xff0c;并在此基础上搭建起来的Web服务。Gitlab是目前被广泛使用的基于 git 的开源代码管理平台&#xff0c;基于Ruby on Rails构建&#xff0c;主要针对软件开发过程中产生的代码…

taro之Picker,PickerView基础用法

1.Picker 直接上代码 import Taro,{Component} from "tarojs/taro"; import {View,Picker} from tarojs/components import { AtIcon } from taro-ui import { putKey } from /src/utils/storage-utilsclass AgriculturePolicy extends Component{constructor (prop…

基于禁忌搜索算法的VRP问题求解matlab仿真,带GUI界面,可设置参数

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1车辆路径问题&#xff08;Vehicle Routing Problem, VRP&#xff09;概述 4.2 禁忌搜索算法&#xff08;Tabu Search, TS&#xff09;原理 5.完整程序 1.程序功能描述 基于禁忌搜索算法…

漫谈微服务网关

一、什么是服务网关 服务网关 路由转发 过滤器 1、路由转发&#xff1a;接收一切外界请求&#xff0c;转发到后端的微服务上去&#xff1b; 2、过滤器&#xff1a;在服务网关中可以完成一系列的横切功能&#xff0c;例如权限校验、限流以及监控等&#xff0c;这些都可以通过…

【Linux】Linux开发工具-vim / 编译器-gcc/g++ / 调试器-gdb / git操作 / 项目自动化构建工具-make/Makefile

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;Linux_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.在Linux写自己的第一个程序 1.1 nano指令 1.2 nano指令的使用 1.2.1 介绍 1.2.2 演示 1.2.2.1 创建.c文件 1.2.2.2 nano cod…

Java后端八股------设计模式

Coffee可以设计成接口。 b

EPSON XV4001BC陀螺仪传感器汽车导航系统的应用

近年来为了提高汽车应用系统的可靠性,传感器融合系统被越来越多的应用到汽车领域,如汽车导航系统中的行人检测和预碰撞警告等,通过提供精准的导航信息,为驾驶员提供更安全,更稳定,更舒适的出行体验,例如在行人检测系统中,只使用低成本的红外传感器不能检测到行人的实际位置,而利…