前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单工厂模式在 CMP 虚拟机管理中应用

简单工厂模式在 CMP 虚拟机管理中应用

原创
作者头像
软件书桌
发布2024-04-30 15:05:43
820
发布2024-04-30 15:05:43

简单工厂模式不属于 GoF 23 个经典设计模式,但通常将它作为学习其它工厂模式的基础。

简单工厂模式(Simple Factory Pattern)

定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,属于类创建型模式。

简单工厂模式包含 3 个角色:

  1. Factory(工厂角色)
    1. 负责实现创建所有产品实例的内部逻辑。
    2. 提供了静态工厂方法 factoryMethod(),可以被外界直接调用,创建所需的产品对象。
  2. Product(抽象产品角色)
    1. 工厂类创建的所有对象的父类,封装了各种产品对象的公有方法。
  3. ConcreteProduct(具体产品角色)
    1. 简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。
    2. 每个具体产品角色都继承了抽象产品角色,需要实现的抽象产品中声明的抽象方法。

在简单工厂模式中,客户端通过工厂类来创建一个产品类的实例,而无须直接使用 new 关键字来创建对象,它是工厂模式家族中最简单的一员。

应用案例

云管平台(CMP)中需要对多种类型的虚拟机进行管理,例如:OpenStack、VMware、Aliyun 等。

可以使用工厂模式来创建不同类型的虚拟机对象。

  • 未使用设计的代码

缺点:

  1. 有 3 种类型的虚拟机,每种类型虚拟机的 create 和 delete 方法都不同,势必导致产生大量冗长的代码。
  2. 每种类型虚拟机操作的代码自身也会持续增长,增长的逻辑中不确定是每种类型虚拟机都有的,还是只有一种类型或者几种类型有这样的业务,会导致代码编写位置的混乱。
  3. 每增加一种类型的虚拟机,就需要新增一个 if,随着纳管类型的增加,代码将会持续大幅增长。
代码语言:javascript
复制
package main

import "fmt"

type VirtualMachine struct {
   name   string
   vmType string

   openstackField string
   vmwareField    string
   aliyunField    string
}

// 构造函数
func newVirtualMachine(name, vmType string) *VirtualMachine {

   if vmType == "OpenStack" {
      return &VirtualMachine{
         name:           name,
         vmType:         vmType,
         openstackField: "OpenStack Field",
      }
   } else if vmType == "VMware" {
      return &VirtualMachine{
         name:           name,
         vmType:         vmType,
         openstackField: "VMware Field",
      }
   } else if vmType == "Aliyun" {
      return &VirtualMachine{
         name:           name,
         vmType:         vmType,
         openstackField: "Aliyun Field",
      }
   }

   return nil
}

func (v VirtualMachine) create() {
   if v.vmType == "OpenStack" {
      fmt.Println("调用 OpenStack 接口 create 虚拟机 API")
      fmt.Println("... 大量业务逻辑代码 ...")
   } else if v.vmType == "VMware" {
      fmt.Println("调用 VMware 接口 create 虚拟机 API")
      fmt.Println("... 大量业务逻辑代码 ...")
   } else if v.vmType == "Aliyun" {
      fmt.Println("调用 Aliyun 接口 create 虚拟机 API")
      fmt.Println("... 大量业务逻辑代码 ...")
   }
}

func (v VirtualMachine) delete() {
   if v.vmType == "OpenStack" {
      fmt.Println("调用 OpenStack 接口 delete 虚拟机 API")
      fmt.Println("... 大量业务逻辑代码 ...")
   } else if v.vmType == "VMware" {
      fmt.Println("调用 VMware 接口 delete 虚拟机 API")
      fmt.Println("... 大量业务逻辑代码 ...")
   } else if v.vmType == "Aliyun" {
      fmt.Println("调用 Aliyun 接口 delete 虚拟机 API")
      fmt.Println("... 大量业务逻辑代码 ...")
   }
}

func main() {

   vm := newVirtualMachine("OpenStack", "OpenStack")
   vm.create()
   
}
  • 使用设计模式的代码

优点:

  1. 每种类型的虚拟机都有自己独立的属性,将这些独立属性放在各类虚拟机子类中,通用属性使用父类。
  2. 每种类型的虚拟机的操作都在各自方法中单独实现,避免耦合在一起相互影响。
代码语言:javascript
复制
package main

type VirtualMachineInterface interface {
   create()
   delete()
}

type VirtualMachine struct {
   name   string
   vmType string
}
代码语言:javascript
复制
package main

import "fmt"

type OpenStackVirtualMachine struct {
   VirtualMachine
   openStackField string
}

func (vm OpenStackVirtualMachine) create() {
   fmt.Println("调用 OpenStack 接口 create 虚拟机 API")
   fmt.Println("... 大量业务逻辑代码 ...")
}

func (vm OpenStackVirtualMachine) delete() {
   fmt.Println("调用 OpenStack 接口 delete 虚拟机 API")
   fmt.Println("... 大量业务逻辑代码 ...")
}
代码语言:javascript
复制
package main

import "fmt"

type VMwareVirtualMachine struct {
   vm          VirtualMachine
   vmwareField string
}

func (vm VMwareVirtualMachine) create() {
   fmt.Println("调用 VMware 接口 create 虚拟机 API")
   fmt.Println("... 大量业务逻辑代码 ...")
}

func (vm VMwareVirtualMachine) delete() {
   fmt.Println("调用 VMware 接口 delete 虚拟机 API")
   fmt.Println("... 大量业务逻辑代码 ...")
}
代码语言:javascript
复制
package main

import "fmt"

type AliyunVirtualMachine struct {
   vm          VirtualMachine
   aliyunField string
}

func (vm AliyunVirtualMachine) create() {
   fmt.Println("调用 Aliyun 接口 create 虚拟机 API")
   fmt.Println("... 大量业务逻辑代码 ...")
}

func (vm AliyunVirtualMachine) delete() {
   fmt.Println("调用 Aliyun 接口 delete 虚拟机 API")
   fmt.Println("... 大量业务逻辑代码 ...")
}
代码语言:javascript
复制
package main

type VirtualMachineFactory struct {
   vmType string
}

func (factory VirtualMachineFactory) create() VirtualMachineInterface {

   if factory.vmType == "OpenStack" {
      return new(OpenStackVirtualMachine)
   } else if factory.vmType == "VMware" {
      return new(VMwareVirtualMachine)
   } else if factory.vmType == "Aliyun" {
      return new(AliyunVirtualMachine)
   }

   return nil

}

func main() {

   factory := new(VirtualMachineFactory)

   factory.vmType = "OpenStack"
   vm := factory.create()
   vm.create()

   factory.vmType = "VMware"
   vm = factory.create()
   vm.create()

   factory.vmType = "Aliyun"
   vm = factory.create()
   vm.create()
}

总结

有些对象属于一类产品,但是属性不同,业务也不同。这种对象可以使用工厂模式来创建。

使用工厂模式的好处是,将对象的创建逻辑从代码主流程中分拆出去,这样主流程代码可读性更高,同时也可以减少逻辑因为同类对象代码耦合在一起引起的逻辑混乱。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简单工厂模式(Simple Factory Pattern)
  • 应用案例
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档