Kennem's Blog
  • 🏠主页
  • 🔍搜索
  • 📚文章
  • ⏱时间轴
  • 🔖标签
  • 🗂️分类
  • 🙋🏻‍♂️关于
主页 » 📚文章

💻技术

Go ——设计模式

Go ——设计模式 simple_factory 简单工厂 package test const ( APITypeHi = iota + 1 APITypeHello ) type Greeting interface { Say(msg string) string } func NewGreeting(t int) Greeting { if t == APITypeHi { return &Hi{} } else if t == APITypeHello { return &Hello{} } return nil } type Hi struct{} func (h *Hi) Say(msg string) string { return "Hi! " + msg } type Hello struct{} func (h *Hello) Say(msg string) string { return "Hello! " + msg } package test import "testing" func TestGreeting(t *testing.T) { tests := []struct { name string apiType int msg string expected string }{ {"HiType", APITypeHi, "2026", "Hi! 2026"}, {"HelloType", APITypeHello, "2026", "Hello! 2026"}, {"NilType", 999, "2026", ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { g := NewGreeting(tt.apiType) if g == nil { if tt.expected != "" { t.Errorf("NewGreeting(%d) returned nil, expected non-nil", tt.apiType) } return } out := g.Say(tt.msg) if out != tt.expected { t.Errorf("Say() = %q, want %q", out, tt.expected) } }) } } facade 装饰器 package test type API interface { Test() string } func NewAPI() API { return &apiImpl{ a: NewAImpl(), b: NewBImpl(), } } type apiImpl struct { a AModule b BModule } func (api *apiImpl) Test() string { // 把两部分结果拼接返回 return api.a.TestA() + api.b.TestB() } // --- AModule --- type AModule interface { TestA() string } type AImpl struct{} func NewAImpl() AModule { return &AImpl{} } func (a *AImpl) TestA() string { return "testA ... " } // --- BModule --- type BModule interface { TestB() string } type BImpl struct{} func NewBImpl() BModule { return &BImpl{} } func (b *BImpl) TestB() string { return "testB ... " } package test import "testing" func TestFacade(t *testing.T) { api := NewAPI() out := api.Test() expected := "testA ... testB ... " if out != expected { t.Errorf("API Test() = %q, want %q", out, expected) } } adapter 适配器 package test type Adapter interface { Request() string } func NewAdapter(adaptee Adaptee) Adapter { return &adapter{ adaptee: adaptee, } } type adapter struct { adaptee Adaptee } func (a *adapter) Request() string { return a.adaptee.SpecificRequest() } // --- Adaptee 接口与实现 --- type Adaptee interface { SpecificRequest() string } type adaptee struct{} func NewAdaptee() Adaptee { return &adaptee{} } func (a *adaptee) SpecificRequest() string { return "specific request called" } package test import "testing" func TestAdapter(t *testing.T) { adaptee := NewAdaptee() adapter := NewAdapter(adaptee) out := adapter.Request() expected := "specific request called" if out != expected { t.Errorf("Adapter Request() = %q, want %q", out, expected) } } singleton 单例设计模式 package test import "sync" type Singleton interface { Foo() } type singleton struct{} func (s *singleton) Foo() {} var ( once sync.Once instance Singleton ) func GetSingleton() Singleton { once.Do(func() { instance = &singleton{} }) return instance } package test import ( "sync" "testing" ) const goroutineCount = 1000 // 单线程测试 func TestSingletonSingleThread(t *testing.T) { a := GetSingleton() b := GetSingleton() if a != b { t.Fatalf("Singleton failed: a != b") } } // 并发测试 func TestSingletonConcurrent(t *testing.T) { start := make(chan struct{}) instances := [goroutineCount]Singleton{} wg := sync.WaitGroup{} wg.Add(goroutineCount) for i := 0; i < goroutineCount; i++ { go func(idx int) { <-start instances[idx] = GetSingleton() wg.Done() }(i) } // 同时启动所有 goroutine close(start) wg.Wait() // 验证所有实例都相等 for i := 0; i < goroutineCount-1; i++ { if instances[i] != instances[i+1] { t.Fatalf("Singleton failed: instances[%d] != instances[%d]", i, i+1) } } } factory_method 工厂方法 package test // Operator 接口 type Operator interface { SetA(int) SetB(int) Result() int } // 工厂接口 type OperatorFactory interface { Create() Operator } // OperatorBase 提供公共字段与方法 type OperatorBase struct { a, b int } func (o *OperatorBase) SetA(a int) { o.a = a } func (o *OperatorBase) SetB(b int) { o.b = b } // PlusOperator type PlusOperator struct{ *OperatorBase } func (p *PlusOperator) Result() int { return p.a + p.b } // PlusOperatorFactory type PlusOperatorFactory struct{} func (PlusOperatorFactory) Create() Operator { return &PlusOperator{&OperatorBase{}} } // MinusOperator type MinusOperator struct{ *OperatorBase } func (m *MinusOperator) Result() int { return m.a - m.b } // MinusOperatorFactory type MinusOperatorFactory struct{} func (MinusOperatorFactory) Create() Operator { return &MinusOperator{&OperatorBase{}} } package test import "testing" func TestOperatorFactory(t *testing.T) { tests := []struct { name string factory OperatorFactory a, b int expected int }{ {"Plus", &PlusOperatorFactory{}, 1001, 10, 1011}, {"Minus", &MinusOperatorFactory{}, 1001, 10, 991}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { op := tt.factory.Create() op.SetA(tt.a) op.SetB(tt.b) if got := op.Result(); got != tt.expected { t.Fatalf("expected %v, got %v", tt.expected, got) } }) } } abstract_factory 抽象工厂 package test // OrderMainDAO 为订单主记录 type OrderMainDAO interface { SaveOrderMain() string } // OrderDetailDAO 为订单详情纪录 type OrderDetailDAO interface { SaveOrderDetail() string } // DAOFactory DAO 抽象工厂接口 type DAOFactory interface { CreateOrderMainDAO() OrderMainDAO CreateOrderDetailDAO() OrderDetailDAO } // ------------------ RDB 实现 ------------------ type RDBMainDAO struct{} func (*RDBMainDAO) SaveOrderMain() string { return "rdb main save" } type RDBDetailDAO struct{} func (*RDBDetailDAO) SaveOrderDetail() string { return "rdb detail save" } type RDBDAOFactory struct{} func (*RDBDAOFactory) CreateOrderMainDAO() OrderMainDAO { return &RDBMainDAO{} } func (*RDBDAOFactory) CreateOrderDetailDAO() OrderDetailDAO { return &RDBDetailDAO{} } // ------------------ XML 实现 ------------------ type XMLMainDAO struct{} func (*XMLMainDAO) SaveOrderMain() string { return "xml main save" } type XMLDetailDAO struct{} func (*XMLDetailDAO) SaveOrderDetail() string { return "xml detail save" } type XMLDAOFactory struct{} func (*XMLDAOFactory) CreateOrderMainDAO() OrderMainDAO { return &XMLMainDAO{} } func (*XMLDAOFactory) CreateOrderDetailDAO() OrderDetailDAO { return &XMLDetailDAO{} } package test import "testing" // GetMainAndDetail 调用工厂生成 DAO 并返回结果 func GetMainAndDetail(factory DAOFactory) (mainResult, detailResult string) { mainResult = factory.CreateOrderMainDAO().SaveOrderMain() detailResult = factory.CreateOrderDetailDAO().SaveOrderDetail() return } func TestAbstractFactory(t *testing.T) { tests := []struct { name string factory DAOFactory expectedMain string expectedDetail string }{ {"RDBFactory", &RDBDAOFactory{}, "rdb main save", "rdb detail save"}, {"XMLFactory", &XMLDAOFactory{}, "xml main save", "xml detail save"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { mainResult, detailResult := GetMainAndDetail(tt.factory) if mainResult != tt.expectedMain { t.Errorf("mainResult = %q, want %q", mainResult, tt.expectedMain) } if detailResult != tt.expectedDetail { t.Errorf("detailResult = %q, want %q", detailResult, tt.expectedDetail) } }) } } builder 建造者 package test // Builder 是生成器接口 type Builder interface { Part1() Part2() Part3() } // Director 构建指挥者 type Director struct { builder Builder } // NewDirector ... func NewDirector(builder Builder) *Director { return &Director{builder: builder} } // Construct 构建产品 func (d *Director) Construct() { d.builder.Part1() d.builder.Part2() d.builder.Part3() } // ---------------- Builder1 ---------------- type Builder1 struct { result string } func (b *Builder1) Part1() { b.result += "1" } func (b *Builder1) Part2() { b.result += "2" } func (b *Builder1) Part3() { b.result += "3" } func (b *Builder1) GetResult() string { return b.result } // ---------------- Builder2 ---------------- type Builder2 struct { result int } func (b *Builder2) Part1() { b.result += 1 } func (b *Builder2) Part2() { b.result += 2 } func (b *Builder2) Part3() { b.result += 3 } func (b *Builder2) GetResult() int { return b.result } package test import "testing" func TestBuilder(t *testing.T) { tests := []struct { name string builder Builder expected interface{} getRes func() interface{} }{ { name: "Builder1", builder: &Builder1{}, expected: "123", getRes: func() interface{} { return (&Builder1{}).GetResult() }, }, { name: "Builder2", builder: &Builder2{}, expected: 6, getRes: func() interface{} { return (&Builder2{}).GetResult() }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { d := NewDirector(tt.builder) d.Construct() var actual interface{} switch b := tt.builder.(type) { case *Builder1: actual = b.GetResult() case *Builder2: actual = b.GetResult() default: t.Fatalf("unsupported builder type") } if actual != tt.expected { t.Fatalf("expected %v, got %v", tt.expected, actual) } }) } } prototype 原型模式 package test // Cloneable 是原型对象需要实现的接口 type Cloneable interface { Clone() Cloneable } type PrototypeManager struct { prototypes map[string]Cloneable } func NewPrototypeManager() *PrototypeManager { return &PrototypeManager{ prototypes: make(map[string]Cloneable), } } // Get 返回指定名称的原型克隆对象 func (p *PrototypeManager) Get(name string) Cloneable { proto, ok := p.prototypes[name] if !ok { return nil } return proto.Clone() } // Set 注册原型对象 func (p *PrototypeManager) Set(name string, prototype Cloneable) { p.prototypes[name] = prototype } package test import "testing" // Type1 原型类型1 type Type1 struct { Name string } func (t *Type1) Clone() Cloneable { tc := *t return &tc } // Type2 原型类型2 type Type2 struct { Name string } func (t *Type2) Clone() Cloneable { tc := *t return &tc } func setupManager() *PrototypeManager { manager := NewPrototypeManager() manager.Set("t1", &Type1{Name: "type1"}) manager.Set("t2", &Type2{Name: "type2"}) return manager } func TestPrototypeClone(t *testing.T) { manager := setupManager() tests := []struct { name string prototype string expected string typeAssert string // 用于类型断言检查 }{ {"Type1 Clone", "t1", "type1", "Type1"}, {"Type2 Clone", "t2", "type2", "Type2"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { obj := manager.Get(tt.prototype) if obj == nil { t.Fatalf("Get(%s) returned nil", tt.prototype) } // 验证克隆对象不是原对象 original := manager.prototypes[tt.prototype] if obj == original { t.Fatalf("Clone returned the same object as original") } // 类型断言并检查字段 switch tt.typeAssert { case "Type1": casted := obj.(*Type1) if casted.Name != tt.expected { t.Fatalf("expected %s, got %s", tt.expected, casted.Name) } case "Type2": casted := obj.(*Type2) if casted.Name != tt.expected { t.Fatalf("expected %s, got %s", tt.expected, casted.Name) } } }) } } proxy 代理 package test type Subject interface { Do() string } type RealSubject struct{} func (RealSubject) Do() string { return "real" } type Proxy struct { real Subject } func NewProxy(real Subject) Subject { return &Proxy{real: real} } func (p *Proxy) Do() string { res := "pre:" res += p.real.Do() res += ":after" return res } package test import "testing" func TestProxy(t *testing.T) { real := &RealSubject{} sub := NewProxy(real) res := sub.Do() if res != "pre:real:after" { t.Fatalf("expect pre:real:after, got %s", res) } } observer 观察者 package test type Subject struct { observers []Observer context string } func NewSubject() *Subject { return &Subject{ observers: make([]Observer, 0), } } type Observer interface { Update(*Subject) } func (s *Subject) Attach(o Observer) { s.observers = append(s.observers, o) } func (s *Subject) notify() { for _, o := range s.observers { o.Update(s) } } func (s *Subject) UpdateContext(context string) { s.context = context s.notify() } func (s *Subject) Context() string { return s.context } type Reader struct { name string received []string } func NewReader(name string) *Reader { return &Reader{ name: name, received: make([]string, 0), } } func (r *Reader) Update(s *Subject) { r.received = append(r.received, s.Context()) } func (r *Reader) Received() []string { return r.received } func (r *Reader) Name() string { return r.name } package test import "testing" func TestObserver(t *testing.T) { subject := NewSubject() r1 := NewReader("reader1") r2 := NewReader("reader2") r3 := NewReader("reader3") subject.Attach(r1) subject.Attach(r2) subject.Attach(r3) subject.UpdateContext("observer mode") readers := []*Reader{r1, r2, r3} for _, r := range readers { received := r.Received() if len(received) != 1 { t.Fatalf("%s expect 1 update got %d", r.Name(), len(received)) } if received[0] != "observer mode" { t.Fatalf("%s expect observer mode got %s", r.Name(), received[0]) } } }

2026-01-02 · 4 分钟 · 1948 字 · updated: 2026-01-02 · ShowGuan

gRpc(1)

gRpc(1) 1. gRPC 是什么 & 基本概念 gRPC 是 Google 开源的高性能 RPC 框架,基于 HTTP/2 和 Protobuf。简单理解: RPC(远程过程调用):像调用本地函数一样调用远程服务。 Protobuf(Protocol Buffers):一种高效、结构化的二进制序列化格式,用 .proto 文件定义消息和服务接口。 在一个典型 gRPC 项目中你会看到: ...

2025-11-23 · 7 分钟 · 3487 字 · updated: 2025-11-23 · ShowGuan

WSL Manager

WSL Manager wsl初始化 创建新用户 使用以下命令创建名为 zg 的新用户: sudo adduser zg 系统会提示你输入 新密码 和 确认密码。 接下来,你还会被要求填写一些额外信息(如全名、房间号等),这些可以按需填写,也可以直接按 Enter 跳过。 将用户添加到 sudo 组(可选) 如果你希望 zg 用户具有管理员权限,可以将其添加到 sudo 组: ...

2025-11-01 · 1 分钟 · 296 字 · updated: 2025-11-01 · ShowGuan

Wsl

Wsl 初始化 su 用户(WSL) WSL 默认未启用 root 密码,可直接使用 sudo 获得管理员权限。 方法 1:直接切到 root(推荐) sudo su # 或 sudo -i 方法 2:设置 root 密码(启用 su) sudo su passwd # 设置 root 密码 exit su # 输入新密码登录 root 方法 3:设置默认登录用户为 root 查看发行版名: ...

2025-10-23 · 1 分钟 · 248 字 · updated: 2025-10-23 · ShowGuan

Wsl Conda

Wsl Conda https://www.anaconda.com/docs/getting-started/miniconda/install wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash ~/Miniconda3-latest-Linux-x86_64.sh source ~/.bashrc

2025-10-23 · 1 分钟 · 9 字 · updated: 2025-11-09 · ShowGuan

Wsl Docker

Wsl Docker 安装 Docker(使用官方推荐方式) 1. 卸载旧版本(如果有) sudo apt-get remove -y docker docker-engine docker.io containerd runc || true 2. 安装依赖 sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release -y 3. 添加官方 GPG 密钥 sudo mkdir -p /usr/share/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-ce-archive-keyring.gpg 4. 添加 Docker 软件源(可切换为国内镜像) 官方源: ...

2025-10-23 · 5 分钟 · 2064 字 · updated: 2025-11-09 · ShowGuan

Wsl Java

Wsl Java 安装多个 Java 版本 使用 apt/yum 官方仓库(推荐) 以 Ubuntu 为例: sudo apt update sudo apt install openjdk-8-jdk openjdk-11-jdk openjdk-17-jdk -y 安装后,你的系统会有多个版本,例如: /usr/lib/jvm/java-8-openjdk-amd64 /usr/lib/jvm/java-11-openjdk-amd64 /usr/lib/jvm/java-17-openjdk-amd64 1、使用 update-alternatives(官方推荐切换方案) update-alternatives 是 Ubuntu/Debian 下管理多版本工具的标准方式。 ...

2025-10-23 · 1 分钟 · 320 字 · updated: 2025-11-09 · ShowGuan

Wsl Node

Wsl Node

2025-10-23 · 1 分钟 · 2 字 · updated: 2025-11-09 · ShowGuan

LeetCode周赛461(250803)

周赛250803 Q4. 三段式数组 II 1. 题目大意 给定一个整数数组 nums,请你在所有三段式子数组中找出最大和。 三段式子数组定义为一个连续子数组 nums[l...r],满足其中存在下标 l < p < q < r,使得这三个片段满足: ...

2025-08-03 · 2 分钟 · 720 字 · updated: 2025-08-03 · ShowGuan

absl

1. 简介 absl(Abseil Python Common Libraries) 是由 Google 开发的一套常用工具库,主要目的是为大型项目提供更稳定、更灵活、更高效的基础工具。它不仅在 Google 内部被广泛使用,在 TensorFlow 等开源项目中也有应用。absl 的设计理念是提供比 Python 标准库更高效、功能更强大的工具,帮助开发者解决日常开发中遇到的各种问题。 ...

2025-04-01 · 5 分钟 · 2250 字 · updated: 2025-04-01 · ShowGuan

20250329LeetCode双周赛 & 20250330LeetCode周赛

20250329LeetCode双周赛 & 20250330LeetCode周赛 T3 - 3500. 将数组分割为子数组的最小代价 1. 题目大意 给定两个等长的整数数组 nums 和 cost,以及一个整数 k。可以将 nums 分割为若干个连续的子数组,每个子数组的代价计算方式如下: ...

2025-03-30 · 8 分钟 · 3612 字 · updated: 2025-03-30 · ShowGuan

NumPy

NumPy 1. NumPy 简介 NumPy(Numerical Python)是 Python 进行科学计算的基础库,提供了高效的多维数组(ndarray)对象和丰富的数值计算函数。它在数据处理、机器学习、工程计算等领域都有广泛应用。 ...

2025-03-29 · 4 分钟 · 1859 字 · updated: 2025-03-29 · ShowGuan

Pandas

Pandas 1. pandas 简介 pandas 是 Python 中一个功能强大的数据分析和数据处理库,它提供了高性能、易用的数据结构(如 Series 和 DataFrame),方便进行数据的导入、清洗、转换、分析和可视化。pandas 广泛应用于金融、统计、科学计算等领域。 ...

2025-03-29 · 4 分钟 · 1854 字 · updated: 2025-03-29 · ShowGuan

Python包管理

Python包管理 pip 1. 检查是否已安装 在终端中运行以下命令,检查是否已安装 pip: pip --version 2. 安装 pip 如果未安装,可以根据操作系统选择以下安装方法: Windows 下载 get-pip.py。 运行以下命令安装: python get-pip.py macOS 使用 Homebrew 安装: ...

2025-03-22 · 3 分钟 · 1294 字 · updated: 2024-03-22 · ShowGuan

HTML 字体

HTML 字体 一. 通用字体家族 1.1 Serif(衬线字体) 常用示例:Times New Roman、Georgia、Garamond、Palatino Linotype、Book Antiqua ...

2025-03-16 · 9 分钟 · 4482 字 · updated: 2025-11-09 · ShowGuan
下一页  »
© 2026 Kennem's Blog · Powered by Hugo & PaperMod
👤 Visitors: 👀 Views: