设计模式案例(一)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 设计模式案例(一)

系列文章目录


例如:第一章 设计模式案例


前言


上一篇文章介绍了常用的几种设计模式和常用场景,便于对设计模式加深理解,此文章主要讲解设计模式的案例。


一、适配器模式


case 包

代码如下(示例):

package _case
import "fmt"
func AdapterCase() {
  var cache StdCache
  redis := &Redis{data: map[string]string{}}
  cache = &RedisAdapter{redis: redis}
  cache.Set("key1", "value1")
  cache.Set("key2", "value2")
  cache.Set("key3", "value3")
  fmt.Println(cache.Get("key1"))
  fmt.Println(cache.Get("key2"))
  fmt.Println(cache.Get("key3"))
  mem := &MemCache{data: map[string]interface{}{}}
  cache = &MemCacheAdapter{mem: mem}
  cache.Set("k1", "v1")
  cache.Set("k2", "v2")
  cache.Set("k3", "v3")
  fmt.Println(cache.Get("k1"))
  fmt.Println(cache.Get("k2"))
  fmt.Println(cache.Get("k3"))
}
type Redis struct {
  data map[string]string
}
func (r *Redis) GetStr(key string) string {
  return r.data[key]
}
func (r *Redis) SetStr(key, value string) {
  r.data[key] = value
}
type MemCache struct {
  data map[string]interface{}
}
func (m *MemCache) GetItem(key string) interface{} {
  return m.data[key]
}
func (m *MemCache) SetItem(key string, value interface{}) {
  m.data[key] = value
}
// 定义标准缓存
type StdCache interface {
  Get(key string) string
  Set(key, value string)
}
// 定义Redis适配器
type RedisAdapter struct {
  redis *Redis
}
func (adapter *RedisAdapter) Get(key string) string {
  return adapter.redis.GetStr(key)
}
func (adapter *RedisAdapter) Set(key, value string) {
  adapter.redis.SetStr(key, value)
}
// 定义MemCache适配器
type MemCacheAdapter struct {
  mem *MemCache
}
func (adapter *MemCacheAdapter) Get(key string) string {
  return adapter.mem.GetItem(key).(string)
}
func (adapter *MemCacheAdapter) Set(key, value string) {
  adapter.mem.SetItem(key, value)
}

代码如下(示例):main

package main
import _case "adapter/case"
func main() {
  _case.AdapterCase()
}

二、观察者模式


case 包

代码如下(示例):case 包

package _case
import (
  "fmt"
)
func ObserverCase() {
  var ob Observer = &WatchConf{}
  var ob1 Observer = &WatchConf{}
  var ob2 Observer = &WatchConf{}
  var ob3 Observer = &WatchConf{}
  var pb Publisher = &Config{data: map[string]string{"host": "localhost", "port": "5051"}}
  //订阅
  pb.Subscribe(ob)
  pb.Subscribe(ob1)
  pb.Subscribe(ob2)
  pb.Subscribe(ob3)
  fmt.Println(pb)
  pb.UnSubscribe(ob1)
  fmt.Println(pb)
  conf := pb.(*Config) // 断言 判断pb 类型
  conf.data = map[string]string{"host": "127.0.0.1", "port": "9998"}
  pb.NotityObserver(conf.data)
  fmt.Println(pb)
}
// 定义观察者接口
type Observer interface {
  Update(data interface{})
}
// 定义发布者
type Publisher interface {
  //关注
  Subscribe(observer Observer)
  //取关
  UnSubscribe(observer Observer)
  //通知
  NotityObserver(data interface{})
}
// 定义具体发布者
type Config struct {
  data      map[string]string
  Observers []Observer
}
// 关注
func (c *Config) Subscribe(o Observer) {
  c.Observers = append(c.Observers, o)
}
// 取关
func (c *Config) UnSubscribe(o Observer) {
  for i, v := range c.Observers {
    if v == o {
      c.Observers = append(c.Observers[:i], c.Observers[i+1:]...)
      break
    }
  }
}
// 通知观察者
func (c *Config) NotityObserver(data interface{}) {
  for _, ob := range c.Observers {
    ob.Update(data)
  }
}
type WatchConf struct {
}
func (*WatchConf) Update(data interface{}) {
  fmt.Println("受到配置更新消息,更新配置为:", data)
}

代码如下(示例):main

package main
import _case "observer/case"
func main() {
  _case.ObserverCase()
}


三、代理模式


case 包

代码如下(示例):case 包

package _case
import "fmt"
func ProxyCase() {
  var cache Icache
  cache = &Cache{data: map[string]interface{}{}}
  proxy := NewProxy(cache)
  proxy.Set("key1", "value1")
  proxy.Set("key2", "value2")
  proxy.Set("key3", "value3")
  proxy.Set("key4", "value4")
  fmt.Println(proxy.Get("key1"))
  fmt.Println(proxy.Get("key2"))
  fmt.Println(proxy.Get("key3"))
  fmt.Println(proxy.Get("key4"))
}
type Icache interface {
  Get(key string) interface{}
  Set(key string, value interface{})
}
// 被代理对象(真实对象)
type Cache struct {
  data map[string]interface{}
}
func (c *Cache) Get(key string) interface{} {
  return c.data[key]
}
func (c *Cache) Set(key string, value interface{}) {
  c.data[key] = value
}
// 代理对象
type Proxy struct {
  cache Icache
}
func NewProxy(cache Icache) *Proxy {
  return &Proxy{
    cache: cache,
  }
}
func (p *Proxy) Get(key string) interface{} {
  // 此处可以增加访问控制逻辑等扩展功能
  return p.cache.Get(key)
}
func (p *Proxy) Set(key string, value interface{}) {
  // 此处可以增加访问控制逻辑等扩展功能
  p.cache.Set(key, value)
}

代码如下(示例):main

package main
import _case "design-pattern/proxy/case"
func main() {
  _case.ProxyCase()
}


总结


提示:这里对文章进行总结:

以上就是今天要讲的内容,本文暂时讲解了部分设计模式案例,后期会在此处持续更新

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
14天前
|
设计模式 存储 缓存
「全网最细 + 实战源码案例」设计模式——享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,旨在减少大量相似对象的内存消耗。通过分离对象的内部状态(可共享、不变)和外部状态(依赖环境、变化),它有效减少了内存使用。适用于存在大量相似对象且需节省内存的场景。模式优点包括节省内存和提高性能,但会增加系统复杂性。实现时需将对象成员变量拆分为内在和外在状态,并通过工厂类管理享元对象。
147 83
|
10天前
|
设计模式 存储 算法
「全网最细 + 实战源码案例」设计模式——命令模式
命令模式(Command Pattern)是一种行为型设计模式,将请求封装成独立对象,从而解耦请求方与接收方。其核心结构包括:Command(命令接口)、ConcreteCommand(具体命令)、Receiver(接收者)和Invoker(调用者)。通过这种方式,命令的执行、撤销、排队等操作更易扩展和灵活。 适用场景: 1. 参数化对象以操作。 2. 操作放入队列或远程执行。 3. 实现回滚功能。 4. 解耦调用者与接收者。 优点: - 遵循单一职责和开闭原则。 - 支持命令组合和延迟执行。 - 可实现撤销、恢复功能。 缺点: - 增加复杂性和类数量。
48 14
「全网最细 + 实战源码案例」设计模式——命令模式
|
10天前
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,允许将请求沿着处理者链进行发送。每个处理者可以处理请求或将其传递给下一个处理者,从而实现解耦和灵活性。其结构包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)。适用于不同方式处理不同种类请求、按顺序执行多个处理者、以及运行时改变处理者及其顺序的场景。典型应用包括日志处理、Java Web过滤器、权限认证等。
47 13
「全网最细 + 实战源码案例」设计模式——责任链模式
|
1月前
|
设计模式 缓存 应用服务中间件
「全网最细 + 实战源码案例」设计模式——外观模式
外观模式(Facade Pattern)是一种结构型设计模式,旨在为复杂的子系统提供一个统一且简化的接口。通过封装多个子系统的复杂性,外观模式使外部调用更加简单、易用。例如,在智能家居系统中,外观类可以同时控制空调、灯光和电视的开关,而用户只需发出一个指令即可。
140 69
|
12天前
|
设计模式 算法 开发者
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
47 8
「全网最细 + 实战源码案例」设计模式——策略模式
|
12天前
|
设计模式 SQL 算法
「全网最细 + 实战源码案例」设计模式——模板方法模式
模板方法模式是一种行为型设计模式,定义了算法的骨架并在父类中实现不变部分,将可变部分延迟到子类实现。通过这种方式,它避免了代码重复,提高了复用性和扩展性。具体步骤由抽象类定义,子类实现特定逻辑。适用于框架设计、工作流和相似算法结构的场景。优点包括代码复用和符合开闭原则,缺点是可能违反里氏替换原则且灵活性较低。
60 7
「全网最细 + 实战源码案例」设计模式——模板方法模式
|
24天前
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
86 40
|
18天前
|
设计模式 Java 开发者
「全网最细 + 实战源码案例」设计模式——适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,通过引入适配器类将一个类的接口转换为客户端期望的另一个接口,使原本因接口不兼容而无法协作的类能够协同工作。适配器模式分为类适配器和对象适配器两种,前者通过多重继承实现,后者通过组合方式实现,更常用。该模式适用于遗留系统改造、接口转换和第三方库集成等场景,能提高代码复用性和灵活性,但也可能增加代码复杂性和性能开销。
67 28
|
14天前
|
设计模式 存储 安全
「全网最细 + 实战源码案例」设计模式——组合模式
组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次结构。它允许客户端以一致的方式对待单个对象和对象集合,简化了复杂结构的处理。组合模式包含三个主要组件:抽象组件(Component)、叶子节点(Leaf)和组合节点(Composite)。通过这种模式,客户端可以统一处理简单元素和复杂元素,而无需关心其内部结构。适用于需要实现树状对象结构或希望以相同方式处理简单和复杂元素的场景。优点包括支持树形结构、透明性和遵循开闭原则;缺点是可能引入不必要的复杂性和过度抽象。
72 22
|
18天前
|
设计模式 缓存 Java
「全网最细 + 实战源码案例」设计模式——代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,通过代理对象控制对目标对象的访问并添加额外功能。它分为静态代理和动态代理,后者包括JDK动态代理和CGLIB动态代理。JDK动态代理基于接口反射生成代理类,而CGLIB通过继承目标类生成子类。代理模式适用于延迟初始化、访问控制、远程服务、日志记录和缓存等场景,优点是职责分离、符合开闭原则和提高安全性,缺点是增加系统复杂性。
69 25

热门文章

最新文章