github欢迎star
https://github.com/transienth...
适配器模式
Adapter模式也被称为Wrapper模式,有以下两种:
-
类适配器(使用继承)
https://design-
实现目标接口,继承被适配类 - 对象适配器(使用委托)
继承目标类,依赖被适配类
参考http://blog.51cto.com/liuxp08...
package main
import (
"fmt"
)
func main() {
duck := &MallardDuck{}
turkey := &WildTurkey{}
turkeyAdapter := NewTurkeyAdapter(turkey)
fmt.Println("The Turkey says...")
turkey.gobble()
turkey.fly()
fmt.Println("The Duck says...")
duck.quack()
duck.fly()
fmt.Println("The Turkey Adapter says...")
turkeyAdapter.quack()
turkeyAdapter.fly()
}
type Duck interface {
quack()
fly()
}
type Turkey interface {
gobble()
fly()
}
type MallardDuck struct {
}
func (*MallardDuck) quack() {
fmt.Println("Quark...")
}
func (*MallardDuck) fly() {
fmt.Println("flying...")
}
type WildTurkey struct {
}
func (*WildTurkey) gobble() {
fmt.Println("Gobble...")
}
func (*WildTurkey) fly() {
fmt.Println("flying a short distance")
}
type TurkeyAdapter struct {
turkey Turkey
}
func NewTurkeyAdapter(turkey Turkey) *TurkeyAdapter {
return &TurkeyAdapter{turkey}
}
func (this *TurkeyAdapter) quack() {
this.turkey.gobble()
}
func (this *TurkeyAdapter) fly() {
for i := 0; i < 5; i++ {
this.turkey.fly()
}
}
适配器TurkeyAdpater,持有turkey Turkey,实现Duck接口。
代理模式
uml:
https://design-patterns.readt...
代理模式中的成员构成:
- Subject(主体)
- Proxy (代理人)
- RealSubject(实际的主体)
- Client (请求者)
代理的目的是在目标对象方法的基础上作增强,这种增强的本质通常就是对目标对象的方法进行拦截和过滤。
golang版的代理模式如下:
Subject
type Git interface {
Clone(url string) bool
}
RealSubject
type Github struct{}
func (p Github) Clone(url string) bool {
if strings.HasPrefix(url, "https") {
fmt.Println("clone from " + url)
return true
}
fmt.Println("failed to clone from " + url)
return false
}
Proxy
type GitBash struce {
//将持有被代理主体
GitCmd Git
}
func (p GitBash) Clone(url string) bool {
//实际上是被代理主体在执行动作
return p.GitCmd.Clone(url)
}
Client
此处client定义为一个coder
type Coder struct {}
func (p Coder) GetCode(url string) {
gitBash := GetGit()
if gitBash.Clone(url) {
fmt.Println("success...")
} else {
fmt.Println("failed...")
}
}
func main() {
coder := Coder{}
coder.GetCode("https://www.github.com")
}
装饰模式
uml
https://design-patterns.readt...
装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式相比生成子类更为灵活。
装饰模式是代理模式的一种特殊应用,两者的共同点是都具有相同的接口,不同点则是代理模式着重为代理过程的控制,而装饰模式则是对类的功能进行加强或减弱,它着重类的功能变化。
package main
import "fmt"
type Noddles interface {
Description() string
Price() float32
}
//普通拉面
type Ramen struct {
name string
price float32
}
func (p Ramen) Description() string {
return p.name
}
func (p Ramen) Price() float32 {
return p.price
}
//想吃鸡蛋拉面怎么办?
type Egg struct {
//多用组合,少用继承,何况golang没有继承
noddles Noddles
name string
price float32
}
func (p Egg) SetNoddles(noddles Noddles) {
p.noddles = noddles
}
func (p Egg) Description() string {
return p.noddles.Description() + " + " + p.name
}
func (p Egg) Price() float32 {
return p.noddles.Price() + p.price
}
//加个香肠吧!
type Sausage struct {
noddles Noddles
name string
price float32
}
func (p Sausage) SetNoddles(noddles Noddles) {
p.noddles = noddles
}
func (p Sausage) Description() string {
return p.noddles.Description() + " + " + p.name
}
func (p Sausage) Price() float32 {
return p.noddles.Price() + p.price
}
func main() {
ramen := Ramen{
name:"ramen",
price:8,
}
egg := Egg{
noddles:ramen,
name:"egg",
price:2,
}
egg2 := Egg{
noddles:egg,
name:"egg",
price:2,
}
sausage := Sausage{
noddles:egg,
name:"sausage",
price:2,
}
fmt.Println("客官,您的普通拉面来了。。。")
fmt.Println(ramen.Description())
fmt.Println(ramen.Price())
fmt.Println("客官,您的鸡蛋拉面来了。。。")
fmt.Println(egg.Description())
fmt.Println(egg.Price())
fmt.Println("客官,您的双蛋拉面来了。。。")
fmt.Println(egg2.Description())
fmt.Println(egg2.Price())
fmt.Println(sausage.Description())
fmt.Println(sausage.Price())
fmt.Println("客官,您的香肠拉面来了。。。")
}
外观模式
外观模式也叫做门面模式,要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
uml图
https://design-patterns.readt...
一个服务有若干个子服务,这种情况下,可以引入一个统一的gateway层作为外观模式,统一管理入口。
package main
import "fmt"
type Facade struct {
M Music
V Video
C Count
}
func (this *Facade) GetRecommandVideos() error {
this.V.GetVideos()
return nil
}
type Video struct {
vid int64
}
func (this *Video) GetVideos() error {
fmt.Println("get videos")
return nil
}
type Music struct {
}
func (this *Music) GetMusic() error {
fmt.Println("get music material")
return nil
}
type Count struct {
PraiseCnt int64
CommentCnt int64
CollectCnt int64
}
func (this *Count) GetCountById(id int64) (*Count, error) {
fmt.Println("get video counts")
return this, nil
}
func main() {
f := &Facade{}
f.GetRecommandVideos()
}
享元模式
package main
import (
"fmt"
"reflect"
)
type Coordinate struct {
x, y int
}
type ChessFlyWeight interface {
getColor() string
display(c Coordinate)
}
type ConcreteChess struct {
Color string
}
func (chess ConcreteChess) display(c Coordinate) {
fmt.Printf("棋子颜色:%s\n", chess.Color)
fmt.Printf("棋子位置:%d----%d\n", c.x, c.y)
}
func (chess ConcreteChess) getColor() string {
return chess.Color
}
type ChessFlyWeightFactory struct {
pool map[string]ChessFlyWeight
}
func (factory ChessFlyWeightFactory) getChess(color string) ChessFlyWeight {
chess := factory.pool[color];
if chess == nil {
chess = ConcreteChess{color}
factory.pool[color] = chess
}
return chess
}
func main() {
pool := make(map[string]ChessFlyWeight)
factory := ChessFlyWeightFactory{pool }
chess1 := factory.getChess("black")
chess2 := factory.getChess("black")
fmt.Println(reflect.DeepEqual(chess1, chess2))
c1 := Coordinate{1,2}
c2 := Coordinate{2, 4}
chess1.display(c1)
chess1.display(c2)
}
桥梁模式
package main
import (
"net/http"
"fmt"
)
//请求接口
type Request interface {
HttpRequest() (*http.Request, error)
}
type Client struct {
Client *http.Client
}
func (c *Client) Query(req Request) (resp *http.Response, err error) {
httpReq, _ := req.HttpRequest()
resp, err = c.Client.Do(httpReq)
return
}
//实现
type CdnRequest struct {
}
func (cdn *CdnRequest) HttpRequest() (*http.Request, error) {
return http.NewRequest("GET", "/cdn", nil)
}
//实现2
type LiveRequest struct {
}
func (cdn *LiveRequest) HttpRequest() (*http.Request, error) {
return http.NewRequest("GET", "/live", nil)
}
func TestBridge() {
client := &Client{http.DefaultClient}
cdnReq := &CdnRequest{}
fmt.Println(client.Query(cdnReq))
liveReq := &LiveRequest{}
fmt.Println(client.Query(liveReq))
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。