go 和 rust 设计模式对比 - 工厂模式 | 水木双

定义

工厂模式可分为三类:

  1. 简单工厂模式
  2. 工厂方法模式
  1. 抽象工厂模式

简单工厂模式

属于创建型模式,不属于 23 种 GOF 设计模式之一,由一个工厂对象决定创建出哪一种产品类实例,逻辑为定义一个工厂类,根据传入的参数不同返回不同的产品实例,被创建的实例具有共同的父类或接口。

工厂方法模式

跟简单工厂模式的区别就是,定义了一些工厂子类,每个工厂子类都可以创建相对应的产品类实例,而不用工厂父类去根据参数创建,一般在产品类比较多的情况下,不想太多复杂的逻辑封装在工厂父类里面,可以用这种模式。

抽象工厂模式

顾名思义,把工厂抽象出来,根据具体的业务需求组合工厂创建产品实例的逻辑,通常为创建多个产品实例类。抽象工厂一旦要增加创建产品实例的逻辑,就需要修改抽象工厂接口的具体产品组合逻辑,所以并不符合开闭原则,如果是需要频繁增加(修改)产品实例的话,要衡量是否采用这种模式

基本结构

工厂模式从源码上总的来说可以分为 4 部分:

抽象产品: 通过声明接口(特性),定义了产品的业务方法。

具体产品: 通过 implement 接口(特性),定义了业务方法的具体逻辑。

抽象工厂: 按照相应的业务逻辑,声明了创建产品对象的业务方法(多数为组合方式)。

具体工厂: 通过 implement 接口(特性),定义了创建产品对象的具体逻辑。

结构设计的关键点:

  • 产品只负责产品对象的创建,其他什么都不关心, 也与其他的产品不会产生任何业务逻辑上的关联
  • 工厂要根据具体的业务需求去决定是否需要抽象,不要为抽象而抽象,抽象出工厂是为了更优雅的源码结构

适用场景

  • 需要统一的逻辑来创建产品实例
  • 各种产品实例创建逻辑很接近
  • 不用关心产品实例的创建过程
  • 需要有统一的入口去联动产品的创建
  • 抽象工厂模式不符合开闭原则,故不适应于需要频繁增加(修改)产品的场景

如以上内容有不对之处请指导修正,谢谢。

范例代码

rust 示例 

/*
工厂方法模式
 */

trait Product {
  fn convert(&self, _: String) -> String;
}

trait Factory {
  fn create_product(&self) -> Box<dyn Product>;

  // 不直接实例化Product, 再执行convert, 而是把这个逻辑封装到一个方法里面,直接调用自身的方法
  fn convert(&self, s: String) -> String {
    self.create_product().convert(s)
  }
}

// ------------------------------------------------
struct ProductX;
impl Product for ProductX {
  fn convert(&self, s: String) -> String {
    println!("ProductX convert: {}", s.to_uppercase());     // 具体逻辑为转大写
    return s.to_uppercase()
  }
}

struct ProductY;
impl Product for ProductY {
  fn convert(&self, s: String) -> String {
    println!("ProductY convert: {}", s.to_lowercase());     // 具体逻辑为转小写
    return s.to_lowercase()
  }
}

// -------------------------------------------------
struct FactoryAll;
impl Factory for FactoryAll{
  fn create_product(&self) -> Box<dyn Product> {
    // Box::new(ProductX) as Box<dyn Product>      // factory for prtoduct X
    Box::new(ProductY) as Box<dyn Product>      // factory for prtoduct Y
  }
}

fn main() {
  let f = FactoryAll;
  println!("{}", f.convert("HaloKid".to_string()))
}

go 实例

package main

import (
  "log"
  "strings"
)
/*
工厂方法模式
 */

type Product interface {
  convert(s string)   string
}

type Factory interface {
  createProduct()   Product
  convert(s string)   string
}

// 函数是第一公民的原则,把convert的逻辑提取出来封装
// 因为interface不能定义逻辑
func convertWrap(p Product, s string) string {
  log.Printf("convertWrap: %s", s)
  return p.convert(s)
}

// ---------------------------------------
type ProductX struct {}

func (p ProductX) convert(s string) string {
  log.Printf("ProductX convert: %s", strings.ToUpper(s))
  return strings.ToUpper(s)
}

func newProductX() Product {    // 映射出ProductX的Product特性
  return ProductX{}
}

// --------------------------------------
type FacotryAll struct {}

func (f FacotryAll) convert(s string) string {
  return convertWrap(f.createProduct(), s)
}

func (f FacotryAll) createProduct() Product {
  return newProductX()
}

func NewFactoryAll() Factory {
  return FacotryAll{}
}

func main() {
  f := NewFactoryAll()
  log.Printf("%s",f.convert("HaloKid"))
}

go 和 rust 源码地址: https://github.com/halokid/rust-cookbook/tree/master/design_patterns/src/factory 

喜欢的麻烦start或者follow下,多谢。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值