go in Design Patterns structural model

Facade pattern

1. Definitions: a subsystem communicate with the outside to be performed by a unified object to provide a consistent interface to the subsystem a set of interfaces.

Code Example 2:

// 定义对外API
type 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. Implementation steps

  • Definition of internal modules
  • External interfaces define the interaction and implementation

4. Scene

  • When you want to provide a simple interface to the subsystem may use a complex pattern appearance. The interface to meet the needs of most users, but users can also directly access subsystem over the appearance of the class.
  • There is a big client with multiple dependencies between subsystems. The introduction of class appearance with customers and other subsystems decoupled subsystems, subsystems can improve independence and portability.
  • In a hierarchical structure, you can define the appearance of the pattern of each layer of the inlet system, no direct link between the layers, and related by class appearance, to reduce the coupling between the layers.

The advantages

Customer shield subsystem components

Adapter mode

1. Definitions: a client interface into another interface desired.

Code Example 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. Implementation steps

  • Define the interface and implementation are adapted
  • Define the target interface and implementation, and implement the interface created by the interface is adapted

4. Scene

The system requires the use of an existing class, an interface, which does not meet the needs of the system.

The advantages

The target class and the class of decoupled fitter to reuse existing fitter adapter class class by introducing one, without modifying the existing code.

Decorative pattern

1. Definition: an object to dynamically add some additional responsibilities.

Code Example 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. Implementation steps

  • Custom Components
  • Defined decorative objects
  • Decorated object generation assembly

4. Scene

Without affecting other objects, dynamic, transparent way to add responsibilities to individual objects.

The advantages

Can be extended by means of a function of an object dynamic way, you can be selected at different decorative runtime configuration file, in order to achieve different behavior.

Flyweight

1. Definitions: Flyweight achieve the same or similar objects reuse by sharing technology.

Code Example 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 *ImageFlyweightFactory

func 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. Implementation steps

  • Flyweight defined objects
  • Defined Flyweight factory
  • Use plants to create Flyweight

4. Scene

  • A system with a large number of identical or similar objects, since the use of such a large number of objects, resulting in consuming a large amount of memory.
    Most state of the object can be outside of these states can be external incoming object.
  • Use Flyweight Flyweight need to maintain a storage object Flyweight pool, and this takes resources, therefore, it should be worth using Flyweight only when used repeatedly Flyweight objects.

The advantages

Flyweight peeled off from the duplicate data object is not changed and the plurality of instances required, a separate Flyweight, a plurality of shared objects, saving memory and reducing the number of objects.

Proxy mode

1. Definitions: an object to provide an agent, by the control proxy object reference to the original object.

Code Example 2:

package proxy

type 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. Implementation steps

  • Defined interfaces
  • The definition of an object that implements
  • Define a proxy object that implements

4. Scene

  • Controlled by the proxy object reference to the original object, a request to increase the injection hijacking

The advantages

Proxy mode to coordinate the caller and the caller, the coupling degree is reduced to some extent.

Bridge Mode

1. Definitions: an object to provide an agent, by the control proxy object reference to the original object.

Code Example 2:

package bridge

import "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. Implementation steps

4. Scene

The advantages

Guess you like

Origin blog.51cto.com/14378068/2411614