go中设计模式之结构型模式
// 定义对外APItype API interface { Test()}func NewAPI() API { return apiImpl{newMod()}}type apiImpl struct { m mod}func (a apiImpl) Test() { a.m.mod()}// 需要交互的内部模块type mod interface { mod()}func newMod() mod { return modImpl{}}type modImpl struct {}func (m modImpl) mod() {}
3. 实现步骤定义内部模块定义对外交互接口及实现4. 使用场景当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。5. 优点
对客户屏蔽子系统组件
适配器模式1. 定义: 将一个接口转换成客户希望的另一个接口。2. 代码示例:// 定义被适配的接口type Adapter interface { Request() string}type adaptee struct {}func (adaptee) Request() string {}func NewAdapter() Adapter { return &adaptee{}}// 定义目标接口type Target interface { TargetRequest() string}func New(adapter Adapter) Target { return &target{adapter}}type target struct { Adapter}func (t *target) TargetRequest() { t.Request()}
3. 实现步骤定义被适配的接口和实现定义目标接口和实现,并且实现接口由被适配接口创建4. 使用场景
系统需要使用现有的类,而这些类的接口不符合系统的需要。
5. 优点将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。
装饰模式1. 定义: 动态地给一个对象增加一些额外的职责。2. 代码示例:// 定义组件type Component interface { Calc() int}type ConcreteComponent struct{}func (*ConcreteComponent) Calc() int { return 0}// 定义装饰对象type MulDecorator struct { Component num int}func WarpMulDecorator(c Component, num int) Component { return &MulDecorator{ Component: c, num: num, }}func (d *MulDecorator) Calc() int { return d.Component.Calc() * d.num}type AddDecorator struct { Component num int}func WarpAddDecorator(c Component, num int) Component { return &AddDecorator{ Component: c, num: num, }}func (d *AddDecorator) Calc() int { return d.Component.Calc() + d.num}
3. 实现步骤定义组件定义装饰对象使用装饰对象生成组件4. 使用场景
在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
5. 优点可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。
享元模式1. 定义: 享元模式通过共享技术实现相同或相似对象的重用。2. 代码示例:// 定义享元对象type ImageFlyweight struct { data string}func NewImageFlyweight(filename string) *ImageFlyweight { // Load image file data := fmt.Sprintf("image data %s", filename) return &ImageFlyweight{ data: data, }}func (i *ImageFlyweight) Data() string { return i.data}// 定义享元对象工厂type ImageFlyweightFactory struct { maps map[string]*ImageFlyweight}var imageFactory *ImageFlyweightFactoryfunc GetImageFlyweightFactory() *ImageFlyweightFactory { if imageFactory == nil { imageFactory = &ImageFlyweightFactory{ maps: make(map[string]*ImageFlyweight), } } return imageFactory}func (f *ImageFlyweightFactory) Get(filename string) *ImageFlyweight { image := f.maps[filename] if image == nil { image = NewImageFlyweight(filename) f.maps[filename] = image } return image}type ImageViewer struct { *ImageFlyweight}func NewImageViewer(filename string) *ImageViewer { image := GetImageFlyweightFactory().Get(filename) return &ImageViewer{ ImageFlyweight: image, }}func (i *ImageViewer) Display() { fmt.Printf("Display: %s\n", i.Data())}
3. 实现步骤定义享元对象定义享元工厂使用享元工厂创建4. 使用场景一个系统有大量相同或者相似的对象,由于这类对象的大量使用,造成内存的大量耗费。
对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。使用享元模式需要维护一个存储享元对象的享元池,而这需要耗费资源,因此,应当在多次重复使用享元对象时才值得使用享元模式。5. 优点
享元模式从对象中剥离出不发生改变且多个实例需要的重复数据,独立出一个享元,使多个对象共享,从而节省内存以及减少对象数量。
代理模式1. 定义: 给某一个对象提供一个代理,并由代理对象控制对原对象的引用。2. 代码示例:package proxytype Subject interface { Do() string}type RealSubject struct{}func (RealSubject) Do() string { return "real"}type Proxy struct { real RealSubject}func (p Proxy) Do() string { var res string // 在调用真实对象之前的工作,检查缓存,判断权限,实例化真实对象等。。 res += "pre:" // 调用真实对象 res += p.real.Do() // 调用之后的操作,如缓存结果,对结果进行处理等。。 res += ":after" return res}
3. 实现步骤定义接口定义实现对象定义代理实现对象4. 使用场景并由代理对象控制对原对象的引用,增加请求注入劫持5. 优点
代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
桥接模式1. 定义: 给某一个对象提供一个代 理,并由代理对象控制对原对象的引用。2. 代码示例:package bridgeimport "fmt"type AbstractMessage interface { SendMessage(text, to string)}type MessageImplementer interface { Send(text, to string)}type MessageSMS struct{}func ViaSMS() MessageImplementer { return &MessageSMS{}}func (*MessageSMS) Send(text, to string) { fmt.Printf("send %s to %s via SMS", text, to)}type MessageEmail struct{}func ViaEmail() MessageImplementer { return &MessageEmail{}}func (*MessageEmail) Send(text, to string) { fmt.Printf("send %s to %s via Email", text, to)}type CommonMessage struct { method MessageImplementer}func NewCommonMessage(method MessageImplementer) *CommonMessage { return &CommonMessage{ method: method, }}func (m *CommonMessage) SendMessage(text, to string) { m.method.Send(text, to)}type UrgencyMessage struct { method MessageImplementer}func NewUrgencyMessage(method MessageImplementer) *UrgencyMessage { return &UrgencyMessage{ method: method, }}func (m *UrgencyMessage) SendMessage(text, to string) { m.method.Send(fmt.Sprintf("[Urgency] %s", text), to)}
3. 实现步骤4. 使用场景5. 优点
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。