structural.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // structural
  2. package pattern
  3. import (
  4. "fmt"
  5. )
  6. // 6. Adapter Pattern
  7. type LegacyPrinter interface {
  8. Print(s string) string
  9. }
  10. type MyLegacyPrinter struct{}
  11. func (p *MyLegacyPrinter) Print(s string) string {
  12. return fmt.Sprintf("Legacy: %s", s)
  13. }
  14. type ModernPrinter interface {
  15. PrintModern(s string) string
  16. }
  17. type PrinterAdapter struct {
  18. OldPrinter LegacyPrinter
  19. }
  20. func (p *PrinterAdapter) PrintModern(s string) string {
  21. return p.OldPrinter.Print(s)
  22. }
  23. // 7. Bridge Pattern
  24. type DrawAPI interface {
  25. DrawCircle(x, y, radius int)
  26. }
  27. type RedCircle struct{}
  28. type GreenCircle struct{}
  29. func (r *RedCircle) DrawCircle(x, y, radius int) {
  30. fmt.Printf("Drawing red circle at (%d,%d) radius %d\n", x, y, radius)
  31. }
  32. func (g *GreenCircle) DrawCircle(x, y, radius int) {
  33. fmt.Printf("Drawing green circle at (%d,%d) radius %d\n", x, y, radius)
  34. }
  35. type Circle struct {
  36. api DrawAPI
  37. X, Y, Radius int
  38. }
  39. func (c *Circle) SetAPI(api DrawAPI) { c.api = api }
  40. func (c *Circle) Draw() { c.api.DrawCircle(c.X, c.Y, c.Radius) }
  41. // 8. Composite Pattern
  42. type Component interface {
  43. Operation() string
  44. }
  45. type Leaf struct {
  46. Name string
  47. }
  48. func (l *Leaf) Operation() string { return l.Name }
  49. type Composite struct {
  50. children []Component
  51. }
  52. func (c *Composite) Add(child Component) {
  53. c.children = append(c.children, child)
  54. }
  55. func (c *Composite) Operation() string {
  56. result := "Branch("
  57. for i, child := range c.children {
  58. result += child.Operation()
  59. if i < len(c.children)-1 {
  60. result += ", "
  61. }
  62. }
  63. return result + ")"
  64. }
  65. // 9. Decorator Pattern
  66. type Coffee interface {
  67. Cost() int
  68. Description() string
  69. }
  70. type SimpleCoffee struct{}
  71. func (s *SimpleCoffee) Cost() int { return 5 }
  72. func (s *SimpleCoffee) Description() string { return "Simple coffee" }
  73. type MilkDecorator struct {
  74. Coffee Coffee
  75. }
  76. func (m *MilkDecorator) Cost() int { return m.Coffee.Cost() + 2 }
  77. func (m *MilkDecorator) Description() string { return m.Coffee.Description() + ", milk" }
  78. // 10. Facade Pattern
  79. type SubsystemA struct{}
  80. func (s *SubsystemA) OperationA() string { return "SubA" }
  81. type SubsystemB struct{}
  82. func (s *SubsystemB) OperationB() string { return "SubB" }
  83. type Facade struct {
  84. a *SubsystemA
  85. b *SubsystemB
  86. }
  87. func NewFacade() *Facade {
  88. return &Facade{&SubsystemA{}, &SubsystemB{}}
  89. }
  90. func (f *Facade) Operation() string {
  91. return f.a.OperationA() + " + " + f.b.OperationB()
  92. }
  93. // 11. Flyweight Pattern
  94. type CharacterFlyweight struct {
  95. Char rune
  96. }
  97. type CharacterFactory struct {
  98. chars map[rune]*CharacterFlyweight
  99. }
  100. func NewCharacterFactory() *CharacterFactory {
  101. return &CharacterFactory{chars: make(map[rune]*CharacterFlyweight)}
  102. }
  103. func (f *CharacterFactory) GetCharacter(c rune) *CharacterFlyweight {
  104. if _, ok := f.chars[c]; !ok {
  105. f.chars[c] = &CharacterFlyweight{Char: c}
  106. }
  107. return f.chars[c]
  108. }
  109. // 12. Proxy Pattern
  110. type Subject interface {
  111. Request() string
  112. }
  113. type RealSubject struct{}
  114. func (s *RealSubject) Request() string { return "RealSubject active" }
  115. type Proxy struct {
  116. realSubject *RealSubject
  117. }
  118. func (p *Proxy) Request() string {
  119. if p.realSubject == nil {
  120. p.realSubject = &RealSubject{}
  121. }
  122. return "Proxy: " + p.realSubject.Request()
  123. }