├── index.go ├── src ├── prototype │ ├── clone.go │ └── honorGuard.go ├── visitor │ ├── visitor.go │ ├── printer.go │ ├── scanner.go │ └── mall.go ├── iterator │ ├── iterator.go │ ├── horses.go │ └── soldiers.go ├── adapter │ ├── mute.go │ └── talker.go ├── bridge │ ├── pen.go │ └── paper.go ├── decorator │ ├── gift.go │ └── pack.go ├── builder │ ├── building.go │ └── style.go ├── facade │ ├── coffee.go │ └── steps.go ├── interpreter │ ├── context.go │ └── interpreter.go ├── proxy │ ├── letter.go │ └── postman.go ├── mediator │ ├── country.go │ └── unitedNations.go ├── flyweight │ └── tree.go ├── command │ ├── soldier.go │ └── command.go ├── singleton │ └── instance.go ├── strategy │ ├── calculator.go │ └── algs.go ├── observer │ ├── reporter.go │ └── news.go ├── memento │ ├── timeController.go │ └── person.go ├── template │ ├── msg.go │ └── method.go ├── chainOfResponsibility │ └── auditor.go ├── state │ ├── fruit.go │ └── stage.go ├── composite │ └── soldier.go └── factory │ ├── shoesFactory.go │ └── shoes.go ├── java └── src │ ├── pattern │ ├── strategy │ │ ├── Alg.java │ │ ├── Bubble.java │ │ └── QuickSort.java │ ├── decorator │ │ ├── Goods.java │ │ ├── Toy.java │ │ └── Pack.java │ ├── factory │ │ ├── SimpleFactory.java │ │ ├── AbstractFactory.java │ │ └── Shoe.java │ ├── adapter │ │ ├── DeafMan.java │ │ ├── SpeakAdapter.java │ │ └── NormalPerson.java │ ├── observer │ │ ├── Reporter.java │ │ └── TvStation.java │ ├── command │ │ ├── Soldier.java │ │ └── Order.java │ └── singleton │ │ └── Redis.java │ ├── Singleton.java │ ├── Strategy.java │ ├── Command.java │ ├── Decorator.java │ ├── Factory.java │ ├── Adapter.java │ └── Observer.java ├── facade.go ├── proxy.go ├── adapter.go ├── singleton.go ├── strategy.go ├── bridge.go ├── state.go ├── prototype.go ├── template.go ├── decorator.go ├── factory.go ├── memento.go ├── interpreter.go ├── chainOfResponsibility.go ├── mediator.go ├── observer.go ├── flyweight.go ├── iterator.go ├── visitor.go ├── command.go ├── composite.go └── README.md /index.go: -------------------------------------------------------------------------------- 1 | package main 2 | -------------------------------------------------------------------------------- /src/prototype/clone.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | type cloneable interface { 4 | Clone() cloneable 5 | } 6 | -------------------------------------------------------------------------------- /src/visitor/visitor.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | type visitor interface { 4 | visitGoods(cart *shoppingCart) string 5 | } 6 | -------------------------------------------------------------------------------- /java/src/pattern/strategy/Alg.java: -------------------------------------------------------------------------------- 1 | package pattern.strategy; 2 | 3 | public interface Alg { 4 | public abstract void cal(); 5 | } 6 | -------------------------------------------------------------------------------- /src/iterator/iterator.go: -------------------------------------------------------------------------------- 1 | package iterator 2 | 3 | type Iterator interface { 4 | Count() int 5 | Next() string 6 | Remove() 7 | } 8 | -------------------------------------------------------------------------------- /java/src/pattern/decorator/Goods.java: -------------------------------------------------------------------------------- 1 | package pattern.decorator; 2 | 3 | public abstract class Goods { 4 | public abstract String sold(); 5 | } 6 | -------------------------------------------------------------------------------- /facade.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "facade" 4 | 5 | func main() { 6 | coffee := facade.NewCoffee() 7 | coffee.Brew() 8 | // water boiled; 9 | // coffee bean grind; 10 | // coffee is done! 11 | } 12 | -------------------------------------------------------------------------------- /java/src/pattern/factory/SimpleFactory.java: -------------------------------------------------------------------------------- 1 | package pattern.factory; 2 | 3 | public class SimpleFactory { 4 | public Shoe product(String type, String brand) { 5 | return new Shoe(type, brand); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /java/src/pattern/strategy/Bubble.java: -------------------------------------------------------------------------------- 1 | package pattern.strategy; 2 | 3 | public class Bubble implements Alg { 4 | @Override 5 | public void cal() { 6 | System.out.println("use bubble sort!"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /java/src/pattern/strategy/QuickSort.java: -------------------------------------------------------------------------------- 1 | package pattern.strategy; 2 | 3 | public class QuickSort implements Alg { 4 | @Override 5 | public void cal() { 6 | System.out.println("use quick sort!"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /proxy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "proxy" 4 | 5 | func main() { 6 | postman := proxy.NewLazyPostman() 7 | postman.RequestLetter() // I am try my best to get the reply letter. 8 | postman.DemandLetter() // The content is:I love you, too. 9 | } 10 | -------------------------------------------------------------------------------- /src/adapter/mute.go: -------------------------------------------------------------------------------- 1 | package adapter 2 | 3 | import "fmt" 4 | 5 | type Mute struct { 6 | Word string 7 | } 8 | 9 | type NoteBook struct { 10 | User Mute 11 | } 12 | 13 | func (notebook NoteBook) Express() { 14 | fmt.Println(notebook.User.Word) 15 | } 16 | -------------------------------------------------------------------------------- /src/adapter/talker.go: -------------------------------------------------------------------------------- 1 | package adapter 2 | 3 | import "fmt" 4 | 5 | type Talker interface { 6 | Express(word string) 7 | } 8 | 9 | type Person struct { 10 | Word string 11 | } 12 | 13 | func (person Person) Express() { 14 | fmt.Println(person.Word) 15 | } 16 | -------------------------------------------------------------------------------- /adapter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "adapter" 4 | 5 | func main() { 6 | zhangsan := adapter.Person{"hello"} 7 | zhangsan.Express() // hello 8 | 9 | lisi := adapter.Mute{"I want to express!"} 10 | notebook := adapter.NoteBook{lisi} 11 | notebook.Express() // I want to express! 12 | } 13 | -------------------------------------------------------------------------------- /java/src/Singleton.java: -------------------------------------------------------------------------------- 1 | import pattern.singleton.Redis; 2 | import redis.clients.jedis.Jedis; 3 | 4 | public class Singleton { 5 | public static void main(String[] argv) { 6 | Jedis client = Redis.getInstance("localhost", 6379); 7 | client.set("test", "hello"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/bridge/pen.go: -------------------------------------------------------------------------------- 1 | package bridge 2 | 3 | type pen interface { 4 | write() string 5 | } 6 | 7 | type Pencil struct { 8 | } 9 | 10 | func (Pencil) write() string { 11 | return "pencil" 12 | } 13 | 14 | type BallPen struct { 15 | } 16 | 17 | func (BallPen) write() string { 18 | return "ballPen" 19 | } 20 | -------------------------------------------------------------------------------- /java/src/pattern/decorator/Toy.java: -------------------------------------------------------------------------------- 1 | package pattern.decorator; 2 | 3 | public class Toy extends Goods { 4 | private String name; 5 | 6 | public Toy(String name) { 7 | this.name = name; 8 | } 9 | 10 | @Override 11 | public String sold() { 12 | return this.name; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /singleton.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "singleton" 6 | ) 7 | 8 | func main() { 9 | object1 := singleton.GetInstance() 10 | fmt.Println(object1.GetName()) // test1 11 | 12 | object2 := singleton.GetInstance() 13 | object2.SetName("test2") 14 | fmt.Println(object2.GetName()) // test2 15 | } 16 | -------------------------------------------------------------------------------- /strategy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "strategy" 4 | 5 | func main() { 6 | calculator := strategy.NewCalculator() 7 | calculator.Cal() // I am using util bubble sort 8 | 9 | quick_sort := strategy.NewQuickSort() 10 | calculator.ChangeAlg(quick_sort) 11 | calculator.Cal() // I am using util quick sort 12 | } 13 | -------------------------------------------------------------------------------- /java/src/pattern/adapter/DeafMan.java: -------------------------------------------------------------------------------- 1 | package pattern.adapter; 2 | 3 | public class DeafMan { 4 | private String name; 5 | 6 | public DeafMan(String name) { 7 | this.name = name; 8 | } 9 | 10 | public String write(String words) { 11 | return name + " speak:" + words; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/decorator/gift.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | type Goods interface { 4 | GetDesc() string 5 | } 6 | 7 | type gift struct { 8 | desc string 9 | } 10 | 11 | func NewGift(name string) gift { 12 | gift := gift{name} 13 | return gift 14 | } 15 | 16 | func (gift gift) GetDesc() string { 17 | return gift.desc 18 | } 19 | -------------------------------------------------------------------------------- /java/src/pattern/adapter/SpeakAdapter.java: -------------------------------------------------------------------------------- 1 | package pattern.adapter; 2 | 3 | public class SpeakAdapter { 4 | private DeafMan man; 5 | 6 | public void setMan(DeafMan man) { 7 | this.man = man; 8 | } 9 | 10 | public void speak(String words) { 11 | System.out.println(this.man.write(words)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /java/src/pattern/adapter/NormalPerson.java: -------------------------------------------------------------------------------- 1 | package pattern.adapter; 2 | 3 | public class NormalPerson { 4 | private String name; 5 | 6 | public NormalPerson(String name) { 7 | this.name = name; 8 | } 9 | 10 | public void speak(String words) { 11 | System.out.println(name + " speak:" + words); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /java/src/pattern/factory/AbstractFactory.java: -------------------------------------------------------------------------------- 1 | package pattern.factory; 2 | 3 | public class AbstractFactory { 4 | private String brand; 5 | 6 | public AbstractFactory(String brand) { 7 | this.brand = brand; 8 | } 9 | 10 | public Shoe product(String type) { 11 | return new Shoe(type, this.brand); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /bridge.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "bridge" 4 | 5 | func main() { 6 | pencil := bridge.Pencil{} 7 | ball_pen := bridge.BallPen{} 8 | 9 | red_paper := bridge.RedPaper{ball_pen} 10 | red_paper.Paint() // ballPen write on red paper! 11 | 12 | blue_paper := bridge.BluePaper{pencil} 13 | blue_paper.Paint() // pencil write on blue paper! 14 | } 15 | -------------------------------------------------------------------------------- /java/src/pattern/observer/Reporter.java: -------------------------------------------------------------------------------- 1 | package pattern.observer; 2 | 3 | public class Reporter { 4 | private String name; 5 | 6 | public Reporter(String name) { 7 | this.name = name; 8 | } 9 | 10 | public void notified(String event) { 11 | System.out.println(this.name + " report a news: " + event); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/builder/building.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | import "fmt" 4 | 5 | type builder struct { 6 | style 7 | } 8 | 9 | func (builder builder) Build() { 10 | fmt.Println("A building with " + builder.roof() + "," + builder.gate()) 11 | } 12 | 13 | func NewBuilder(style style) builder { 14 | building := builder{style: style} 15 | 16 | return building 17 | } 18 | -------------------------------------------------------------------------------- /src/decorator/pack.go: -------------------------------------------------------------------------------- 1 | package decorator 2 | 3 | type pack struct { 4 | desc string 5 | gift Goods 6 | } 7 | 8 | func NewPack(gift Goods, pack_desc string) pack { 9 | pack := pack{desc: pack_desc, gift: gift} 10 | return pack 11 | } 12 | 13 | func (pack pack) GetDesc() string { 14 | return pack.gift.GetDesc() + ", with " + pack.desc + " packed" 15 | } 16 | -------------------------------------------------------------------------------- /src/facade/coffee.go: -------------------------------------------------------------------------------- 1 | package facade 2 | 3 | type coffee struct { 4 | } 5 | 6 | func (coffee) Brew() { 7 | water := water{} 8 | water.boil() 9 | 10 | coffee_bean := coffeeBean{} 11 | coffee_bean.grind() 12 | 13 | coffee_powder := coffeePowder{} 14 | coffee_powder.brew() 15 | } 16 | 17 | func NewCoffee() coffee { 18 | coffee := coffee{} 19 | return coffee 20 | } 21 | -------------------------------------------------------------------------------- /src/visitor/printer.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | type printer struct { 4 | } 5 | 6 | func (printer printer) VisitGoods(cart *shoppingCart) string { 7 | names := "" 8 | for _, goods := range cart.bought { 9 | names += goods.name + " " 10 | } 11 | 12 | return names 13 | } 14 | 15 | func NewPrinter() *printer { 16 | printer := &printer{} 17 | 18 | return printer 19 | } 20 | -------------------------------------------------------------------------------- /src/interpreter/context.go: -------------------------------------------------------------------------------- 1 | package interpreter 2 | 3 | type context struct { 4 | args map[string]expression 5 | } 6 | 7 | func (context *context) AddItem(key string, val expression) { 8 | context.args[key] = val 9 | } 10 | 11 | func NewContext() *context { 12 | args := make(map[string]expression) // map必须初始化后才能添加值 13 | context := &context{args} 14 | 15 | return context 16 | } 17 | -------------------------------------------------------------------------------- /java/src/Strategy.java: -------------------------------------------------------------------------------- 1 | import pattern.strategy.*; 2 | 3 | public class Strategy { 4 | public static void main(String[] args) { 5 | Alg bubble = new Bubble(); 6 | Alg quickSort = new QuickSort(); 7 | 8 | Strategy.sort(bubble); 9 | Strategy.sort(quickSort); 10 | } 11 | 12 | private static void sort(Alg alg) { 13 | alg.cal(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/src/pattern/factory/Shoe.java: -------------------------------------------------------------------------------- 1 | package pattern.factory; 2 | 3 | public class Shoe { 4 | private String type; 5 | private String brand; 6 | 7 | public Shoe(String type, String brand) { 8 | this.type = type; 9 | this.brand = brand; 10 | } 11 | 12 | public String getDetail() { 13 | return "a " + this.brand + " " + this.type + " shoe."; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/proxy/letter.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import "fmt" 4 | 5 | type letterContent interface { 6 | get() 7 | } 8 | 9 | type realContent struct { 10 | } 11 | 12 | func (realContent) get() { 13 | fmt.Println("The content is:I love you, too.") 14 | } 15 | 16 | type tempContent struct { 17 | } 18 | 19 | func (tempContent) get() { 20 | fmt.Println("I am try my best to get the reply letter.") 21 | } 22 | -------------------------------------------------------------------------------- /state.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "state" 4 | 5 | func main() { 6 | fruit := state.NewFruit() 7 | fruit.Harvest() // The plant is just planted! 8 | fruit.Water() // The plant is growing! 9 | fruit.Harvest() // The plant is blooming, don't do that! 10 | fruit.Water() // The plant is ripping! 11 | fruit.Water() // The plant don't need water! 12 | fruit.Harvest() // You got lots of fruits! 13 | } 14 | -------------------------------------------------------------------------------- /prototype.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "prototype" 6 | ) 7 | 8 | func main() { 9 | guard_sample := prototype.NewhonorGuard(18, 180, 72, "m") 10 | 11 | zhangsan := guard_sample.Clone() 12 | zhangsan.SetName("zhangsan") 13 | fmt.Println(zhangsan) // &{18 180 72 m zhangsan} 14 | 15 | lisi := guard_sample.Clone() 16 | lisi.SetName("lisi") 17 | fmt.Println(lisi) // &{18 180 72 m lisi} 18 | } 19 | -------------------------------------------------------------------------------- /src/facade/steps.go: -------------------------------------------------------------------------------- 1 | package facade 2 | 3 | import "fmt" 4 | 5 | type water struct { 6 | } 7 | 8 | func (water) boil() { 9 | fmt.Println("water boiled;") 10 | } 11 | 12 | type coffeeBean struct { 13 | } 14 | 15 | func (coffeeBean) grind() { 16 | fmt.Println("coffee bean grind;") 17 | } 18 | 19 | type coffeePowder struct { 20 | } 21 | 22 | func (coffeePowder) brew() { 23 | fmt.Println("coffee is done!") 24 | } 25 | -------------------------------------------------------------------------------- /src/visitor/scanner.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | import "strconv" 4 | 5 | type scanner struct { 6 | } 7 | 8 | func (scanner scanner) VisitGoods(cart *shoppingCart) string { 9 | princes := "" 10 | for _, goods := range cart.bought { 11 | princes += strconv.Itoa(goods.price) + "元 " 12 | } 13 | 14 | return princes 15 | } 16 | 17 | func NewScanner() *scanner { 18 | scanner := &scanner{} 19 | 20 | return scanner 21 | } 22 | -------------------------------------------------------------------------------- /src/proxy/postman.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | type lazyPostman struct { 4 | letter letterContent 5 | } 6 | 7 | func NewLazyPostman() lazyPostman { 8 | letter := tempContent{} 9 | return lazyPostman{letter} 10 | } 11 | 12 | func (postman lazyPostman) RequestLetter() { 13 | postman.letter.get() 14 | } 15 | 16 | func (postman *lazyPostman) DemandLetter() { 17 | postman.letter = realContent{} 18 | postman.letter.get() 19 | } 20 | -------------------------------------------------------------------------------- /template.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "template" 4 | 5 | func main() { 6 | cm := template.NewCommunicate("A", "hello", "B") 7 | 8 | method_mail := template.Mail{} 9 | cm.SendMsg(method_mail) // send from A@126.com, to B@163.com, and the content is:mail:hello 10 | 11 | method_sms := template.Sms{} 12 | cm.SendMsg(method_sms) // send from A's phone_number :110, to B's phone_number: 12345, and the content is:sms:hello 13 | } 14 | -------------------------------------------------------------------------------- /decorator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "decorator" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | gift := decorator.NewGift("flower") 10 | gift_packed_first := decorator.NewPack(gift, "red ribbon") 11 | gift_packed_second := decorator.NewPack(gift_packed_first, "box") 12 | 13 | fmt.Println("a good sold, its detail:" + gift_packed_second.GetDesc()) // a good sold, its detail:flower, with red ribbon packed, with box packed 14 | } 15 | -------------------------------------------------------------------------------- /src/bridge/paper.go: -------------------------------------------------------------------------------- 1 | package bridge 2 | 3 | import "fmt" 4 | 5 | type paper interface { 6 | Paint() 7 | } 8 | 9 | type RedPaper struct { 10 | Pen pen 11 | } 12 | 13 | type BluePaper struct { 14 | Pen pen 15 | } 16 | 17 | func (paper RedPaper) Paint() { 18 | fmt.Println(paper.Pen.write() + " write on red paper!") 19 | } 20 | 21 | func (paper BluePaper) Paint() { 22 | fmt.Println(paper.Pen.write() + " write on blue paper!") 23 | } 24 | -------------------------------------------------------------------------------- /src/mediator/country.go: -------------------------------------------------------------------------------- 1 | package mediator 2 | 3 | type country struct { 4 | name string 5 | msg string 6 | } 7 | 8 | func (country *country) Receive(nations *unitedNations) string { 9 | return nations.getMsg(country) 10 | } 11 | 12 | func (country *country) Announce(msg string) { 13 | country.msg = msg 14 | } 15 | 16 | func NewCountry(name string) *country { 17 | country := &country{name: name} 18 | 19 | return country 20 | } 21 | -------------------------------------------------------------------------------- /src/flyweight/tree.go: -------------------------------------------------------------------------------- 1 | package flyweight 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | type forest struct { 9 | trees []map[string]int 10 | } 11 | 12 | func (forest forest) Fell() { 13 | for _, attr := range forest.trees { 14 | fmt.Println("a " + strconv.Itoa(attr["height"]) + " m tree cutted!") 15 | } 16 | } 17 | 18 | func NewForest(trees []map[string]int) forest { 19 | forest := forest{trees} 20 | 21 | return forest 22 | } 23 | -------------------------------------------------------------------------------- /factory.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "factory" 5 | ) 6 | 7 | func main() { 8 | lining_shoes_factory := factory.LiNingFactory{} 9 | lining_shoe := lining_shoes_factory.Product("plastic") 10 | lining_shoe.Wear() // a lining plastic shoe, it's price is 120元; 11 | 12 | adidas_shoe_factory := factory.AdidasFactory{} 13 | adidas_shoe := adidas_shoe_factory.Product("sports") 14 | adidas_shoe.Wear() // a adidas sports shoe, it's price is 70元; 15 | } 16 | -------------------------------------------------------------------------------- /src/command/soldier.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "fmt" 4 | 5 | type Soldier struct { 6 | Name string 7 | } 8 | 9 | func (soldier Soldier) ExecCommand(command Command) { 10 | fmt.Print("I am " + soldier.Name + ", I will execute general's command: ") 11 | command.exec() 12 | } 13 | 14 | func (soldier Soldier) UndoCommand(command Command) { 15 | fmt.Print("I am " + soldier.Name + ", I will execute general's command: ") 16 | command.undo() 17 | } 18 | -------------------------------------------------------------------------------- /src/singleton/instance.go: -------------------------------------------------------------------------------- 1 | package singleton 2 | 3 | var object *instance 4 | 5 | type instance struct { 6 | name string 7 | } 8 | 9 | func (instance instance) GetName() string { 10 | return instance.name 11 | } 12 | 13 | func (instance *instance) SetName(name string) { 14 | instance.name = name 15 | } 16 | 17 | // todo 后续考虑并行问题 18 | func GetInstance() *instance { 19 | if object == nil { 20 | object = &instance{"test1"} 21 | } 22 | 23 | return object 24 | } 25 | -------------------------------------------------------------------------------- /java/src/Command.java: -------------------------------------------------------------------------------- 1 | import pattern.command.Order; 2 | import pattern.command.Soldier; 3 | 4 | public class Command { 5 | public static void main(String[] args) { 6 | Order command = new Order("run", "mountain", "river"); 7 | Soldier lisi = new Soldier("lisi"); 8 | lisi.setCommand(command); 9 | 10 | lisi.execCommand(); // lisi run from mountain to river 11 | lisi.undoCommand();// lisi run from river to mountain 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /java/src/pattern/decorator/Pack.java: -------------------------------------------------------------------------------- 1 | package pattern.decorator; 2 | 3 | public class Pack extends Goods { 4 | private Goods goods; 5 | private String name; 6 | 7 | public Pack(String name) { 8 | this.name = name; 9 | } 10 | 11 | public void packet(Goods goods) { 12 | this.goods = goods; 13 | } 14 | 15 | @Override 16 | public String sold() { 17 | return this.name + "( " + this.goods.sold() + " )"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /memento.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "memento" 6 | ) 7 | 8 | func main() { 9 | time_controller := memento.NewTimeController() 10 | xiaoming := memento.NewPerson("xiaoming", 18, 175, 70) 11 | time_controller.Save(xiaoming.GetAge(), xiaoming.Bak()) 12 | 13 | xiaoming.GrowUp(80, 170, 65) 14 | fmt.Println(xiaoming) // &{xiaoming 80 170 65} 小明变成老明了 15 | xiaoming.Renewal(time_controller.GetMemo(18)) 16 | fmt.Println(xiaoming) // &{xiaoming 18 175 70} 小明又成为小明了 17 | } 18 | -------------------------------------------------------------------------------- /interpreter.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "interpreter" 6 | ) 7 | 8 | func main() { 9 | hello := interpreter.NewWords("hello") 10 | greeting := interpreter.NewVariable("greeting") 11 | context := interpreter.NewContext() 12 | context.AddItem("greeting", hello) 13 | context.AddItem("test", greeting) 14 | 15 | var_test := interpreter.NewVariable("$$test") 16 | fmt.Println(var_test.Interpret(context)) // $greeting = "hello"; $test = "greeting"; $$test = "hello" 17 | } 18 | -------------------------------------------------------------------------------- /src/strategy/calculator.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | // 计算器类,有算法属性,且其算法随时可被替换,以使用其他的算法 4 | type calculator struct { 5 | alg IAlg 6 | } 7 | 8 | // 计算器构造方法,默认使用二分法计算 9 | func NewCalculator() calculator { 10 | alg := NewBubbleSearch() 11 | calculator := calculator{alg} 12 | 13 | return calculator 14 | } 15 | 16 | // 改变算法 17 | func (calculator *calculator) ChangeAlg(alg IAlg) { 18 | calculator.alg = alg 19 | } 20 | 21 | func (calculator calculator) Cal() { 22 | calculator.alg.used() 23 | } 24 | -------------------------------------------------------------------------------- /java/src/Decorator.java: -------------------------------------------------------------------------------- 1 | import pattern.decorator.*; 2 | 3 | public class Decorator { 4 | public static void main(String[] args){ 5 | Toy toyCar = new Toy("toy car"); 6 | System.out.println(toyCar.sold()); 7 | 8 | Pack box = new Pack("box"); 9 | box.packet(toyCar); 10 | System.out.println(box.sold()); 11 | 12 | Pack redRibbon = new Pack("red ribbon"); 13 | redRibbon.packet(box); 14 | System.out.println(redRibbon.sold()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/observer/reporter.go: -------------------------------------------------------------------------------- 1 | package observer 2 | 3 | import "fmt" 4 | 5 | // 记者接口,有报道方法 6 | type IReporter interface { 7 | report(string) 8 | } 9 | 10 | // 新闻记者基类, 有名字属性和并实现了报道方法 11 | type newsReporter struct { 12 | name string 13 | } 14 | 15 | func NewNewsReporter(name string) newsReporter { 16 | news_reporter := newsReporter{name} 17 | 18 | return news_reporter 19 | } 20 | 21 | func (reporter newsReporter) report(event string) { 22 | fmt.Println(reporter.name + " reported an event:" + event) 23 | } 24 | -------------------------------------------------------------------------------- /chainOfResponsibility.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "chainOfResponsibility" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | CEO := chainOfResponsibility.NewAuditor("CEO", 10000, nil) 10 | manager := chainOfResponsibility.NewAuditor("manager", 2000, CEO) 11 | leader := chainOfResponsibility.NewAuditor("leader", 500, manager) 12 | 13 | fmt.Println(leader.Audit(300)) // leader permitted! 14 | fmt.Println(leader.Audit(3000)) // CEO permitted! 15 | fmt.Println(leader.Audit(80000)) // out of limit! 16 | } 17 | -------------------------------------------------------------------------------- /mediator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "mediator" 6 | ) 7 | 8 | func main() { 9 | france := mediator.NewCountry("France") 10 | korea := mediator.NewCountry("korea") 11 | 12 | unitedNations := mediator.NewUnitedNations(france, korea) 13 | 14 | france.Announce("I am a romantic country~") 15 | fmt.Println(korea.Receive(unitedNations)) // I am a romantic country~ 16 | korea.Announce("I am good at copy!") // I am good at copy! 17 | fmt.Println(france.Receive(unitedNations)) 18 | } 19 | -------------------------------------------------------------------------------- /src/builder/style.go: -------------------------------------------------------------------------------- 1 | package builder 2 | 3 | type style interface { 4 | roof() string 5 | gate() string 6 | } 7 | 8 | type ChineseType struct { 9 | } 10 | 11 | func (ChineseType) roof() string { 12 | return "golden roof" 13 | } 14 | 15 | func (ChineseType) gate() string { 16 | return "red gate" 17 | } 18 | 19 | type ItalianType struct { 20 | } 21 | 22 | func (ItalianType) roof() string { 23 | return "white round roof" 24 | } 25 | 26 | func (ItalianType) gate() string { 27 | return "white gate" 28 | } 29 | -------------------------------------------------------------------------------- /java/src/Factory.java: -------------------------------------------------------------------------------- 1 | import pattern.factory.*; 2 | 3 | public class Factory { 4 | public static void main(String[] args) { 5 | SimpleFactory simpleFactory = new SimpleFactory(); 6 | Shoe shoeA = simpleFactory.product("sports", "adidas"); 7 | System.out.println(shoeA.getDetail()); 8 | 9 | AbstractFactory liningShoeFactory = new AbstractFactory("lining"); 10 | Shoe shoeB = liningShoeFactory.product("cotton"); 11 | System.out.println(shoeB.getDetail()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/mediator/unitedNations.go: -------------------------------------------------------------------------------- 1 | package mediator 2 | 3 | type unitedNations struct { 4 | europe *country 5 | asia *country 6 | } 7 | 8 | func (mediator unitedNations) getMsg(country *country) string { 9 | if mediator.europe == country { 10 | return mediator.asia.msg 11 | } else { 12 | return mediator.europe.msg 13 | } 14 | } 15 | 16 | func NewUnitedNations(european_country, asian_countryB *country) *unitedNations { 17 | unitedNations := &unitedNations{european_country, asian_countryB} 18 | 19 | return unitedNations 20 | } 21 | -------------------------------------------------------------------------------- /src/visitor/mall.go: -------------------------------------------------------------------------------- 1 | package visitor 2 | 3 | type goods struct { 4 | name string 5 | price int 6 | } 7 | 8 | func NewGoods(name string, price int) *goods { 9 | goods := &goods{name, price} 10 | return goods 11 | } 12 | 13 | func (goods *goods) AddToCart(cart *shoppingCart) { 14 | cart.bought = append(cart.bought, goods) 15 | } 16 | 17 | type shoppingCart struct { 18 | bought []*goods 19 | } 20 | 21 | func NewShoppingCart() *shoppingCart { 22 | bought := make([]*goods, 0) 23 | cart := &shoppingCart{bought} 24 | return cart 25 | } 26 | -------------------------------------------------------------------------------- /observer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "observer" 4 | 5 | func main() { 6 | news := observer.News{} 7 | 8 | zhangsan := observer.NewNewsReporter("zhangsan") 9 | news.Focus(zhangsan) 10 | 11 | lisi := observer.NewNewsReporter("lisi") 12 | news.Focus(lisi) 13 | 14 | news.Happen("someone was killed!") // zhangsan reported an event:someone was killed! lisi reported an event:someone was killed! 15 | 16 | news.Ignore(lisi) 17 | news.Happen("a building built in the city!") // zhangsan reported an event:a building built in the city! 18 | } 19 | -------------------------------------------------------------------------------- /java/src/Adapter.java: -------------------------------------------------------------------------------- 1 | import pattern.adapter.DeafMan; 2 | import pattern.adapter.NormalPerson; 3 | import pattern.adapter.SpeakAdapter; 4 | 5 | public class Adapter { 6 | public static void main(String[] args) { 7 | NormalPerson zhangsan = new NormalPerson("zhangsan"); 8 | zhangsan.speak("hi"); // zhangsan speak:hi 9 | 10 | DeafMan lisi = new DeafMan("lisi"); 11 | SpeakAdapter adapter = new SpeakAdapter(); 12 | adapter.setMan(lisi); 13 | adapter.speak("hello"); // lisi speak:hello 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/src/pattern/command/Soldier.java: -------------------------------------------------------------------------------- 1 | package pattern.command; 2 | 3 | public class Soldier { 4 | private String name; 5 | private Order command; 6 | 7 | public Soldier(String name) { 8 | this.name = name; 9 | } 10 | 11 | public void execCommand() { 12 | System.out.println(name + " " + command.execute()); 13 | } 14 | 15 | public void undoCommand() { 16 | System.out.println(name + " " + command.undo()); 17 | } 18 | 19 | public void setCommand(Order command) { 20 | this.command = command; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/prototype/honorGuard.go: -------------------------------------------------------------------------------- 1 | package prototype 2 | 3 | type honorGuard struct { 4 | age int 5 | height int 6 | weight int 7 | gender string 8 | name string 9 | } 10 | 11 | func (guard *honorGuard) SetName(name string) { 12 | guard.name = name 13 | } 14 | 15 | func (guard *honorGuard) Clone() *honorGuard { 16 | new_guard := *guard 17 | 18 | return &new_guard 19 | } 20 | 21 | func NewhonorGuard(age, height, weight int, gender string) *honorGuard { 22 | guard := &honorGuard{age: age, height: height, weight: weight, gender: gender} 23 | 24 | return guard 25 | } 26 | -------------------------------------------------------------------------------- /flyweight.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "flyweight" 4 | 5 | func main() { 6 | treeA := map[string]int{"height": 20} 7 | treeB := map[string]int{"height": 14} 8 | treeC := map[string]int{"height": 25} 9 | treeD := map[string]int{"height": 7} 10 | treeE := map[string]int{"height": 40} 11 | trees := []map[string]int{treeA, treeB, treeC, treeD, treeE} 12 | 13 | forest := flyweight.NewForest(trees) 14 | 15 | forest.Fell() 16 | /* 17 | a 20 m tree cutted! 18 | a 14 m tree cutted! 19 | a 25 m tree cutted! 20 | a 7 m tree cutted! 21 | a 40 m tree cutted! 22 | */ 23 | } 24 | -------------------------------------------------------------------------------- /iterator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "iterator" 6 | ) 7 | 8 | func main() { 9 | horses := []string{"white", "black", "brown"} 10 | horse_queue := iterator.NewHorses(horses) 11 | 12 | soldiers := 13 | map[string]string{ 14 | "zhangsan": "zhangsan", 15 | "lisi": "lisi", 16 | "wangwu": "wangwu", 17 | } 18 | soldier_queue := iterator.NewSoldiers(soldiers) 19 | 20 | fmt.Println(horse_queue.Count(), soldier_queue.Count()) 21 | fmt.Println(horse_queue.Next(), soldier_queue.Next()) 22 | horse_queue.Remove() 23 | soldier_queue.Remove() 24 | } 25 | -------------------------------------------------------------------------------- /src/memento/timeController.go: -------------------------------------------------------------------------------- 1 | package memento 2 | 3 | type memo struct { 4 | age int 5 | height int 6 | weight int 7 | } 8 | 9 | type timeController struct { 10 | memos map[int]memo 11 | } 12 | 13 | func NewTimeController() *timeController { 14 | memos := make(map[int]memo) 15 | controller := &timeController{memos} 16 | 17 | return controller 18 | } 19 | 20 | func (controller *timeController) Save(age int, memo memo) { 21 | controller.memos[age] = memo 22 | } 23 | 24 | func (controller *timeController) GetMemo(age int) memo { 25 | return controller.memos[age] 26 | } 27 | -------------------------------------------------------------------------------- /java/src/pattern/command/Order.java: -------------------------------------------------------------------------------- 1 | package pattern.command; 2 | 3 | public class Order { 4 | private String action; 5 | private String source; 6 | private String dest; 7 | 8 | public Order(String action, String source, String dest) { 9 | this.action = action; 10 | this.source = source; 11 | this.dest = dest; 12 | } 13 | 14 | public String execute() { 15 | return action + " from " + source + " to " + dest; 16 | } 17 | 18 | public String undo() { 19 | return action + " from " + dest + " to " + source; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/observer/news.go: -------------------------------------------------------------------------------- 1 | package observer 2 | 3 | type News struct { 4 | reporters []IReporter 5 | } 6 | 7 | func (news News) Happen(event string) { 8 | for _, reporter := range news.reporters { 9 | reporter.report(event) 10 | } 11 | } 12 | 13 | func (news *News) Focus(reporter IReporter) { 14 | news.reporters = append(news.reporters, reporter) 15 | } 16 | 17 | func (news *News) Ignore(reporter IReporter) { 18 | for index, news_reporter := range news.reporters { 19 | if news_reporter == reporter { 20 | news.reporters = append(news.reporters[:index], news.reporters[index+1:]...) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/template/msg.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import "fmt" 4 | 5 | type Communicate struct { 6 | sender string 7 | content string 8 | receiver string 9 | } 10 | 11 | // there is not parent class in go, this function is a substitute 12 | func (cm Communicate) SendMsg(method Sample) { 13 | fmt.Println("send from " + method.getSender(cm.sender) + ", to " + method.getReceiver(cm.receiver) + ", and the content is:" + method.processContent(cm.content)) 14 | } 15 | 16 | func NewCommunicate(sender, content, receiver string) Communicate { 17 | cm := Communicate{sender, content, receiver} 18 | 19 | return cm 20 | } 21 | -------------------------------------------------------------------------------- /java/src/Observer.java: -------------------------------------------------------------------------------- 1 | import pattern.observer.*; 2 | 3 | public class Observer { 4 | public static void main(String[] args) { 5 | TvStation station = new TvStation(); 6 | 7 | Reporter zhangsan = new Reporter("zhangsan"); 8 | station.register(zhangsan); 9 | Reporter lisi = new Reporter("lisi"); 10 | station.register(lisi); 11 | Reporter wangwu = new Reporter("wangwu"); 12 | station.register(wangwu); 13 | 14 | station.eventHappen("a man murdered!"); 15 | 16 | station.cancel(lisi); 17 | 18 | station.eventHappen("a car accident..."); 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/command/command.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import "fmt" 4 | 5 | type Command interface { 6 | exec() 7 | undo() 8 | } 9 | 10 | type Run struct { 11 | Start string 12 | Destination string 13 | } 14 | 15 | func (command Run) exec() { 16 | fmt.Println("run to " + command.Destination + " from " + command.Start) 17 | } 18 | 19 | func (command Run) undo() { 20 | fmt.Println("run to " + command.Start + " from " + command.Destination) 21 | } 22 | 23 | type Attention struct { 24 | } 25 | 26 | func (command Attention) exec() { 27 | fmt.Println("Attention!") 28 | } 29 | 30 | func (command Attention) undo() { 31 | fmt.Println("At ease!") 32 | } 33 | -------------------------------------------------------------------------------- /src/chainOfResponsibility/auditor.go: -------------------------------------------------------------------------------- 1 | package chainOfResponsibility 2 | 3 | type auditor struct { 4 | name string 5 | authority int 6 | superior *auditor 7 | } 8 | 9 | func (auditor auditor) Audit(request int) string { 10 | if request <= auditor.authority { 11 | return auditor.name + " permitted!" 12 | } else { 13 | if auditor.superior == nil { 14 | return "out of limit!" 15 | } else { 16 | return auditor.superior.Audit(request) 17 | } 18 | } 19 | } 20 | 21 | func NewAuditor(name string, authority int, superior *auditor) *auditor { 22 | auditor := &auditor{name: name, authority: authority, superior: superior} 23 | 24 | return auditor 25 | } 26 | -------------------------------------------------------------------------------- /src/state/fruit.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | type fruit struct { 4 | stage Stage 5 | } 6 | 7 | func NewFruit() fruit { 8 | seedling := seedling{} 9 | fruit := fruit{seedling} 10 | 11 | return fruit 12 | } 13 | 14 | func (fruit *fruit) Water() { 15 | fruit.stage.water() 16 | if _, ok := interface{}(fruit.stage).(seedling); ok { 17 | bloom := bloom{} 18 | fruit.stage = bloom 19 | } else { 20 | maturity := maturity{} 21 | fruit.stage = maturity 22 | } 23 | } 24 | 25 | func (fruit *fruit) Harvest() { 26 | fruit.stage.harvest() 27 | if _, ok := interface{}(fruit.stage).(maturity); ok { 28 | seedling := seedling{} 29 | fruit.stage = seedling 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /visitor.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "visitor" 6 | ) 7 | 8 | func main() { 9 | cart := visitor.NewShoppingCart() 10 | water := visitor.NewGoods("nofushanquan", 2) 11 | water.AddToCart(cart) 12 | 13 | milk := visitor.NewGoods("wangzai", 5) 14 | milk.AddToCart(cart) 15 | 16 | ballPen := visitor.NewGoods("morning light", 1) 17 | ballPen.AddToCart(cart) 18 | 19 | scanner := visitor.NewScanner() 20 | fmt.Println("goods's prices are:" + scanner.VisitGoods(cart)) // goods's prices are:2元 5元 1元 21 | 22 | printer := visitor.NewPrinter() 23 | fmt.Println("goods's names are:" + printer.VisitGoods(cart)) // goods's names are:nofushanquan wangzai morning light 24 | 25 | } 26 | -------------------------------------------------------------------------------- /command.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "command" 4 | 5 | func main() { 6 | // this is a general, and publish command to a soldier 7 | command_run := command.Run{"tree", "grass_ground"} 8 | soldier_A := command.Soldier{"zhangsan"} 9 | soldier_A.ExecCommand(command_run) // I am zhangsan, I will execute general's command: run to grass_ground from tree 10 | soldier_A.UndoCommand(command_run) // I am zhangsan, I will execute general's command: run to tree from grass_ground 11 | 12 | command_attention := command.Attention{} 13 | soldier_A.ExecCommand(command_attention) // I am zhangsan, I will execute general's command: Attention! 14 | soldier_A.UndoCommand(command_attention) // I am zhangsan, I will execute general's command: At ease! 15 | } 16 | -------------------------------------------------------------------------------- /src/iterator/horses.go: -------------------------------------------------------------------------------- 1 | package iterator 2 | 3 | type horses struct { 4 | queue []string 5 | cursor int 6 | } 7 | 8 | func NewHorses(queue []string) *horses { 9 | horses := &horses{queue, -1} 10 | 11 | return horses 12 | } 13 | 14 | func (horses horses) Count() int { 15 | return len(horses.queue) 16 | } 17 | 18 | func (horses *horses) Next() string { 19 | if horses.cursor >= len(horses.queue) { 20 | return "out of range!" 21 | } else { 22 | horses.cursor++ 23 | return horses.queue[horses.cursor] 24 | } 25 | } 26 | 27 | func (horses *horses) Remove() { 28 | for index := range horses.queue { 29 | if index == horses.cursor { 30 | horses.queue = append(horses.queue[:index], horses.queue[index+1:]...) 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/state/stage.go: -------------------------------------------------------------------------------- 1 | package state 2 | 3 | import "fmt" 4 | 5 | type Stage interface { 6 | water() 7 | harvest() 8 | } 9 | 10 | type seedling struct { 11 | } 12 | 13 | func (seedling) water() { 14 | fmt.Println("The plant is growing!") 15 | } 16 | 17 | func (seedling) harvest() { 18 | fmt.Println("The plant is just planted!") 19 | } 20 | 21 | type bloom struct { 22 | } 23 | 24 | func (bloom) water() { 25 | fmt.Println("The plant is ripping!") 26 | } 27 | 28 | func (bloom) harvest() { 29 | fmt.Println("The plant is blooming, don't do that!") 30 | } 31 | 32 | type maturity struct { 33 | } 34 | 35 | func (maturity) water() { 36 | fmt.Println("The plant don't need water!") 37 | } 38 | 39 | func (maturity) harvest() { 40 | fmt.Println("You got lots of fruits!") 41 | } 42 | -------------------------------------------------------------------------------- /src/composite/soldier.go: -------------------------------------------------------------------------------- 1 | package composite 2 | 3 | import "fmt" 4 | 5 | type Military interface { 6 | Fight() 7 | } 8 | 9 | type General struct { 10 | Name string 11 | Followers []Captain 12 | } 13 | 14 | func (general General) Fight() { 15 | fmt.Println(general.Name + " is fighting!") 16 | for _, captain := range general.Followers { 17 | captain.Fight() 18 | } 19 | } 20 | 21 | type Captain struct { 22 | Name string 23 | Followers []Soldier 24 | } 25 | 26 | func (captain Captain) Fight() { 27 | fmt.Println(captain.Name + " is fighting") 28 | for _, soldier := range captain.Followers { 29 | soldier.Fight() 30 | } 31 | } 32 | 33 | type Soldier struct { 34 | Name string 35 | } 36 | 37 | func (soldier Soldier) Fight() { 38 | fmt.Println(soldier.Name + " is fighting!") 39 | } 40 | -------------------------------------------------------------------------------- /src/strategy/algs.go: -------------------------------------------------------------------------------- 1 | package strategy 2 | 3 | import "fmt" 4 | 5 | // 算法接口 有 "被使用" 方法 6 | type IAlg interface { 7 | used() 8 | } 9 | 10 | /***************** 11 | 算法 冒泡 12 | *****************/ 13 | type BubbleSort struct { 14 | name string 15 | } 16 | 17 | func NewBubbleSearch() BubbleSort { 18 | binary_search := BubbleSort{"bubble sort"} 19 | 20 | return binary_search 21 | } 22 | 23 | func (alg BubbleSort) used() { 24 | fmt.Println("I am using util " + alg.name) 25 | } 26 | 27 | /***************** 28 | 算法 快速排序法 29 | *****************/ 30 | type quickSort struct { 31 | name string 32 | } 33 | 34 | func NewQuickSort() quickSort { 35 | quick_sort := quickSort{"quick sort"} 36 | 37 | return quick_sort 38 | } 39 | 40 | func (alg quickSort) used() { 41 | fmt.Println("I am using util " + alg.name) 42 | } 43 | -------------------------------------------------------------------------------- /java/src/pattern/singleton/Redis.java: -------------------------------------------------------------------------------- 1 | package pattern.singleton; 2 | 3 | import redis.clients.jedis.Jedis; 4 | import java.util.HashMap; 5 | 6 | public class Redis { 7 | private static volatile HashMap INSTANCES = new HashMap<>(); 8 | 9 | private Redis() { 10 | } 11 | 12 | public static Jedis getInstance(String host, int port) { 13 | String hashKey = host + "_" + port; 14 | 15 | if (Redis.INSTANCES.get(hashKey) == null) { 16 | synchronized (Redis.class) { 17 | if (Redis.INSTANCES.get(hashKey) == null) { 18 | Jedis instance = new Jedis(host, port); 19 | Redis.INSTANCES.put(hashKey, instance); 20 | } 21 | } 22 | } 23 | 24 | return Redis.INSTANCES.get(hashKey); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/memento/person.go: -------------------------------------------------------------------------------- 1 | package memento 2 | 3 | type person struct { 4 | name string 5 | age int 6 | height int 7 | weight int 8 | } 9 | 10 | func (person *person) GetAge() int { 11 | return person.age 12 | } 13 | 14 | func (person *person) GrowUp(age, height, weight int) { 15 | person.age = age 16 | person.height = height 17 | person.weight = weight 18 | } 19 | 20 | func (person *person) Bak() memo { 21 | memo := memo{person.age, person.height, person.weight} 22 | 23 | return memo 24 | } 25 | 26 | func (person *person) Renewal(memo memo) { 27 | person.age = memo.age 28 | person.height = memo.height 29 | person.weight = memo.weight 30 | } 31 | 32 | func NewPerson(name string, age, height, weight int) *person { 33 | person := &person{name: name, age: age, height: height, weight: weight} 34 | 35 | return person 36 | } 37 | -------------------------------------------------------------------------------- /composite.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "composite" 4 | 5 | func main() { 6 | solderA := composite.Soldier{"soldierA"} 7 | solderB := composite.Soldier{"soldierB"} 8 | solderC := composite.Soldier{"soldierC"} 9 | solderD := composite.Soldier{"soldierD"} 10 | 11 | soldier_queue_A := []composite.Soldier{solderA, solderB} 12 | captainA := composite.Captain{"captainA", soldier_queue_A} 13 | soldier_queue_B := []composite.Soldier{solderC, solderD} 14 | captainB := composite.Captain{"captainB", soldier_queue_B} 15 | 16 | captain_queue := []composite.Captain{captainA, captainB} 17 | general := composite.General{"GENERAL", captain_queue} 18 | general.Fight() 19 | /* 20 | GENERAL is fighting! 21 | captainA is fighting 22 | soldierA is fighting! 23 | soldierB is fighting! 24 | captainB is fighting 25 | soldierC is fighting! 26 | soldierD is fighting! 27 | */ 28 | } 29 | -------------------------------------------------------------------------------- /src/template/method.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | type Sample interface { 4 | getSender(name string) string 5 | processContent(content string) string 6 | getReceiver(name string) string 7 | } 8 | 9 | type Sms struct { 10 | } 11 | 12 | func (sender Sms) getSender(name string) string { 13 | return name + "'s phone_number :110" 14 | } 15 | 16 | func (sender Sms) processContent(content string) string { 17 | return "sms:" + content 18 | } 19 | 20 | func (sender Sms) getReceiver(name string) string { 21 | return name + "'s phone_number: 12345" 22 | } 23 | 24 | type Mail struct { 25 | } 26 | 27 | func (sender Mail) getSender(name string) string { 28 | return name + "@126.com" 29 | } 30 | 31 | func (sender Mail) processContent(content string) string { 32 | return "mail:" + content 33 | } 34 | 35 | func (sender Mail) getReceiver(name string) string { 36 | return name + "@163.com" 37 | } 38 | -------------------------------------------------------------------------------- /src/interpreter/interpreter.go: -------------------------------------------------------------------------------- 1 | package interpreter 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | type expression interface { 8 | Interpret(*context) string 9 | } 10 | 11 | type words struct { 12 | val string 13 | } 14 | 15 | func NewWords(val string) *words { 16 | words := &words{val} 17 | return words 18 | } 19 | 20 | func (words words) Interpret(context *context) string { 21 | return words.val 22 | } 23 | 24 | type variable struct { 25 | val string 26 | } 27 | 28 | func NewVariable(val string) *variable { 29 | variable := &variable{val} 30 | return variable 31 | } 32 | 33 | func (variable variable) Interpret(context *context) string { 34 | //index := strings.Index(variable.val, "$") 35 | 36 | var index int 37 | for { 38 | index = strings.Index(variable.val, "$") 39 | if index < 0 { 40 | break 41 | } 42 | 43 | variable.val = string([]rune(variable.val)[1:]) 44 | } 45 | 46 | return context.args[variable.val].Interpret(context) 47 | } 48 | -------------------------------------------------------------------------------- /src/factory/shoesFactory.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | type ShoesFactory interface { 4 | Product(material string) 5 | } 6 | 7 | type LiNingFactory struct { 8 | } 9 | 10 | func (factory LiNingFactory) Product(material string) Shoe { 11 | var shoe Shoe 12 | if material == "plastic" { 13 | shoe = liNingPlasticShoe{"lining plastic shoe", 120} 14 | } else if material == "cotton" { 15 | shoe = liNingCottonShoe{"linig cotton shoe", 110} 16 | } else { 17 | shoe = liNingPlasticShoe{"linig sports shoe", 100} 18 | } 19 | 20 | return shoe 21 | } 22 | 23 | type AdidasFactory struct { 24 | } 25 | 26 | func (factory AdidasFactory) Product(material string) Shoe { 27 | var shoe Shoe 28 | if material == "plastic" { 29 | shoe = adidasPlasticShoe{"adidas plastic shoe", 90} 30 | } else if material == "cotton" { 31 | shoe = adidasCottonShoe{"adidas cotton shoe", 80} 32 | } else { 33 | shoe = adidasSportsShoe{"adidas sports shoe", 70} 34 | } 35 | 36 | return shoe 37 | } 38 | -------------------------------------------------------------------------------- /java/src/pattern/observer/TvStation.java: -------------------------------------------------------------------------------- 1 | package pattern.observer; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | 6 | public class TvStation { 7 | private ArrayList reporters; 8 | 9 | public TvStation() { 10 | this.reporters = new ArrayList(); 11 | } 12 | 13 | public void register(Reporter reporter) { 14 | this.reporters.add(reporter); 15 | } 16 | 17 | public void cancel(Reporter reporter) { 18 | Iterator iterator = this.reporters.iterator(); 19 | 20 | while (iterator.hasNext()) { 21 | Reporter item = (Reporter) iterator.next(); 22 | if (item.equals(reporter)) { 23 | iterator.remove(); 24 | } 25 | } 26 | } 27 | 28 | public void eventHappen(String event) { 29 | Iterator iterator = this.reporters.iterator(); 30 | 31 | while (iterator.hasNext()) { 32 | Reporter reporter = (Reporter) iterator.next(); 33 | reporter.notified(event); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/iterator/soldiers.go: -------------------------------------------------------------------------------- 1 | package iterator 2 | 3 | type soldiers struct { 4 | queue map[string]string 5 | names []string // map is not ordered, use a slice to store the order 6 | cursor int 7 | } 8 | 9 | func NewSoldiers(queue map[string]string) *soldiers { 10 | var names []string 11 | for index := range queue { 12 | names = append(names, index) 13 | } 14 | soldiers := &soldiers{queue, names, -1} 15 | 16 | return soldiers 17 | } 18 | 19 | func (soldiers soldiers) Count() int { 20 | return len(soldiers.queue) 21 | } 22 | 23 | func (soldiers *soldiers) Next() string { 24 | 25 | if soldiers.cursor >= len(soldiers.names) { 26 | return "out of range!" 27 | } else { 28 | soldiers.cursor++ 29 | return soldiers.queue[soldiers.names[soldiers.cursor]] 30 | } 31 | } 32 | 33 | func (soldiers *soldiers) Remove() { 34 | for index, name := range soldiers.names { 35 | if index == soldiers.cursor { 36 | soldiers.names = append(soldiers.names[:index], soldiers.names[index+1:]...) 37 | delete(soldiers.queue, name) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/factory/shoes.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | import "fmt" 4 | 5 | type Shoe interface { 6 | Wear() // todo tooooo many implements!!! How to Optimize??? 7 | } 8 | 9 | type Function struct { 10 | name string 11 | price int 12 | } 13 | 14 | type liNingPlasticShoe struct { 15 | name string 16 | price int 17 | } 18 | 19 | func (shoe liNingPlasticShoe) Wear() { 20 | fmt.Printf("a %s, it's price is %d元;\n", shoe.name, shoe.price) 21 | } 22 | 23 | type liNingCottonShoe struct { 24 | name string 25 | price int 26 | } 27 | 28 | func (shoe liNingCottonShoe) Wear() { 29 | fmt.Printf("a %s, it's price is %d元;\n", shoe.name, shoe.price) 30 | } 31 | 32 | type liNingSportsShoe struct { 33 | name string 34 | price int 35 | } 36 | 37 | func (shoe liNingSportsShoe) Wear() { 38 | fmt.Printf("a %s, it's price is %d元;\n", shoe.name, shoe.price) 39 | } 40 | 41 | type adidasPlasticShoe struct { 42 | name string 43 | price int 44 | } 45 | 46 | func (shoe adidasPlasticShoe) Wear() { 47 | fmt.Printf("a %s, it's price is %d元;\n", shoe.name, shoe.price) 48 | } 49 | 50 | type adidasCottonShoe struct { 51 | name string 52 | price int 53 | } 54 | 55 | func (shoe adidasCottonShoe) Wear() { 56 | fmt.Printf("a %s, it's price is %d元;\n", shoe.name, shoe.price) 57 | } 58 | 59 | type adidasSportsShoe struct { 60 | name string 61 | price int 62 | } 63 | 64 | func (shoe adidasSportsShoe) Wear() { 65 | fmt.Printf("a %s, it's price is %d元;\n", shoe.name, shoe.price) 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DesignPattern 2 | 设计模式 3 | 4 | - strategy 策略模式 5 | - observer 观察者模式 6 | - decorator 装饰者模式 7 | - factory 工厂模式(简单工厂/抽象工厂) 8 | - singleton 单例模式 9 | - command 命令模式 10 | - adapter 适配器模式 11 | - facade 外观模式 12 | - template 模板模式 13 | - iterator 迭代器模式 14 | - composite 组合模式 15 | - state 状态模式 16 | - proxy 代理模式 17 | - bridge 桥接模式 18 | - builder 建造者模式 19 | - chain_of_responsibility 责任链模式 20 | - flyweight 蝇量模式 21 | - interpreter 解释器模式 22 | - mediator 中介者模式 23 | - memento 备忘录模式 24 | - prototype 原型模式 25 | - visitor 访问者模式 26 | 27 | 根据设计模式所针对的问题,将设计模式分为三类: 28 | 29 | - 创建型,创建型模式针对对象的创建。包括:工厂模式、单例模式、生成器模式、原型模式; 30 | - 行为型,行为型模式针对对象的行为,如对象之间的通信、职责分配。包括:策略模式、观察者模式、状态模式、模板模式、命令模式、迭代器模式、责任链模式、中介者模式、解释器模式、备忘录模式、访问者模式。 31 | - 结构型,结构型模式针对如何实现对象的结构。包括:装饰者模式、适配器模式、外观模式、桥接模式、组合模式、代理者模式、蝇量模式。 32 | 33 | --- 34 | 35 | # 策略模式(Strategy) 36 | ### 介绍 37 | 策略模式: 将算法或操作抽象成`实现共同接口、可以被替换`的类,实现逻辑和具体算法的解耦。 38 | 39 | - 将各种行为`抽象成算法`,封装算法为对象; 40 | - 算法实现`共同接口`,调用者调用时不考虑算法具体实现,调用接口方法即可; 41 | - 调用者可随时替换此算法对象; 42 | 43 | ### 场景 44 | - 多个方法择一使用,且他们会被随时替换; 45 | - 方法没有共性,使用继承会有大量重写,使用接口会有大量重复使用; 46 | 47 | ### 实现 48 | 1. 两个算法: 冒泡排序和快速排序; 49 | 2. 抽象冒泡排序和快速排序为算法对象,实现算法接口,拥有 used() 被使用方法; 50 | 3. 计算器计算时不用理会是什么算法,调用 used() 即可。 51 | 52 | 53 | --- 54 | 55 | # 观察者模式(Observer) 56 | ### 介绍 57 | 观察者模式:主题`主动向观察者推送`变化,解决观察者对主题对象的依赖。 58 | 59 | - 观察者实现`被通知`接口,并在主题上注册,主题只`保存观察者的引用`,不关心观察者的实现; 60 | - 在主题有变化时调用观察者的通知接口来通知已注册的观察者; 61 | - 通知方式有`推`(主题变化时将变化数据推送给观察者)和`拉`(主题只告知变化,观察者主动来拉取数据) 62 | 63 | ### 场景 64 | - 一个主题,多个观察者,主题的任何变动,观察者都要第一时刻得到; 65 | - 观察者获取主题变化困难,定时不及时,轮询消耗大; 66 | - 观察者可以随时停止关注某主题; 67 | 68 | ### 实现 69 | 1. 张三和李四是记者,他们需要及时了解城市发生的新闻; 70 | 2. 张三和李四在电视台注册了自己的信息; 71 | 3. 城市发生了新闻,电视台遍历注册信息,通知了张三和李四; 72 | 4. 李四退休了,在电视台注销了自己的信息; 73 | 5. 城市又发生了新闻,电视台只通知了张三; 74 | 75 | 76 | --- 77 | # 装饰者模式(Decorator) 78 | 79 | ### 介绍 80 | 装饰者模式:包装一个对象,在被装饰对象的基础上`添加功能`; 81 | 82 | - 装饰者与被装饰对象拥有同一个超类,`装饰者拥有被装饰对象的所有外部接口`,可被调用,外界无法感知调用的是装饰者还是被装饰者; 83 | - 装饰者需要被装饰者作为参数传入,并在装饰者内部,在`被装饰者实现的基础上添加或修改某些功能`后,提供同被装饰者一样的接口; 84 | - 装饰者也可被另一个装饰者装饰,即嵌套装饰。 85 | - 装饰者是一群包装类,由于装饰的复杂性,会多出很多个装饰者小类; 86 | 87 | 88 | ### 场景 89 | - 对象需要动态地添加和修改功能; 90 | - 功能改变后不影响原对象的使用 91 | 92 | ### 实现 93 | 1. 在商店内,花作为被装饰者对象、红丝带和盒子作为花的装饰者; 94 | 2. 花、红丝带、盒子有共同的超类“商品”,他们都能被卖掉; 95 | 3. 我们可以在红丝带装饰过花后,再用盒子再包装一次; 96 | 4. 包装后的花,顾客买时也不会受到任何影响; 97 | 98 | --- 99 | # 工厂模式(Factory) 100 | 101 | ### 介绍 102 | 工厂模式: 顾名思义,工厂模式是`对象的生产器`,解耦用户对具体对象的依赖。 103 | 104 | - 实现`依赖倒置`,让用户通过一个"产品工厂"`依赖产品的抽象`,而不是一个具体的产品; 105 | - 简单工厂模式:接收参数并根据参数创建对应类,将对象的实例化和具体使用解耦; 106 | - 抽象工厂模式:将工厂`抽象出多个生产接口`,不同类型的工厂调用生产接口时,生产不同类型的对象; 107 | - 简单工厂常配合抽象工厂一起使用; 108 | 109 | ### 场景 110 | - 根据不同条件需求不同的对象; 111 | - 对象实例化的代码经常需要修改; 112 | 113 | ### 实现 114 | 1. 简单工厂:向鞋厂内传入不同的类型(布制),鞋厂会生产出不同类型的鞋子(布鞋); 115 | 2. 抽象工厂:有两座鞋厂:李宁鞋厂、Adidas鞋厂,他们能生产对应各自品牌的鞋子; 116 | 3. 搭配使用:向不同的抽象工厂(李宁)传入不同的类型(运动类型),会生产出对应品牌对应类型的鞋子(李宁运动鞋); 117 | 118 | --- 119 | # 单例模式(Singleton) 120 | ### 介绍 121 | 单例模式:保证同一个类`全局只有一个实例对象`; 122 | 123 | - 在第一次实例化后会使用`静态变量保存`实例,后续全局使用此静态变量; 124 | - 一般将构造方法私有化,构造方法添加 final 关键字无法被重写,添加一个类静态方法用于返回此实例; 125 | - 在多线程时应该考虑`并发`问题,防止两次调用都被判定为实例未初始化而重复初始化对象; 126 | 127 | ### 场景 128 | - 全局共享同一个实例对象(数据库连接等); 129 | - 某一处对此对象的更新全局可见; 130 | 131 | ### 实现 132 | 1. 利用 Go 中包的可见性规则来隐藏对象的实例化权限; 133 | 2. 使用包变量保存实例对象,获取实例时判断是否已实例化,如为nil,实例化对象并返回,如有值,直接返回值; 134 | 3. 待用锁实现 Go routine 并发时的问题; 135 | 136 | ---- 137 | # 命令模式(Command) 138 | ### 介绍 139 | 命令模式:将一个`命令封装成对象`,解耦命令的发起者和执行者。 140 | 141 | - 命令对象实现`命令接口(excute[、undo])`,命令发起者实例化命令对象,并传递此对象,并不关心此对象由谁执行; 142 | - 命令执行者只负责调用命令对象的执行方法即可,不关心对象是由谁生成的; 143 | - 与策略模式不同之处:策略模式是通过不同的算法做同一件事情(例如排序),而命令模式则是通过不同的命令做不同的事情; 144 | 145 | ### 场景 146 | - 命令发起者与执行者无法直接接触; 147 | - 命令需要撤销功能,却不易保存命令执行状态信息时; 148 | 149 | ### 实现 150 | 1. 指挥官创建了一个“从树下跑到草地上”的命令; 151 | 2. 命令被分配给张三执行,张三作为军人,接到命令后不管命令的具体内容,而是直接调用命令的执行接口执行。 152 | 3. 指挥官发布了撤销指令,张三又从草地上跑到了树下。 153 | 154 | --- 155 | # 适配器模式(Adapter) 156 | ### 介绍 157 | 适配器模式:包装对象提供一个接口,以`适配调用者`。 158 | 159 | - 适配器通过一个中间对象,`封装目标接口`以`适应调用者`调用; 160 | - 调用者调用此适配器,以达到调用目标接口的目的; 161 | - 适配器模式与装饰者模式的不同之处:适配器模式不改变接口的功能,而装饰者会添加或修改原接口功能; 162 | 163 | ### 场景 164 | - 提供的接口与调用者调用的其他的接口都不一致; 165 | - 为一个特殊接口修改调用者的调用方式得不偿失; 166 | 167 | ### 实现 168 | 1. 张三是个正常人,他能通过说话直接地表达自己; 169 | 2. 李四是个聋哑人,他没法直接表达自己,但他会写字。 170 | 3. 笔记本作为一个适配器,用笔记本“包装”了李四之后,当李四需要表达自己想法时,调用笔记本的“表达”功能,笔记本再调用李四“写字”的方法。 171 | 172 | --- 173 | # 外观模式(Facade) 174 | ### 介绍 175 | 外观模式:通过`封装多个复杂的接口`来提供一个`简化接口`来实现一个复杂功能。 176 | 177 | - 外观模式是通过封装多个接口来将接口`简单化`; 178 | - 外观模式不会改变原有的多个复杂的单一接口,这些接口依然能被单独调用,只是提供了一个额外的接口; 179 | - 外观模式与适配器模式的不同之处:外观模式是`整合`多个接口并`添加`一个简化接口,适配器是适配一个接口; 180 | 181 | ### 场景 182 | - 实现某一功能需要调用多个复杂接口; 183 | - 经常需要实现此功能, 184 | 185 | ### 实现 186 | 1. 正常的冲咖啡步骤是:磨咖啡豆、烧开水、倒开水搅拌咖啡。 187 | 2. 我们经常需要直接冲咖啡,而不是使用单一步骤,每次喝咖啡时调用三个方法很麻烦; 188 | 3. 封装三个接口,额外提供一个 “冲咖啡” 的方法,需要喝咖啡时只需要调用一次冲咖啡方法即可。 189 | 190 | --- 191 | # 模板模式(Template) 192 | ### 介绍 193 | 模板模式:模板模式在`抽象类或父类`中抽象出`算法步骤`作为模板,模板的具体细节推迟到子类实现。 194 | 195 | - 模板模式在父类或抽象类中定义一个`算法的骨架`,并在父类或抽象类中实现共同的部分,各个不同的步骤由不同的子类分别实现; 196 | - 模板板式在父类的算法步骤中定义`勾子(hook)`,在子类中判断并定义一些不是非通用步骤; 197 | - 模板模式与策略模式的不同之处在于,策略模式是针对多个不同的算法,而模板模式是针对一个算法的不同步骤,在模板模式中,只有一个算法; 198 | 199 | 200 | ### 场景 201 | - 多个算法有多个共同之处,但某些步骤略微不同; 202 | - 各子类步骤顺序一致,但步骤的具体实现有所不同时; 203 | 204 | ### 实现 205 | 1. 有发邮件和发短信两种通讯方式; 206 | 2. 他们都需要获取目标信息、格式化正文、填写发送方信息,但实现不同; 207 | 3. 在信息类中抽象出三个步骤,具体的处理方式由两种通讯方式各自实现; 208 | 4. 发送信息时调用信息类中的发送方法,发送方法会按照顺序自动调用对应的步骤; 209 | 210 | 211 | --- 212 | # 迭代器模式(Iterator) 213 | ### 介绍 214 | 迭代器模式:迭代器模式允许调用者在`不知道类内部实现`的情况下`遍历类元素`。 215 | 216 | - 迭代器接口常用方法有 `length(),next(),previous(),remove()`等; 217 | - 各类在内部实现迭代器接口,用对应的方法操作元素; 218 | - 调用者不考虑类内部实现,调用迭代器接口即可; 219 | 220 | ### 场景 221 | - 类使用不同的数据结构存储数据; 222 | - 需要对不同的数据类型进行遍历等操作; 223 | 224 | ### 实现 225 | 1. 使用 slice 存储一列战马,使用 map 存储一列士兵; 226 | 2. 战马和士兵结构都实现了迭代器接口; 227 | 3. 获取战马数和士兵数,遍历战马和士兵,调用迭代器接口即可; 228 | 229 | 230 | --- 231 | # 组合模式(Composite) 232 | ### 介绍 233 | 组合器模式:使用一种`组件抽象`来同时表达`集合与元素`,使用统一的接口来管理集合和元素。 234 | 235 | - 组合模式通常为`树结构`,父结点和子节点具有同样的抽象和接口; 236 | - 在操作集合时,会`同时操作集合所属的具体元素`; 237 | - 通常给组合模式添加一个迭代器来完成组合结构的迭代; 238 | 239 | ### 场景 240 | - 管理的多个对象构成树型层级结构; 241 | - 操作高层级的对象时,需要同时其所属的下级对象,如界面窗口等; 242 | 243 | ### 实现 244 | 1. 将军、队长、士兵构成树型层级结构,且他们都是战士,拥有战斗方法; 245 | 2. 每位战士都保存着自己的下级名单,没有下级时忽略; 246 | 3. 每个人在战斗时,都会率领着下级战斗; 247 | 248 | --- 249 | # 状态模式(State) 250 | ### 介绍 251 | 状态模式:状态模式抽象出一个`事物的状态`作为类,解耦事物和不同状态下的行为; 252 | 253 | - 状态模式通过替换状态对象作为状态转换的方式; 254 | - 状态对象实现根据状态动作的接口,可以根据不同的`动作做出对应`的反应; 255 | - 状态模式与策略模式的实现相似,但状态模式是对类内部状态作出改变,而策略模式是针对算法封装; 256 | 257 | ### 场景 258 | - 事物有多种状态,且可以相互转换; 259 | - 事物多种状态下对同一动作做出的行为不同; 260 | 261 | ### 实现 262 | 1. 植物有 幼苗、开花和成熟 三种状态,且它们会通过浇水和收获的动作进行相互转换; 263 | 2. 幼苗和开花时不能收获,只能浇水,成熟状态只能收获,不需要再浇水; 264 | 3. 定义三种状态,和它们对不同动作时的行为,植物通过三种对象的替换来进行状态转换; 265 | 266 | 267 | --- 268 | # 代理模式(Proxy) 269 | ### 介绍 270 | 代理模式:给对象提供一个代理,由代理对象控制对原对象的调用; 271 | 272 | - 代理模式为一个对象(通常是大对象或无法复制的对象)`创建另外一个类作为其访问的接口`,所有对真实对象的请求都`通过代理对象`完成; 273 | - 代理对象可以`控制用户对真实对象的访问权限`,也可以在访问真实对象时附加功能; 274 | - 代理模式可被用作:远程代理,虚拟代理,安全代理,指针引用,延迟加载; 275 | 276 | ### 场景 277 | - 对象无法被直接访问时; 278 | - 对象过大,初始化较慢; 279 | - 对象不必要立刻初始化,可使用默认值代替; 280 | 281 | ### 实现 282 | 1. 小明给暗恋对象写了一封信,在等回信; 283 | 2. 邮递员是个非常忙的人,来不及去收取回信; 284 | 3. 小明好声好气向邮递员要回信时,邮递员都推拖说自己要去取; 285 | 4. 小明发怒了,邮递员终于抽时间去取了信给小明; 286 | 5. 此信中邮递员就是代理模式中的代理,他实现了懒加载。 287 | 6. 回信内容见源码:) 288 | 289 | 290 | --- 291 | # 桥接模式(Bridge) 292 | ### 介绍 293 | 桥接模式:将事务的`多个维度`都抽象出来以`解耦抽象与实际`之间的绑定关系,使抽象和实际向着不同维度改变; 294 | 295 | - 桥接模式通过对象的组合来解决事物的多维度变化问题,以替代多继承的不灵活; 296 | - 桥接模式可以轻易在多维度上拓展,而不改变原有模式; 297 | - 桥接模式与策略模式的不同之处:策略模式是针对一个不变的主题替换抽象算法,而桥接模式是策略模式的高维度状态,它的主题也可能会被替换; 298 | 299 | ### 场景 300 | - 某事物在多个维度上都有变化; 301 | - 无法使用多继承或使用多继承会很不灵活; 302 | 303 | ### 实现 304 | 1. 作画时可以使用铅笔和圆珠笔等不同的笔,也可以在宣纸或普通A4纸; 305 | 2. 抽象出笔和纸两种对象; 306 | 3. 自由组合笔和纸进行作画; 307 | 308 | --- 309 | # 建造者模式(Builder) 310 | ### 介绍 311 | 建造者模式:建造者模式`分离创建复杂对象的过程和细节`,使得同样的创建过程能创建不同的对象。 312 | 313 | - 建造者模式将创建对象部件的`一般过程抽象出接口`,而由不同的建造者类实现具体的接口,实现过程的步骤; 314 | - 通过建造者,调用者不用考虑对象创建过程的细节,且建造者也可以被灵活替换; 315 | - 与模板模式的区别:建造者模式使用类的组合进行对象的创建,而模板模式使用类的继承实现对象的具体构造; 316 | - 与工厂模式的区别:工厂模式会返回一个具体类,而建造者模式会建造出一个由多个类组装而成的完整类; 317 | 318 | ### 场景 319 | - 对象的创建包含其他对象为类元素,创建过程复杂; 320 | - 多个复杂对象的创建过程具有高度相似性; 321 | 322 | ### 实现 323 | 1. 中国式建筑有金色屋顶和红色大门,而意式建筑有圆项和白色大门; 324 | 2. 中国建筑师和意式建筑师分别擅长建造不同类型的建筑; 325 | 3. 我们在盖不同类型的房子时先创建一个建筑师,再用建筑师去创建对应风格的房子; 326 | 327 | --- 328 | # 责任链模式(Chain of Responsibility) 329 | ### 介绍 330 | 责任链模式:将`请求处理者串成“链”`,`依次尝试`处理请求,以此解耦请求和处理者; 331 | 332 | - 责任链模式将任务处理者划分先后次序,依次尝试,直到任务被处理; 333 | - 每个处理者`存储自己的下一环`;任务开始时选择最靠前的处理者试图处理任务; 334 | - 在遇到自己无法处理的情况,传递给自己的下一环来处理; 335 | 336 | ### 场景 337 | - 适用于单个任务,多个处理者; 338 | - 需要依次尝试处理者; 339 | 340 | ### 实现 341 | 1. 公司里 leader、经理和CEO有不同额度的报销限额; 342 | 2. leader报销不了的金额交给经理,而经理将自己处理不了的给CEO处理; 343 | 3. 张三要报销200元,leader就能批准; 344 | 4. 李四要报销8000元,leader报销不了,就交给经理,经理也处理不了,最后交给CEO报销; 345 | 346 | --- 347 | # 蝇量模式(Flyweight) 348 | ### 介绍 349 | 蝇量模式:使用`一个对象`来`存储和模拟多个虚拟对象`,大大减少多个对象的内存占用。 350 | 351 | - 实例化多个相似实例会占用较多内存空间,蝇量模式使用一个对象类变量保存多个对象的属性,以一个对象控制多个对象; 352 | - 蝇量模式可以极大地减少内存占用,也可以方便对多个对象进行`统一管理`; 353 | - 实例一旦实现了蝇量模式,那么单个实例就无法再独立拥有不同的行为; 354 | 355 | ### 场景 356 | - 有很多相似对象,拥有相同的属性项和方法; 357 | - 多个对象只会被统一调用; 358 | 359 | ### 实现 360 | - 在一片森林中,有很多大树,他们都只有高度一个属性; 361 | - 将多个大树的属性保存一个森林对象的 map 中; 362 | - 调用森林的砍伐方法,砍伐森林中所有的树; 363 | 364 | --- 365 | # 解释器模式(Intepreter) 366 | ### 介绍 367 | 解释器模式:定义`一种方法和对应的解释器`,使用解释器`解释此方法的语句`来执行; 368 | 369 | - 解释器模式需要上下文类来`定义和存储上下文`,解释器类用来将语句来翻译成可执行程序; 370 | - 解释器扩展和改变文化非常简单,构建完成后可以很方便地数据格式; 371 | - 解释器模式会将非终结表达式`递归解释`,直到解释为终结符表达式; 372 | 373 | ### 场景 374 | - 解释器模式适用于数据结构不规则,但数据要素相同的情况; 375 | - 语法不能太复杂,复杂的最好使用解释形语言来实现以降低复杂性; 376 | 377 | ### 实现 378 | 1. 在php中,php环境是上下文; 379 | 2. 字符串值不能再向下解释了,如 `"hello" "greeting"` 都是终结符; 380 | 3. 在上下文中定义了两个变量 `$greeting = "hello"; $test = "greeting";` 381 | 4. 现在来解释变量 `$$test = "hello" `; 382 | 383 | --- 384 | # 中介者模式(Mediator) 385 | ### 介绍 386 | 中介者模式:通过一个中介对象`封装多个对象之间的交互`,解耦各个对象之前的相互依赖; 387 | 388 | - 对象之间`通过中介者进行交互`,不必再显示调用目标对象; 389 | - 中介者对对象之间的关系进行了封装,减少了对象之间的耦合,使得对象可以独立改变和复用; 390 | - 中介者模式与适配器模式和代理模式的不同之处:三者都通过中间对象解决对象之间的沟通问题,但他们要解决的问题和解决问题的对象都不同; 391 | 392 | ### 场景 393 | - 中介者模式适合多对多的对象交互情况; 394 | - 中介者适合对象之间交互较多,依赖复杂的情况; 395 | 396 | ### 实现 397 | 1. 联合国作为多个国家之间的中间人存在,各国家之间通过联合国沟通; 398 | 2. 法国和韩国尝试通过联合国隔空对话; 399 | 3. 他们双方只向联合国喊话,并从联合国处获取对方国家的回应; 400 | 401 | --- 402 | # 备忘录模式(Memento) 403 | ### 介绍 404 | 备忘录模式:使用一个备忘录对象`记录并保存`对象内部状态,并能`随时恢复`到保存的状态; 405 | 406 | - 备忘录对象是一个类似于目标对象的轻量级对象,它保存着目标对象的可变属性; 407 | - 备忘录保管者可以保存多个备忘录,并将对象恢复到任一时刻; 408 | ### 场景 409 | - 备忘录模式适用于需要保存对象历史状态用以支持撤销的场景; 410 | 411 | ### 实现 412 | 1. 时光掌控者保存着许多人类世界的“时间快照”; 413 | 2. 小明18岁时身高175,体重70,时光掌控者此时获取小明的信息产生了一个快照; 414 | 3. 小明在不停地长大,80岁时身高170,体重65; 415 | 4. 时光掌控者选择小明18岁的快照对小时进行了恢复,小明又回到了18岁; 416 | 417 | --- 418 | # 原型模式(Prototype) 419 | ### 介绍 420 | 原型模式:通过复制`原型对象`再`修改属性`的方式来快速创建新对象; 421 | 422 | - 原型模式通过`抽象多个对象的相同属性和方法`来设置一个原型; 423 | - 原型模式可以通过原型对象设置对象的基本属性,减少创建出的对象的开放; 424 | - 原型模式使得调用者只知道对象的原型而不必了解创建过程即可创建一个新对象; 425 | 426 | ### 场景 427 | - 原型模式适用于对象较大或创建过程较复杂的情况; 428 | - 适用于需要创建多个有共同“原型”的对象,也即它们拥有大部分共同属性; 429 | 430 | ### 实现 431 | 1. 据说国家仪仗队的队员都是 年龄20岁、身高180、体重72kg的男性士兵; 432 | 2. 抽象一个“年龄20岁、身高180、体重72kg”的人作为仪仗队员的“原型”; 433 | 3. 创建一个仪仗队员原型,并设置姓名来产生一个真实的仪仗队员对象; 434 | 435 | 436 | --- 437 | # 访问者模式(Visitor) 438 | ### 介绍 439 | 访问者模式:将对一些对象的`访问过程抽象出类`,以实现在不改变对象的前提下对这些对象添加操作; 440 | 441 | - 访问者模式`分离对象的数据结构和数据操作`; 442 | - 访问者模式将数据的访问方法集中到一个类中作为访问者,便于对数据访问的统一管理; 443 | - 如果数据有添加或删除,需要修改多个访问者; 444 | 445 | ### 场景 446 | - 访问者模式适用于数据结构稳定的类; 447 | - 对对象的同一种数据有多种不同的操作方式; 448 | 449 | ### 实现 450 | 1. 超市里的商品都有 名称和价格 两种属性,顾客使用购物车保存了要买的商品; 451 | 2. 设置一个打印机访问者,访问并打印顾客购物车内的商品名称; 452 | 3. 如果要添加一个商品价格计算器,只需要实现与打印机相同的访问者接口,访问并计算购物车中商品的价格; 453 | --------------------------------------------------------------------------------