Golang设计模式,装饰器模式

aside section ._1OhGeD · · 668 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

package decorator

import (
    "errors"
    "fmt"
)

type IngredientAdder interface {
    AddIngredient() (string, error)
}


type PizzaDecorator struct {
    Ingredient IngredientAdder
}

func (p *PizzaDecorator) AddIngredient() (string, error) {
    return "Pizza with the following ingredients:", nil
}


type Meat struct {
    Ingredient IngredientAdder
}


func (m *Meat) AddIngredient() (string, error) {
    if m.Ingredient == nil {
        return "", errors.New("An IngredientAdder is needed on the Ingredient field of the Meat") 
    }

    s, err := m.Ingredient.AddIngredient()
    if err != nil {
        return "", err
    }

    return fmt.Sprintf("%s %s", s, "meat"), nil
}


type Onion struct {
    Ingredient IngredientAdder
}


func (o *Onion) AddIngredient() (string, error) {
    if o.Ingredient == nil {
        return "", errors.New("An IngredientAdder is needed on the Ingredient field of the Onion")
    }

    s, err := o.Ingredient.AddIngredient()
    if err != nil {
        return "", err
    }

    return fmt.Sprintf("%s %s", s, "onion"), nil
}

装饰器模式测试

package decorator
import (
    "strings"
    "testing"
)



func TestPizzaDecorator_AddIngredient(t *testing.T) {
    pizza := &PizzaDecorator{}
    pizzaResult, err := pizza.AddIngredient()
    if err != nil {
        t.Error(err)
    }

    expectedText := "Pizza with the following ingredients:"

    if !strings.Contains(pizzaResult, expectedText) {
        t.Errorf("When calling the add ingredient of the pizza decorator it "+ 
        "must return the text %s, not '%s'", expectedText, pizzaResult)
    }
}


func TestOnion_AddIngredient(t *testing.T) {
    onion := &Onion{}
    onionResult, err := onion.AddIngredient()
    if err == nil {
        t.Errorf("When calling AddIngredient on the onion decorator without "+
                 "an IngredientAdder on its Ingredient field it must return an error, "+
                 "not a string with '%s'", onionResult)
    } 

    onion = &Onion{&PizzaDecorator{}}
    onionResult, err = onion.AddIngredient()
    if err != nil {
        t.Error(err)
    } 

    if !strings.Contains(onionResult, "onion") {
        t.Errorf("When calling the add ingredient of the onion decorator it "+
                 "must return a text with the word 'onion', not '%s'", onionResult)
    }
}


func TestMeat_AddIngredient(t *testing.T) {
    meat := &Meat{}
    meatResult, err := meat.AddIngredient()
    if err == nil {
        t.Errorf("When calling AddIngredient on the meat decorator without " +
                "an IngredientAdder on its Ingredient field must return an error, " +
                "not a string with '%s'", meatResult)
    }

    meat = &Meat{&PizzaDecorator{}}
    meatResult, err = meat.AddIngredient()
    if err != nil {
        t.Error(err)
    } 
    if !strings.Contains(meatResult, "meat") {
        t.Errorf("When calling the AddIngredient of the meat decorator it "+
                 "must return a text with the word 'meat', not '%s'", meatResult)
    }
}


func TestPizzaDecorator_FullStack(t *testing.T) {
    pizza := &Onion{&Meat{&PizzaDecorator{}}}
    pizzaResult, err := pizza.AddIngredient()
    if err != nil {
        t.Error(err)
    } 

    expectedText := "Pizza with the following ingredients: meat onion"
    if !strings.Contains(pizzaResult, expectedText) {
        t.Errorf("When asking for a pizza with onion and meat the returned "+
                "string must contain the text '%s' but '%s' didn't have it", expectedText,
            pizzaResult)
    }


}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:aside section ._1OhGeD

查看原文:Golang设计模式,装饰器模式

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

668 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传