├── src ├── main │ ├── java │ │ └── pers │ │ │ └── hai │ │ │ └── sample │ │ │ └── dp │ │ │ ├── observer │ │ │ ├── readme.md │ │ │ ├── framework │ │ │ │ ├── Observer.java │ │ │ │ └── NumberGenerator.java │ │ │ ├── CycleObserver.java │ │ │ ├── DigitObserver.java │ │ │ ├── GraphObserver.java │ │ │ ├── IncrementNumberGenerator.java │ │ │ └── RandomNumberGenerator.java │ │ │ ├── template │ │ │ ├── readme.md │ │ │ ├── AbstractDisplay.java │ │ │ ├── CharDisplay.java │ │ │ └── StringDisplay.java │ │ │ ├── singleton │ │ │ ├── readme.md │ │ │ ├── Settings.java │ │ │ └── Settings2.java │ │ │ ├── factory │ │ │ ├── method │ │ │ │ ├── readme.md │ │ │ │ ├── framework │ │ │ │ │ ├── Product.java │ │ │ │ │ └── Factory.java │ │ │ │ ├── model │ │ │ │ │ └── Account.java │ │ │ │ └── idcard │ │ │ │ │ ├── IDCardFactory.java │ │ │ │ │ └── IDCard.java │ │ │ └── abstr │ │ │ │ ├── FactoryType.java │ │ │ │ ├── framework │ │ │ │ ├── Shape.java │ │ │ │ ├── ShapeFactory.java │ │ │ │ ├── RedShapeFactory.java │ │ │ │ └── BlueShapeFactory.java │ │ │ │ └── shape │ │ │ │ ├── BlueCircularShape.java │ │ │ │ ├── RedCircularShape.java │ │ │ │ ├── BlueSquarenessShape.java │ │ │ │ ├── RedSquarenessShape.java │ │ │ │ ├── CircularShape.java │ │ │ │ └── SquarenessShape.java │ │ │ ├── decorator │ │ │ ├── Border.java │ │ │ ├── Display.java │ │ │ ├── StringDisplay.java │ │ │ ├── FullBorder.java │ │ │ └── SideBorder.java │ │ │ ├── flyweight │ │ │ ├── Shape.java │ │ │ ├── readme.md │ │ │ ├── Circular.java │ │ │ ├── ShapeFactory.java │ │ │ └── Rectangle.java │ │ │ ├── iterator │ │ │ ├── Aggregate.java │ │ │ ├── Iterator.java │ │ │ ├── readme.md │ │ │ ├── Book.java │ │ │ ├── BookShelfIterator.java │ │ │ └── BookShelf.java │ │ │ ├── visitor │ │ │ ├── Visitable.java │ │ │ ├── readme.md │ │ │ ├── Visitor.java │ │ │ ├── FloatElement.java │ │ │ ├── StringElement.java │ │ │ └── ConcreteVisitor.java │ │ │ ├── bridge │ │ │ ├── readme.md │ │ │ ├── DisplayImpl.java │ │ │ ├── CountDisplay.java │ │ │ ├── Display.java │ │ │ └── StringDisplayImpl.java │ │ │ ├── proxy │ │ │ ├── virtual2 │ │ │ │ ├── Printable.java │ │ │ │ ├── PrinterProxy.java │ │ │ │ └── Printer.java │ │ │ ├── readme.md │ │ │ ├── virtual1 │ │ │ │ ├── IStation.java │ │ │ │ ├── ITicketable.java │ │ │ │ ├── NanjingStation.java │ │ │ │ ├── NanjingnanStation.java │ │ │ │ └── StationProxy.java │ │ │ ├── access │ │ │ │ ├── UnauthorizedException.java │ │ │ │ ├── Forum.java │ │ │ │ ├── WriterProxy.java │ │ │ │ ├── TouristProxy.java │ │ │ │ └── ManagerProxy.java │ │ │ └── dynamic │ │ │ │ ├── IStation.java │ │ │ │ ├── ITicketable.java │ │ │ │ ├── model │ │ │ │ ├── StationPort.java │ │ │ │ └── TravelPorts.java │ │ │ │ ├── jdk │ │ │ │ └── DynamicProxyHandler.java │ │ │ │ ├── cglib │ │ │ │ └── CglibProxy.java │ │ │ │ ├── NanjingnanStation.java │ │ │ │ └── NanjingStation.java │ │ │ ├── strategy │ │ │ ├── Strategy.java │ │ │ ├── readme.md │ │ │ ├── WinningStrategy.java │ │ │ ├── Player.java │ │ │ ├── Hand.java │ │ │ └── ProbStrategy.java │ │ │ ├── adapter │ │ │ ├── inherit │ │ │ │ ├── Print.java │ │ │ │ ├── PrintBanner.java │ │ │ │ └── Banner.java │ │ │ ├── entrust │ │ │ │ ├── Print.java │ │ │ │ └── PrintBanner.java │ │ │ └── readme.md │ │ │ ├── command │ │ │ ├── cmd │ │ │ │ ├── Command.java │ │ │ │ ├── AddCommand.java │ │ │ │ ├── DivCommand.java │ │ │ │ ├── MulCommand.java │ │ │ │ └── SubCommand.java │ │ │ ├── CommandAttachable.java │ │ │ ├── Computable.java │ │ │ ├── ComputeResult.java │ │ │ ├── ComputeCore.java │ │ │ └── MobileCalculator.java │ │ │ ├── prototype │ │ │ ├── Product.java │ │ │ ├── Manager.java │ │ │ ├── UnderlinePen.java │ │ │ └── MessageBox.java │ │ │ ├── interpreter │ │ │ ├── Node.java │ │ │ ├── readme.md │ │ │ ├── ParseException.java │ │ │ ├── ProgramNode.java │ │ │ ├── PrimitiveCommandNode.java │ │ │ ├── CommandNode.java │ │ │ ├── RepeatCommandNode.java │ │ │ ├── CommandListNode.java │ │ │ └── Context.java │ │ │ ├── memento │ │ │ ├── readme.md │ │ │ ├── Memento.java │ │ │ └── Gamer.java │ │ │ ├── mediator │ │ │ ├── readme.md │ │ │ ├── Mediator.java │ │ │ ├── Person.java │ │ │ ├── Tenant.java │ │ │ ├── HouseOwner.java │ │ │ └── MediatorStructure.java │ │ │ ├── composite │ │ │ ├── readme.md │ │ │ ├── FileTreatMentException.java │ │ │ ├── Entry.java │ │ │ ├── File.java │ │ │ └── Directory.java │ │ │ ├── cor │ │ │ ├── readme.md │ │ │ ├── NoSupport.java │ │ │ ├── OddSupport.java │ │ │ ├── LimitSupport.java │ │ │ ├── SpecialSupport.java │ │ │ ├── Trouble.java │ │ │ └── Support.java │ │ │ ├── state │ │ │ ├── StateLimitException.java │ │ │ ├── OpenningState.java │ │ │ ├── RunningState.java │ │ │ ├── State.java │ │ │ ├── StoppingState.java │ │ │ ├── ClosingState.java │ │ │ └── Lift.java │ │ │ └── builder │ │ │ ├── Builder.java │ │ │ ├── Director.java │ │ │ ├── TextBuilder.java │ │ │ └── HTMLBuilder.java │ └── resources │ │ └── log4j.properties └── test │ └── java │ └── pers │ └── hai │ └── sample │ └── dp │ ├── Testable.java │ ├── TemplatePatternTest.java │ ├── AdapterTests.java │ ├── FactoryMethodTest.java │ ├── BridgeTests.java │ ├── MediatorTests.java │ ├── ChainTests.java │ ├── FactoryAbstractTest.java │ ├── IteratorTests.java │ ├── StatePatternTest.java │ ├── BuilderTests.java │ ├── ObserverPatternTest.java │ ├── VisitorTests.java │ ├── PrototypeTest.java │ ├── SingletonPatternTest.java │ ├── InterpreterTests.java │ ├── DecoratorPatternTest.java │ ├── MementoTests.java │ ├── StrategyTests.java │ ├── CompositeTests.java │ ├── FlyweightTests.java │ ├── CommandPatternTest.java │ └── ProxyPatternTest.java ├── umls ├── dp-proxy-uml.jpg ├── dp-proxy-uml.vsdx └── dp-state-uml.vsdx ├── .gitignore ├── design.pattern.iml ├── readme.md └── pom.xml /src/main/java/pers/hai/sample/dp/observer/readme.md: -------------------------------------------------------------------------------- 1 | ## Observer Design Pattern -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/template/readme.md: -------------------------------------------------------------------------------- 1 | ## Template Design Pattern -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/singleton/readme.md: -------------------------------------------------------------------------------- 1 | ## Singleton Design Pattern -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/method/readme.md: -------------------------------------------------------------------------------- 1 | ## Factory Method Design Pattern -------------------------------------------------------------------------------- /umls/dp-proxy-uml.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwhai/design-pattern/HEAD/umls/dp-proxy-uml.jpg -------------------------------------------------------------------------------- /umls/dp-proxy-uml.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwhai/design-pattern/HEAD/umls/dp-proxy-uml.vsdx -------------------------------------------------------------------------------- /umls/dp-state-uml.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwhai/design-pattern/HEAD/umls/dp-state-uml.vsdx -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=debug,stdout 2 | 3 | # console 4 | log4j.appender.stdout = org.apache.log4j.ConsoleAppender 5 | log4j.appender.stdout.layout = org.apache.log4j.PatternLayout 6 | log4j.appender.stdout.layout.ConversionPattern = [%d{yyyy-MM-dd HH:mm:ss}]:[%p] %m%n -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/FactoryType.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public enum FactoryType { 10 | CIRCULAR, 11 | SQUARENESS 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/framework/Shape.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.framework; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public interface Shape { 10 | 11 | void show(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/observer/framework/Observer.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.observer.framework; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public interface Observer { 10 | void update(NumberGenerator generator); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/decorator/Border.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.decorator; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 18:01 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public abstract class Border extends Display { } 13 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/flyweight/Shape.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.flyweight; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-03 18:03 7 | * Last Modify: 2019-06-03 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Shape { 13 | void draw(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/iterator/Aggregate.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.iterator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 16:42 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Aggregate { 13 | Iterator iterator(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/visitor/Visitable.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.visitor; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 11:15 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Visitable { 13 | void accept(Visitor visitor); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/bridge/readme.md: -------------------------------------------------------------------------------- 1 | ## Bridge Design Pattern. 2 | 3 | > 桥接模式:将抽象部分与它的实现部分分离,使得它们可以独立地变化。 4 | 5 | ### Ref 6 | - 《图解设计模式》 7 | 8 | ----- 9 | 10 | - [CSDN](https://qwhai.blog.csdn.net/) 11 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 12 | - [Github](https://github.com/qwhai) 13 | - [E-mail](return_zero0@163.com) 14 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/iterator/Iterator.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.iterator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 16:39 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Iterator { 13 | boolean hasNext(); 14 | Object next(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/virtual2/Printable.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.virtual2; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-07 18:04 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Printable { 13 | 14 | void print(String content); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/framework/ShapeFactory.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.framework; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public interface ShapeFactory { 10 | 11 | Shape createSquareness(); 12 | 13 | Shape createCircular(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/iterator/readme.md: -------------------------------------------------------------------------------- 1 | ## Iterator Design Pattern. 2 | 3 | > 迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。 4 | 5 | ### Ref 6 | - 《图解设计模式》 7 | 8 | ----- 9 | 10 | - [CSDN](https://qwhai.blog.csdn.net/) 11 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 12 | - [Github](https://github.com/qwhai) 13 | - [E-mail](return_zero0@163.com) 14 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/strategy/Strategy.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.strategy; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 18:25 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Strategy { 13 | Hand nextHand(); 14 | void study(boolean win); 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | /.idea 25 | /target 26 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/adapter/inherit/Print.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.adapter.inherit; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 17:25 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Print { 13 | void printWeak(); 14 | void printStrong(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/readme.md: -------------------------------------------------------------------------------- 1 | ## Proxy Design Pattern 2 | 3 | > 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 4 | 5 | 以上是代理模式的定义。从定义我们可以剖析出代理模式的使用场景: 6 | 1. 一个对象不适合直接引用另一个对象 7 | 2. 一个对象不能直接引用另一个对象 8 | 9 | 本文将围绕这两种场景张开讲解。 10 | 11 | ------------ 12 | 13 | 本文关键点备忘 14 | 15 | ```$xslt 16 | 两种场景:静态代理 动态代理 17 | 类图 代理需要为实际对象减负 提高扩展性 代理细节(包括执行顺序等) 18 | 代理更常用的场景:RPC/RMI 19 | ``` -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/cmd/Command.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command.cmd; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-20 10:28 7 | * Last Modify: 2019-05-20 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Command { 13 | void calculate(); 14 | void undo(); 15 | void redo(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/prototype/Product.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.prototype; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019/5/21 21:41 7 | * Last Modify: 2019/5/21 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Product extends Cloneable { 13 | void use(String s); 14 | Product createClone(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/method/framework/Product.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.method.framework; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public abstract class Product { 10 | 11 | public abstract void recharge(double x); 12 | 13 | public abstract void use(double x); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/interpreter/Node.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.interpreter; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:42 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public abstract class Node { 13 | public abstract void parse(Context context) throws ParseException; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/memento/readme.md: -------------------------------------------------------------------------------- 1 | ## Memento Design Pattern. 2 | 3 | > 备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 4 | 5 | ### Ref 6 | - 《图解设计模式》 7 | 8 | ----- 9 | 10 | - [CSDN](https://qwhai.blog.csdn.net/) 11 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 12 | - [Github](https://github.com/qwhai) 13 | - [E-mail](return_zero0@163.com) 14 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/virtual1/IStation.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.virtual1; 2 | 3 | /** 4 | * 车站接口 5 | * 6 | * Create Time: 2019-04-05 22:23 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface IStation extends ITicketable { 13 | int ticketSurplus(String start, String end); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/visitor/readme.md: -------------------------------------------------------------------------------- 1 | ## Visitor Design Pattern. 2 | 3 | > 访问者模式:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 4 | 5 | ### Ref 6 | - 《23种Java设计模式》 7 | 8 | ----- 9 | 10 | - [CSDN](https://qwhai.blog.csdn.net/) 11 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 12 | - [Github](https://github.com/qwhai) 13 | - [E-mail](return_zero0@163.com) 14 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/Testable.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-05-20 14:46 9 | * Last Modify: 2019-05-20 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | class Testable { 15 | final Logger logger = Logger.getLogger(Testable.class); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/mediator/readme.md: -------------------------------------------------------------------------------- 1 | ## Mediator Design Pattern. 2 | 3 | > 中介者模式:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。 4 | 5 | ### Ref 6 | - 《图解设计模式》 7 | 8 | ----- 9 | 10 | - [CSDN](https://qwhai.blog.csdn.net/) 11 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 12 | - [Github](https://github.com/qwhai) 13 | - [E-mail](return_zero0@163.com) 14 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/mediator/Mediator.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.mediator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 14:28 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public abstract class Mediator { 13 | //申明一个联络方法 14 | public abstract void constact(String message, Person person); 15 | } -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/adapter/entrust/Print.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.adapter.entrust; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 17:34 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public abstract class Print { 13 | public abstract void printWeak(); 14 | public abstract void printStrong(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/interpreter/readme.md: -------------------------------------------------------------------------------- 1 | ## Interpreter Design Pattern. 2 | 3 | > 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用这个表示来解释语言中的句子。 4 | 5 | ### 应用场景 6 | 7 | 8 | ### Ref 9 | - 《图解设计模式》 10 | 11 | ----- 12 | 13 | - [CSDN](https://qwhai.blog.csdn.net/) 14 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 15 | - [Github](https://github.com/qwhai) 16 | - [E-mail](return_zero0@163.com) 17 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/interpreter/ParseException.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.interpreter; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:50 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class ParseException extends Exception { 13 | public ParseException(String message) { 14 | super(message); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/bridge/DisplayImpl.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.bridge; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 17:56 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public abstract class DisplayImpl { 13 | public abstract void rawOpen(); 14 | public abstract void rawPrint(); 15 | public abstract void rawClose(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/adapter/readme.md: -------------------------------------------------------------------------------- 1 | ## Adapter Design Pattern. 2 | 3 | > 适配器模式:将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 4 | 5 | - entrust -- 基于委托实现的适配器模式 6 | - inherit -- 基于继承实现的适配器模式 7 | 8 | ### Ref 9 | - 《图解设计模式》 10 | 11 | ----- 12 | 13 | - [CSDN](https://qwhai.blog.csdn.net/) 14 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 15 | - [Github](https://github.com/qwhai) 16 | - [E-mail](return_zero0@163.com) 17 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/CommandAttachable.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command; 2 | 3 | import pers.hai.sample.dp.command.cmd.Command; 4 | 5 | /** 6 | * 可附加命令 7 | * 8 | * Create Time: 2019-05-20 15:03 9 | * Last Modify: 2019-05-20 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public interface CommandAttachable { 15 | void attachUndo(Command command); 16 | void attachRedo(Command command); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/composite/readme.md: -------------------------------------------------------------------------------- 1 | ## Composite Design Pattern. 2 | 3 | > 组合模式:将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 4 | 5 | ### Ref 6 | - 《图解设计模式》 7 | 8 | ----- 9 | 10 | - [CSDN](https://qwhai.blog.csdn.net/) 11 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 12 | - 《[Java设计模式--组合模式](https://qwhai.blog.csdn.net/article/details/51437883)》 13 | - [Github](https://github.com/qwhai) 14 | - [E-mail](return_zero0@163.com) 15 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/strategy/readme.md: -------------------------------------------------------------------------------- 1 | ## Strategy Design Pattern. 2 | 3 | > 策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。 4 | 5 | ### Ref 6 | - 《图解设计模式》 7 | 8 | ----- 9 | 10 | - [CSDN](https://qwhai.blog.csdn.net/) 11 | - 《[Java设计模式--策略模式](https://qwhai.blog.csdn.net/article/details/45894511)》 12 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 13 | - [Github](https://github.com/qwhai) 14 | - [E-mail](return_zero0@163.com) 15 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/Computable.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command; 2 | 3 | /** 4 | * 表示可计算接口 5 | * 6 | * Create Time: 2019-05-20 10:30 7 | * Last Modify: 2019-05-20 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public interface Computable { 13 | void add(double x); 14 | void sub(double x); 15 | void mul(double x); 16 | void div(double x); 17 | 18 | void undo(); 19 | void redo(); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/visitor/Visitor.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.visitor; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-06-14 11:17 9 | * Last Modify: 2019-06-14 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public interface Visitor { 15 | void visitString(StringElement stringE); 16 | void visitFloat(FloatElement floatE); 17 | void visitCollection(Collection collection); 18 | } -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/composite/FileTreatMentException.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.composite; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-30 09:50 7 | * Last Modify: 2019-05-30 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class FileTreatMentException extends RuntimeException { 13 | public FileTreatMentException() { } 14 | public FileTreatMentException(String msg) { 15 | super(msg); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/mediator/Person.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.mediator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 14:28 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public abstract class Person { 13 | protected String name; 14 | Mediator mediator; 15 | 16 | Person(String name, Mediator mediator){ 17 | this.name = name; 18 | this.mediator = mediator; 19 | } 20 | } -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/ComputeResult.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-05-20 11:50 7 | * Last Modify: 2019-05-20 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | class ComputeResult { 13 | private double result = 0; 14 | 15 | double getResult() { 16 | return result; 17 | } 18 | 19 | void setResult(double result) { 20 | this.result = result; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/cor/readme.md: -------------------------------------------------------------------------------- 1 | ## Chain of Responsibility Design Pattern. 2 | 3 | > 责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 4 | 5 | ### 应用场景 6 | 1. 在控件相互嵌套的界面程序中,当传递来了一个事件消息,这个消息在何处被传递,何处被消费。这就是一个责任链模式。 7 | 8 | 9 | ### Ref 10 | - 《图解设计模式》 11 | 12 | ----- 13 | 14 | - [CSDN](https://qwhai.blog.csdn.net/) 15 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 16 | - [Github](https://github.com/qwhai) 17 | - [E-mail](return_zero0@163.com) 18 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/cor/NoSupport.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.cor; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:15 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class NoSupport extends Support { 13 | 14 | public NoSupport(String name) { 15 | super(name); 16 | } 17 | 18 | @Override 19 | protected boolean resolve(Trouble trouble) { 20 | return false; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/state/StateLimitException.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.state; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 17:00 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class StateLimitException extends RuntimeException { 13 | 14 | public StateLimitException() { 15 | super(); 16 | } 17 | 18 | public StateLimitException(String message) { 19 | super(message); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/builder/Builder.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.builder; 2 | 3 | /** 4 | * 定义决定文档结构的方法的抽象类 5 | * 6 | * Create Time: 2019/5/25 23:19 7 | * Last Modify: 2019/5/25 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public abstract class Builder { 13 | public abstract void makeTitle(String title); 14 | public abstract void makeString(String content); 15 | public abstract void makeItems(String[] items); 16 | public abstract void close(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/observer/framework/NumberGenerator.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.observer.framework; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public interface NumberGenerator { 10 | 11 | void generate(); 12 | 13 | void registerChangedObserver(Observer observer); 14 | void registerCycleObserver(Observer observer, int t); 15 | void publish(); 16 | 17 | String getName(); 18 | int getNumber(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/access/UnauthorizedException.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.access; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-07 22:27 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class UnauthorizedException extends Exception { 13 | 14 | public UnauthorizedException() { 15 | super(); 16 | } 17 | 18 | public UnauthorizedException(String message) { 19 | super(message); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/cor/OddSupport.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.cor; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:18 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class OddSupport extends Support { 13 | 14 | public OddSupport(String name) { 15 | super(name); 16 | } 17 | 18 | @Override 19 | protected boolean resolve(Trouble trouble) { 20 | return 1 == trouble.getNumber() % 2; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/shape/BlueCircularShape.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.shape; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * Last Modify: 2019-05-24 7 | * 8 | * @author Q-WHai 9 | * @see https://github.com/qwhai 10 | */ 11 | public class BlueCircularShape extends CircularShape { 12 | 13 | private final Logger logger = Logger.getLogger(BlueCircularShape.class); 14 | 15 | @Override 16 | public void show() { 17 | logger.info("创建了一个蓝色的圆形"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/shape/RedCircularShape.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.shape; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * Last Modify: 2019-05-24 7 | * 8 | * @author Q-WHai 9 | * @see https://github.com/qwhai 10 | */ 11 | public class RedCircularShape extends CircularShape { 12 | 13 | private final Logger logger = Logger.getLogger(RedCircularShape.class); 14 | 15 | @Override 16 | public void show() { 17 | logger.info("创建了一个红色的圆形"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/TemplatePatternTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import pers.hai.sample.dp.template.AbstractDisplay; 4 | import pers.hai.sample.dp.template.CharDisplay; 5 | import pers.hai.sample.dp.template.StringDisplay; 6 | import org.junit.Test; 7 | 8 | public class TemplatePatternTest { 9 | 10 | @Test 11 | public void testTemplate() { 12 | AbstractDisplay d1 = new CharDisplay('A'); 13 | d1.display(); 14 | 15 | AbstractDisplay d2 = new StringDisplay("Hello, World"); 16 | d2.display(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/shape/BlueSquarenessShape.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.shape; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * Last Modify: 2019-05-24 7 | * 8 | * @author Q-WHai 9 | * @see https://github.com/qwhai 10 | */ 11 | public class BlueSquarenessShape extends SquarenessShape { 12 | 13 | private final Logger logger = Logger.getLogger(BlueCircularShape.class); 14 | 15 | @Override 16 | public void show() { 17 | logger.info("创建了一个蓝色的方形"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/shape/RedSquarenessShape.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.shape; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * Last Modify: 2019-05-24 7 | * 8 | * @author Q-WHai 9 | * @see https://github.com/qwhai 10 | */ 11 | public class RedSquarenessShape extends SquarenessShape { 12 | 13 | private final Logger logger = Logger.getLogger(RedSquarenessShape.class); 14 | 15 | @Override 16 | public void show() { 17 | logger.info("创建了一个红色的方形"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/shape/CircularShape.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.shape; 2 | 3 | import pers.hai.sample.dp.factory.abstr.framework.Shape; 4 | import org.apache.log4j.Logger; 5 | 6 | /** 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class CircularShape implements Shape { 13 | 14 | private final Logger logger = Logger.getLogger(CircularShape.class); 15 | 16 | @Override 17 | public void show() { 18 | logger.info("创建了一个圆形"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/dynamic/IStation.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.dynamic; 2 | 3 | import pers.hai.sample.dp.proxy.dynamic.model.StationPort; 4 | 5 | /** 6 | * 车站接口 7 | * 8 | * Create Time: 2019-04-10 10:47 9 | * Last Modify: 2019-05-24 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public interface IStation extends ITicketable { 15 | 16 | // 余票查询 17 | int ticketSurplus(StationPort from, StationPort to); 18 | 19 | // 修正余票信息 20 | void amendTicketSurplus(StationPort from, StationPort to); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/template/AbstractDisplay.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.template; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public abstract class AbstractDisplay { 10 | 11 | public abstract void open(); 12 | 13 | public abstract void print(); 14 | 15 | public abstract void close(); 16 | 17 | public final void display() { 18 | open(); 19 | for (int i = 0; i < 5; i++){ 20 | print(); 21 | } 22 | 23 | close(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/shape/SquarenessShape.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.shape; 2 | 3 | import pers.hai.sample.dp.factory.abstr.framework.Shape; 4 | import org.apache.log4j.Logger; 5 | 6 | /** 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class SquarenessShape implements Shape { 13 | 14 | private final Logger logger = Logger.getLogger(SquarenessShape.class); 15 | 16 | @Override 17 | public void show() { 18 | logger.info("创建了一个方形"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/decorator/Display.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.decorator; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 18:01 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public abstract class Display { 13 | 14 | abstract int getRows(); 15 | abstract int getColumns(); 16 | abstract String getRowText(int row); 17 | 18 | public void show() { 19 | for (int i = 0; i < getRows(); i++) { 20 | System.out.println(getRowText(i)); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/bridge/CountDisplay.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.bridge; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 17:58 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class CountDisplay extends Display { 13 | 14 | public CountDisplay(DisplayImpl impl) { 15 | super(impl); 16 | } 17 | 18 | public void multiDisplay(int times) { 19 | open(); 20 | for (int i = 0; i < times; i++) { 21 | print(); 22 | } 23 | close(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/method/framework/Factory.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.method.framework; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public abstract class Factory { 10 | 11 | public Product create(String name) { 12 | Product product = createProduct(name); 13 | registerProduct(product); 14 | 15 | return product; 16 | } 17 | 18 | protected abstract Product createProduct(String name); 19 | 20 | protected abstract void registerProduct(Product product); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/iterator/Book.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.iterator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 16:40 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class Book { 13 | 14 | private String name; 15 | 16 | public Book(String name) { 17 | this.name = name; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return String.format("《%s》", getName()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/cor/LimitSupport.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.cor; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:16 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class LimitSupport extends Support { 13 | 14 | private int limit; 15 | 16 | public LimitSupport(String name, int limit) { 17 | super(name); 18 | this.limit = limit; 19 | } 20 | 21 | @Override 22 | protected boolean resolve(Trouble trouble) { 23 | return trouble.getNumber() < limit; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/observer/CycleObserver.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.observer; 2 | 3 | import pers.hai.sample.dp.observer.framework.NumberGenerator; 4 | import pers.hai.sample.dp.observer.framework.Observer; 5 | 6 | /** 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class CycleObserver implements Observer { 13 | 14 | @Override 15 | public void update(NumberGenerator generator) { 16 | System.out.println(String.format("Cycle Observer 接收到 %s 发布的更新:%d", generator.getName(), generator.getNumber())); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/observer/DigitObserver.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.observer; 2 | 3 | import pers.hai.sample.dp.observer.framework.NumberGenerator; 4 | import pers.hai.sample.dp.observer.framework.Observer; 5 | 6 | /** 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class DigitObserver implements Observer { 13 | 14 | @Override 15 | public void update(NumberGenerator generator) { 16 | System.out.println(String.format("Digit Observer 接收到 %s 发布的更新:%d", generator.getName(), generator.getNumber())); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/cor/SpecialSupport.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.cor; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:20 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class SpecialSupport extends Support { 13 | 14 | private int number; 15 | 16 | public SpecialSupport(String name, int number) { 17 | super(name); 18 | this.number = number; 19 | } 20 | 21 | @Override 22 | protected boolean resolve(Trouble trouble) { 23 | return trouble.getNumber() == number; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/cor/Trouble.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.cor; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:07 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class Trouble { 13 | 14 | private int number; 15 | 16 | public Trouble(int number) { 17 | this.number = number; 18 | } 19 | 20 | public int getNumber() { 21 | return this.number; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return String.format("[Trouble %d]", this.number); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/adapter/inherit/PrintBanner.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.adapter.inherit; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 17:25 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class PrintBanner extends Banner implements Print { 13 | 14 | public PrintBanner(String name) { 15 | super(name); 16 | } 17 | 18 | @Override 19 | public void printWeak() { 20 | showWithParen(); 21 | } 22 | 23 | @Override 24 | public void printStrong() { 25 | showWithAster(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/ComputeCore.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-20 10:45 7 | * Last Modify: 2019-05-20 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | class ComputeCore { 13 | 14 | double add(double x, double y) { 15 | return x + y; 16 | } 17 | 18 | double sub(double x, double y) { 19 | return x - y; 20 | } 21 | 22 | double mul(double x, double y) { 23 | return x * y; 24 | } 25 | 26 | double div(double x, double y) { 27 | return x / y; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/flyweight/readme.md: -------------------------------------------------------------------------------- 1 | ## Flyweight Design Pattern. 2 | 3 | > 享元模式:运用共享技术有效地支持大量细粒度的对象。 4 | 5 | ### 应用场景 6 | 7 | > 如果一个应用使用了大量的对象,而大量的这些对象产生了很大的存储开销时就应该考虑使用;还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。 8 | > 9 | > 1. 字符串的对象池 10 | 11 | ### Ref 12 | - 《大话设计模式》 13 | - [https://www.runoob.com/design-pattern/flyweight-pattern.html](https://www.runoob.com/design-pattern/flyweight-pattern.html) 14 | 15 | ----- 16 | 17 | - [CSDN](https://qwhai.blog.csdn.net/) 18 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 19 | - [Github](https://github.com/qwhai) 20 | - [E-mail](return_zero0@163.com) 21 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/visitor/FloatElement.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.visitor; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 11:17 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class FloatElement implements Visitable { 13 | 14 | private Float value; 15 | public FloatElement(Float value) { 16 | this.value = value; 17 | } 18 | 19 | Float getValue(){ 20 | return value; 21 | } 22 | 23 | //定义 accept 的具体内容 这里是很简单的一句调用 24 | public void accept(Visitor visitor) { 25 | visitor.visitFloat(this); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/visitor/StringElement.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.visitor; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 11:17 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class StringElement implements Visitable { 13 | 14 | private String value; 15 | public StringElement(String string) { 16 | value = string; 17 | } 18 | 19 | String getValue(){ 20 | return value; 21 | } 22 | 23 | //定义 accept 的具体内容 这里是很简单的一句调用 24 | public void accept(Visitor visitor) { 25 | visitor.visitString(this); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/method/model/Account.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.method.model; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public class Account { 10 | 11 | private String name; 12 | private double balance; 13 | 14 | public String getName() { 15 | return name; 16 | } 17 | 18 | public void setName(String name) { 19 | this.name = name; 20 | } 21 | 22 | public double getBalance() { 23 | return balance; 24 | } 25 | 26 | public void setBalance(double balance) { 27 | this.balance = balance; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/template/CharDisplay.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.template; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public class CharDisplay extends AbstractDisplay { 10 | private char _ch; 11 | 12 | public CharDisplay(char ch){ 13 | this._ch = ch; 14 | } 15 | 16 | @Override 17 | public void open() { 18 | System.out.print("<<"); 19 | } 20 | 21 | @Override 22 | public void print() { 23 | System.out.print(this._ch); 24 | } 25 | 26 | @Override 27 | public void close() { 28 | System.out.println(">>"); 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/framework/RedShapeFactory.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.framework; 2 | 3 | import pers.hai.sample.dp.factory.abstr.shape.RedCircularShape; 4 | import pers.hai.sample.dp.factory.abstr.shape.RedSquarenessShape; 5 | 6 | /** 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class RedShapeFactory implements ShapeFactory { 13 | 14 | @Override 15 | public Shape createCircular() { 16 | return new RedCircularShape(); 17 | } 18 | 19 | @Override 20 | public Shape createSquareness() { 21 | return new RedSquarenessShape(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/singleton/Settings.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.singleton; 2 | 3 | import java.util.UUID; 4 | 5 | /** 6 | * Last Modify: 2019-05-24 7 | * 8 | * @author Q-WHai 9 | * @see https://github.com/qwhai 10 | */ 11 | public class Settings { 12 | 13 | private String uuid; 14 | 15 | private static Settings instance; 16 | 17 | public static Settings getInstance() { 18 | if (null == instance) instance = new Settings(); 19 | 20 | return instance; 21 | } 22 | 23 | public String getUuid() { 24 | return uuid; 25 | } 26 | 27 | private Settings() 28 | { 29 | uuid = UUID.randomUUID().toString(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/prototype/Manager.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.prototype; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * TODO 8 | *

9 | * Create Time: 2019/5/21 21:42 10 | * Last Modify: 2019/5/21 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class Manager { 16 | 17 | private Map showcase = new HashMap<>(); 18 | 19 | public void register(String name, Product proto) { 20 | showcase.put(name, proto); 21 | } 22 | 23 | public Product create(String protoName) { 24 | Product p = (Product) showcase.get(protoName); 25 | return p.createClone(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/abstr/framework/BlueShapeFactory.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.abstr.framework; 2 | 3 | import pers.hai.sample.dp.factory.abstr.shape.BlueCircularShape; 4 | import pers.hai.sample.dp.factory.abstr.shape.BlueSquarenessShape; 5 | 6 | /** 7 | * TODO 8 | * 9 | * Last Modify: 2019-05-24 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class BlueShapeFactory implements ShapeFactory { 15 | 16 | @Override 17 | public Shape createSquareness() { 18 | return new BlueSquarenessShape(); 19 | } 20 | 21 | @Override 22 | public Shape createCircular() { 23 | return new BlueCircularShape(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/adapter/entrust/PrintBanner.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.adapter.entrust; 2 | 3 | import pers.hai.sample.dp.adapter.inherit.Banner; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-05-29 17:34 9 | * Last Modify: 2019-05-29 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class PrintBanner extends Print { 15 | 16 | private Banner banner; 17 | 18 | public PrintBanner(String name) { 19 | banner = new Banner(name); 20 | } 21 | 22 | @Override 23 | public void printWeak() { 24 | banner.showWithParen(); 25 | } 26 | 27 | @Override 28 | public void printStrong() { 29 | banner.showWithAster(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/interpreter/ProgramNode.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.interpreter; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:46 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class ProgramNode extends Node { 13 | 14 | private Node commandListNode; 15 | 16 | @Override 17 | public void parse(Context context) throws ParseException { 18 | context.skipToken("program"); 19 | commandListNode = new CommandListNode(); 20 | commandListNode.parse(context); 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return String.format("[program %s]", commandListNode); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/bridge/Display.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.bridge; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 17:53 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class Display { 13 | private DisplayImpl impl; 14 | public Display(DisplayImpl impl) { 15 | this.impl = impl; 16 | } 17 | 18 | public void open() { 19 | impl.rawOpen(); 20 | } 21 | 22 | public void print() { 23 | impl.rawPrint(); 24 | } 25 | 26 | public void close() { 27 | impl.rawClose(); 28 | } 29 | 30 | public final void display() { 31 | open(); 32 | print(); 33 | close(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/decorator/StringDisplay.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.decorator; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 18:01 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class StringDisplay extends Display { 13 | 14 | private String content; 15 | 16 | public StringDisplay(String content) { 17 | this.content = content; 18 | } 19 | 20 | @Override 21 | int getRows() { 22 | return 1; 23 | } 24 | 25 | @Override 26 | int getColumns() { 27 | return content.length(); 28 | } 29 | 30 | @Override 31 | String getRowText(int row) { 32 | return 0 == row ? content : null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/adapter/inherit/Banner.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.adapter.inherit; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-05-29 17:22 9 | * Last Modify: 2019-05-29 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class Banner { 15 | 16 | private final Logger logger = Logger.getLogger(Banner.class); 17 | 18 | private String name; 19 | 20 | public Banner(String name) { 21 | this.name = name; 22 | } 23 | 24 | public void showWithParen() { 25 | logger.info(String.format("(%s)", name)); 26 | } 27 | 28 | public void showWithAster() { 29 | logger.info(String.format("*%s*", name)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/observer/GraphObserver.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.observer; 2 | 3 | import pers.hai.sample.dp.observer.framework.NumberGenerator; 4 | import pers.hai.sample.dp.observer.framework.Observer; 5 | 6 | /** 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class GraphObserver implements Observer { 13 | 14 | @Override 15 | public void update(NumberGenerator generator) { 16 | StringBuilder sb = new StringBuilder(); 17 | for (int i = 0; i < generator.getNumber(); i++) { 18 | sb.append("*"); 19 | } 20 | System.out.println(String.format("Graph Observer 接收到 %s 发布的更新:%s", generator.getName(), sb.toString())); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/virtual1/ITicketable.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.virtual1; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * 可售票的 8 | * 9 | * Create Time: 2019-04-05 22:54 10 | * Last Modify: 2019-05-24 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public interface ITicketable { 16 | 17 | Map ticketMap = new HashMap() { 18 | { 19 | put("nanjing|shanghaihongqiao", 139.5); 20 | put("nanjingnan|shanghaihongqiao", 144.5); 21 | put("wuhan|changshanan", 164.5); 22 | } 23 | }; 24 | 25 | double ticketPrice(String start, String end); 26 | void booking(String start, String end); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/access/Forum.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.access; 2 | 3 | /** 4 | * 角色 5 | * 1.root 6 | * 2.管理员 7 | * 3.作者 8 | * 4.访客 9 | * 10 | * Create Time: 2019-04-07 20:08 11 | * Last Modify: 2019-05-24 12 | * 13 | * @author Q-WHai 14 | * @see https://github.com/qwhai 15 | */ 16 | public interface Forum { 17 | 18 | void visit() throws UnauthorizedException; // 访问 19 | void comment() throws UnauthorizedException; // 评论 20 | 21 | void createTopic() throws UnauthorizedException; // 创建话题 22 | void moidfyTopic() throws UnauthorizedException; // 更新话题 23 | void deleteTopic() throws UnauthorizedException; // 删除话题 24 | 25 | boolean auditTopic(String topicId) throws UnauthorizedException; // 审核话题 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/composite/Entry.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.composite; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-30 09:39 7 | * Last Modify: 2019-05-30 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public abstract class Entry { 13 | public abstract String getName(); 14 | public abstract int getSize(); 15 | public Entry add(Entry entry) throws FileTreatMentException { 16 | throw new FileTreatMentException(); 17 | } 18 | 19 | public void printList() { 20 | printList(""); 21 | } 22 | 23 | protected abstract void printList(String prefix); 24 | 25 | @Override 26 | public String toString() { 27 | return String.format("%s (%d)", getName(), getSize()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/memento/Memento.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.memento; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * TODO 8 | *

9 | * Create Time: 2019-06-13 17:10 10 | * Last Modify: 2019-06-13 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class Memento { 16 | 17 | private int money; 18 | private List fruits; 19 | 20 | public int getMoney() { 21 | return this.money; 22 | } 23 | 24 | public Memento(int money) { 25 | this.money = money; 26 | this.fruits = new ArrayList<>(); 27 | } 28 | 29 | void addFruit(String fruit) { 30 | fruits.add(fruit); 31 | } 32 | 33 | List getFruits() { 34 | return fruits; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/AdapterTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-05-29 17:27 9 | * Last Modify: 2019-05-29 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class AdapterTests extends Testable { 15 | 16 | @Test 17 | public void test1() { 18 | pers.hai.sample.dp.adapter.inherit.Print p = new pers.hai.sample.dp.adapter.inherit.PrintBanner("Hello"); 19 | p.printWeak(); 20 | p.printStrong(); 21 | } 22 | 23 | @Test 24 | public void test2() { 25 | pers.hai.sample.dp.adapter.entrust.Print p = new pers.hai.sample.dp.adapter.entrust.PrintBanner("Hello"); 26 | p.printWeak(); 27 | p.printStrong(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/FactoryMethodTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import pers.hai.sample.dp.factory.method.framework.Factory; 4 | import pers.hai.sample.dp.factory.method.framework.Product; 5 | import pers.hai.sample.dp.factory.method.idcard.IDCardFactory; 6 | import org.junit.Test; 7 | 8 | import java.util.List; 9 | 10 | public class FactoryMethodTest { 11 | 12 | @Test 13 | public void IDCardFactoryTest() { 14 | Factory factory = new IDCardFactory(); 15 | 16 | Product p1 = factory.create("小明"); 17 | p1.recharge(500); 18 | p1.use(100); 19 | 20 | Product p2 = factory.create("小红"); 21 | p2.recharge(550); 22 | p2.use(300); 23 | 24 | List owners = ((IDCardFactory) factory).getOwners(); 25 | System.out.println(owners.size()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/state/OpenningState.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.state; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 16:44 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class OpenningState extends State { 13 | 14 | @Override 15 | public void open() { 16 | logger.info("电梯正在开门..."); 17 | } 18 | 19 | @Override 20 | public void close() { 21 | this.context.switchState(Lift.closingState); 22 | this.context.close(); 23 | } 24 | 25 | @Override 26 | public void run() { 27 | throw new StateLimitException("电梯正在开门,无法运行"); 28 | } 29 | 30 | @Override 31 | public void stop() { 32 | throw new StateLimitException("电梯正在开门,无法停止"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/interpreter/PrimitiveCommandNode.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.interpreter; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:50 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class PrimitiveCommandNode extends Node { 13 | 14 | private String name; 15 | 16 | @Override 17 | public void parse(Context context) throws ParseException { 18 | name = context.currentToken(); 19 | context.skipToken(name); 20 | if (!name.equals("go") && !name.equals("right") && !name.equals("left")) 21 | throw new ParseException(String.format("%s is undefined.", name)); 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return name; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/state/RunningState.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.state; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 16:46 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class RunningState extends State { 13 | 14 | @Override 15 | public void open() { 16 | throw new StateLimitException("电梯正在运行,无法进行开门操作"); 17 | } 18 | 19 | @Override 20 | public void close() { 21 | throw new StateLimitException("电梯正在运行,无法进行关门操作"); 22 | } 23 | 24 | @Override 25 | public void run() { 26 | logger.info("电梯正在运行中..."); 27 | } 28 | 29 | @Override 30 | public void stop() { 31 | this.context.switchState(Lift.stoppingState); 32 | this.context.stop(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/iterator/BookShelfIterator.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.iterator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 16:45 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class BookShelfIterator implements Iterator { 13 | 14 | private BookShelf bookShelf; 15 | private int index; 16 | 17 | public BookShelfIterator(BookShelf bookShelf) { 18 | this.bookShelf = bookShelf; 19 | index = 0; 20 | } 21 | 22 | @Override 23 | public boolean hasNext() { 24 | return index < bookShelf.getLength(); 25 | } 26 | 27 | @Override 28 | public Object next() { 29 | Book book = bookShelf.getBookAt(index); 30 | index++; 31 | return book; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/state/State.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.state; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * TODO 7 | * 8 | * Create Time: 2019-04-10 16:41 9 | * Last Modify: 2019-05-24 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | abstract class State { 15 | 16 | protected Logger logger = Logger.getLogger(State.class); 17 | protected Lift context; 18 | 19 | void setContext(Lift context) { 20 | this.context = context; 21 | } 22 | 23 | /** 24 | * 开门 25 | */ 26 | abstract void open(); 27 | 28 | /** 29 | * 关门 30 | */ 31 | abstract void close(); 32 | 33 | /** 34 | * 启动 35 | */ 36 | abstract void run(); 37 | 38 | /** 39 | * 停止 40 | */ 41 | abstract void stop(); 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/composite/File.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.composite; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-30 09:41 7 | * Last Modify: 2019-05-30 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class File extends Entry { 13 | 14 | private String name; 15 | private int size; 16 | 17 | public File(String name, int size) { 18 | this.name = name; 19 | this.size = size; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | @Override 28 | public int getSize() { 29 | return size; 30 | } 31 | 32 | @Override 33 | protected void printList(String prefix) { 34 | System.out.println(String.format("%s/%s", prefix, this)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/interpreter/CommandNode.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.interpreter; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:49 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class CommandNode extends Node { 13 | 14 | private Node node; 15 | 16 | @Override 17 | public void parse(Context context) throws ParseException { 18 | if (context.currentToken().equals("repeat")) { 19 | node = new RepeatCommandNode(); 20 | node.parse(context); 21 | } else { 22 | node = new PrimitiveCommandNode(); 23 | node.parse(context); 24 | } 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return node.toString(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/state/StoppingState.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.state; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 16:46 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class StoppingState extends State { 13 | 14 | @Override 15 | public void open() { 16 | this.context.switchState(Lift.openningState); 17 | this.context.open(); 18 | } 19 | 20 | @Override 21 | public void close() { 22 | throw new StateLimitException("电梯已停止,无法关闭"); 23 | } 24 | 25 | @Override 26 | public void run() { 27 | this.context.switchState(Lift.runningState); 28 | this.context.run(); 29 | } 30 | 31 | @Override 32 | public void stop() { 33 | logger.info("电梯已停止运行"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/state/ClosingState.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.state; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 16:45 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class ClosingState extends State { 13 | 14 | @Override 15 | public void open() { 16 | this.context.switchState(Lift.openningState); 17 | this.context.open(); 18 | } 19 | 20 | @Override 21 | public void close() { 22 | logger.info("电梯正在关门,请稍等"); 23 | } 24 | 25 | @Override 26 | public void run() { 27 | this.context.switchState(Lift.runningState); 28 | this.context.run(); 29 | } 30 | 31 | @Override 32 | public void stop() { 33 | throw new StateLimitException("电梯正在关门,无法停止"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/mediator/Tenant.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.mediator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 14:30 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class Tenant extends Person{ 13 | 14 | public Tenant(String name, Mediator mediator) { 15 | super(name, mediator); 16 | } 17 | 18 | /** 19 | * @desc 与中介者联系 20 | * @param message 21 | * @return void 22 | */ 23 | public void constact(String message){ 24 | mediator.constact(message, this); 25 | } 26 | 27 | /** 28 | * @desc 获取信息 29 | * @param message 30 | * @return void 31 | */ 32 | public void getMessage(String message){ 33 | System.out.println("租房者:" + name +",获得信息:" + message); 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/builder/Director.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.builder; 2 | 3 | /** 4 | * 文档类 5 | * 6 | * Create Time: 2019/5/25 23:19 7 | * Last Modify: 2019/5/25 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class Director { 13 | private Builder builder; 14 | 15 | public Director(Builder builder) { 16 | this.builder = builder; 17 | } 18 | 19 | public void construct() { 20 | builder.makeTitle("Greeting"); 21 | builder.makeString("从早上到下午"); 22 | builder.makeItems(new String[] { 23 | "早上好。", 24 | "下午好。" 25 | }); 26 | builder.makeString("晚上"); 27 | builder.makeItems(new String[] { 28 | "晚上好。", 29 | "晚安。" 30 | }); 31 | builder.close(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/strategy/WinningStrategy.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.strategy; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-05-29 18:26 9 | * Last Modify: 2019-05-29 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class WinningStrategy implements Strategy { 15 | 16 | private Random random; 17 | private boolean won = false; 18 | private Hand prevHand; 19 | 20 | public WinningStrategy(int seed) { 21 | random = new Random(seed); 22 | } 23 | 24 | @Override 25 | public Hand nextHand() { 26 | if (!won) 27 | prevHand = Hand.getHand(random.nextInt(3)); 28 | 29 | return prevHand; 30 | } 31 | 32 | @Override 33 | public void study(boolean win) { 34 | won = win; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/mediator/HouseOwner.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.mediator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 14:29 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class HouseOwner extends Person{ 13 | 14 | public HouseOwner(String name, Mediator mediator) { 15 | super(name, mediator); 16 | } 17 | 18 | /** 19 | * @desc 与中介者联系 20 | * @param message 21 | * @return void 22 | */ 23 | public void constact(String message){ 24 | mediator.constact(message, this); 25 | } 26 | 27 | /** 28 | * @desc 获取信息 29 | * @param message 30 | * @return void 31 | */ 32 | public void getMessage(String message){ 33 | System.out.println("房主:" + name +", 获得信息:" + message); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/interpreter/RepeatCommandNode.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.interpreter; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 17:49 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class RepeatCommandNode extends Node { 13 | 14 | private int number; 15 | private Node commandListNode; 16 | 17 | @Override 18 | public void parse(Context context) throws ParseException { 19 | context.skipToken("repeat"); 20 | number = context.currentNumber(); 21 | context.nextToken(); 22 | commandListNode = new CommandListNode(); 23 | commandListNode.parse(context); 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return String.format("[repeat %d %s]", number, commandListNode); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/singleton/Settings2.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.singleton; 2 | 3 | import java.util.UUID; 4 | 5 | /** 6 | * Last Modify: 2019-05-24 7 | * 8 | * @author Q-WHai 9 | * @see https://github.com/qwhai 10 | */ 11 | public class Settings2 { 12 | 13 | private String uuid; 14 | 15 | private volatile static Settings2 instance; 16 | 17 | public static Settings2 getInstance() { 18 | if (null == instance) { 19 | synchronized (Settings2.class) { 20 | if (null == instance) { 21 | instance = new Settings2(); 22 | } 23 | } 24 | } 25 | 26 | return instance; 27 | } 28 | 29 | public String getUuid() { 30 | return uuid; 31 | } 32 | 33 | private Settings2() 34 | { 35 | uuid = UUID.randomUUID().toString(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/BridgeTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.bridge.CountDisplay; 5 | import pers.hai.sample.dp.bridge.Display; 6 | import pers.hai.sample.dp.bridge.StringDisplayImpl; 7 | 8 | /** 9 | * TODO 10 | *

11 | * Create Time: 2019-05-29 18:04 12 | * Last Modify: 2019-05-29 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class BridgeTests { 18 | 19 | @Test 20 | public void test1() { 21 | Display d1 = new Display(new StringDisplayImpl("Hello, China")); 22 | Display d2 = new CountDisplay(new StringDisplayImpl("Hello, World")); 23 | CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello, Universe")); 24 | 25 | d1.display(); 26 | d2.display(); 27 | d3.display(); 28 | d3.multiDisplay(10); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/method/idcard/IDCardFactory.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.method.idcard; 2 | 3 | import pers.hai.sample.dp.factory.method.framework.Factory; 4 | import pers.hai.sample.dp.factory.method.framework.Product; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Last Modify: 2019-05-24 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class IDCardFactory extends Factory { 16 | 17 | private List owners = new ArrayList<>(); 18 | 19 | @Override 20 | public Product createProduct(String name) { 21 | return new IDCard(name); 22 | } 23 | 24 | @Override 25 | public void registerProduct(Product product) { 26 | owners.add(((IDCard)product).getOwner()); 27 | } 28 | 29 | public List getOwners() { 30 | return owners; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/iterator/BookShelf.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.iterator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 16:41 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class BookShelf implements Aggregate { 13 | 14 | private Book[] books; 15 | private int last = 0; 16 | 17 | public BookShelf(int maxSize) { 18 | books = new Book[maxSize]; 19 | } 20 | 21 | public Book getBookAt(int index) { 22 | return books[index]; 23 | } 24 | 25 | public void appendBook(Book book) { 26 | if (last >= books.length) return; 27 | 28 | books[last] = book; 29 | last++; 30 | } 31 | 32 | public int getLength() { 33 | return last; 34 | } 35 | 36 | @Override 37 | public Iterator iterator() { 38 | return new BookShelfIterator(this); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/dynamic/ITicketable.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.dynamic; 2 | 3 | import pers.hai.sample.dp.proxy.dynamic.model.StationPort; 4 | import pers.hai.sample.dp.proxy.dynamic.model.TravelPorts; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * TODO 11 | * 12 | * Create Time: 2019-04-10 10:50 13 | * Last Modify: 2019-05-24 14 | * 15 | * @author Q-WHai 16 | * @see https://github.com/qwhai 17 | */ 18 | public interface ITicketable { 19 | 20 | Map ticketMap = new HashMap() { 21 | { 22 | put(new TravelPorts("南京", "上海虹桥"), 139.5); 23 | put(new TravelPorts("南京南", "上海虹桥"), 144.5); 24 | put(new TravelPorts("武汉", "长沙"), 164.5); 25 | } 26 | }; 27 | 28 | // 票价查询 29 | double ticketPrice(StationPort from, StationPort to); 30 | 31 | // 订票 32 | boolean booking(StationPort from, StationPort to); 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/MediatorTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.mediator.HouseOwner; 5 | import pers.hai.sample.dp.mediator.MediatorStructure; 6 | import pers.hai.sample.dp.mediator.Tenant; 7 | 8 | /** 9 | * TODO 10 | *

11 | * Create Time: 2019-06-14 14:01 12 | * Last Modify: 2019-06-14 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class MediatorTests extends Testable { 18 | 19 | @Test 20 | public void test1() { 21 | MediatorStructure mediator = new MediatorStructure(); 22 | 23 | HouseOwner houseOwner = new HouseOwner("张三", mediator); 24 | Tenant tenant = new Tenant("李四", mediator); 25 | 26 | //中介结构要知道房主和租房者 27 | mediator.setHouseOwner(houseOwner); 28 | mediator.setTenant(tenant); 29 | 30 | tenant.constact("听说你那里有三室的房主出租....."); 31 | houseOwner.constact("是的!请问你需要租吗?"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/ChainTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.cor.*; 5 | 6 | /** 7 | * TODO 8 | *

9 | * Create Time: 2019-06-14 14:46 10 | * Last Modify: 2019-06-14 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class ChainTests extends Testable { 16 | 17 | @Test 18 | public void test1() { 19 | Support alice = new NoSupport("Alice"); 20 | Support bob = new LimitSupport("Bob", 100); 21 | Support charlie = new SpecialSupport("Charlie", 429); 22 | Support diana = new LimitSupport("Diana", 200); 23 | Support elmo = new OddSupport("Elmo"); 24 | Support fred = new LimitSupport("Fred", 300); 25 | 26 | alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred); 27 | 28 | for (int i = 0; i < 500; i+=33) { 29 | alice.support(new Trouble(i)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/template/StringDisplay.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.template; 2 | 3 | /** 4 | * Last Modify: 2019-05-24 5 | * 6 | * @author Q-WHai 7 | * @see https://github.com/qwhai 8 | */ 9 | public class StringDisplay extends AbstractDisplay { 10 | 11 | private int _width; 12 | private String _text; 13 | 14 | public StringDisplay(String text){ 15 | this._text = text; 16 | this._width = this._text.length(); 17 | } 18 | 19 | @Override 20 | public void open() { 21 | printLine(); 22 | } 23 | 24 | @Override 25 | public void print() { 26 | System.out.println("|" + _text + "|"); 27 | } 28 | 29 | @Override 30 | public void close() { 31 | printLine(); 32 | } 33 | 34 | private void printLine() { 35 | System.out.print("+"); 36 | for (int i = 0; i < _width; i ++) { 37 | System.out.print("-"); 38 | } 39 | System.out.println("+"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/FactoryAbstractTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import pers.hai.sample.dp.factory.abstr.framework.BlueShapeFactory; 4 | import pers.hai.sample.dp.factory.abstr.framework.RedShapeFactory; 5 | import pers.hai.sample.dp.factory.abstr.framework.Shape; 6 | import pers.hai.sample.dp.factory.abstr.framework.ShapeFactory; 7 | import org.junit.Test; 8 | 9 | public class FactoryAbstractTest { 10 | 11 | @Test 12 | public void test1() { 13 | ShapeFactory factory1 = new BlueShapeFactory(); 14 | { 15 | Shape shape1 = factory1.createCircular(); 16 | shape1.show(); 17 | 18 | Shape shape2 = factory1.createSquareness(); 19 | shape2.show(); 20 | } 21 | 22 | ShapeFactory factory2 = new RedShapeFactory(); 23 | { 24 | Shape shape1 = factory2.createCircular(); 25 | shape1.show(); 26 | 27 | Shape shape2 = factory2.createSquareness(); 28 | shape2.show(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/dynamic/model/StationPort.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.dynamic.model; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 14:27 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class StationPort { 13 | private String name; 14 | 15 | public StationPort(String name) { 16 | this.name = name; 17 | } 18 | 19 | public void setName(String name) { 20 | this.name = name; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | @Override 28 | public boolean equals(Object obj) { 29 | if (!(obj instanceof StationPort)) return false; 30 | return hashCode() == obj.hashCode(); 31 | } 32 | 33 | @Override 34 | public int hashCode() { 35 | return getName().hashCode(); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return String.format("[%s]", getName()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/dynamic/model/TravelPorts.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.dynamic.model; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 15:14 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class TravelPorts { 13 | private StationPort from; 14 | private StationPort to; 15 | 16 | public TravelPorts(String from, String to) { 17 | this.from = new StationPort(from); 18 | this.to = new StationPort(to); 19 | } 20 | 21 | @Override 22 | public boolean equals(Object obj) { 23 | if (!(obj instanceof TravelPorts)) return false; 24 | return hashCode() == obj.hashCode(); 25 | } 26 | 27 | @Override 28 | public int hashCode() { 29 | return String.format("%s|%s", from.getName(), to.getName()).hashCode(); 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return String.format("[%s->%s]", from.getName(), to.getName()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/visitor/ConcreteVisitor.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.visitor; 2 | 3 | import java.util.Collection; 4 | import java.util.Iterator; 5 | 6 | /** 7 | * TODO 8 | *

9 | * Create Time: 2019-06-14 11:21 10 | * Last Modify: 2019-06-14 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class ConcreteVisitor implements Visitor { 16 | //在本方法中,我们实现了对 Collection 的元素的成功访问 17 | public void visitCollection(Collection collection) { 18 | Iterator iterator = collection.iterator(); 19 | while (iterator.hasNext()) { 20 | Object o = iterator.next(); 21 | if (o instanceof Visitable) 22 | ((Visitable) o).accept(this); 23 | } 24 | } 25 | 26 | public void visitString(StringElement stringE) { 27 | System.out.println("'"+stringE.getValue()+"'"); 28 | } 29 | 30 | public void visitFloat(FloatElement floatE) { 31 | System.out.println(floatE.getValue().toString()+"f"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/flyweight/Circular.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.flyweight; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-06-03 18:04 9 | * Last Modify: 2019-06-03 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class Circular implements Shape { 15 | 16 | private final Logger logger = Logger.getLogger(Circular.class); 17 | 18 | private String color; 19 | private double x; 20 | private double y; 21 | private double r; 22 | 23 | public Circular(String color) { 24 | this.color = color; 25 | } 26 | 27 | public void setX(double x) { 28 | this.x = x; 29 | } 30 | 31 | public void setY(double y) { 32 | this.y = y; 33 | } 34 | 35 | public void setR(double r) { 36 | this.r = r; 37 | } 38 | 39 | @Override 40 | public void draw() { 41 | logger.info(String.format("Circular: color = %s, x = %s, y = %s, r = %s", color, x, y , r)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/mediator/MediatorStructure.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.mediator; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-06-14 14:30 7 | * Last Modify: 2019-06-14 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class MediatorStructure extends Mediator{ 13 | //首先中介结构必须知道所有房主和租房者的信息 14 | private HouseOwner houseOwner; 15 | private Tenant tenant; 16 | 17 | public HouseOwner getHouseOwner() { 18 | return houseOwner; 19 | } 20 | 21 | public void setHouseOwner(HouseOwner houseOwner) { 22 | this.houseOwner = houseOwner; 23 | } 24 | 25 | public Tenant getTenant() { 26 | return tenant; 27 | } 28 | 29 | public void setTenant(Tenant tenant) { 30 | this.tenant = tenant; 31 | } 32 | 33 | public void constact(String message, Person person) { 34 | if(person == houseOwner) 35 | tenant.getMessage(message); 36 | else 37 | houseOwner.getMessage(message); 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/virtual2/PrinterProxy.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.virtual2; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-07 18:05 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class PrinterProxy implements Printable { 13 | 14 | private String name; 15 | private Printer real; 16 | 17 | public PrinterProxy(String name) { 18 | this.name = name; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public synchronized void setName(String name) { 26 | if (null != real) { 27 | real.setName(name); 28 | } 29 | 30 | this.name = name; 31 | } 32 | 33 | @Override 34 | public void print(String content) { 35 | realize(); 36 | real.print(content); 37 | } 38 | 39 | private synchronized void realize() { 40 | if (null == real) { 41 | real = new Printer(this.name); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/IteratorTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import pers.hai.sample.dp.iterator.Book; 4 | import pers.hai.sample.dp.iterator.BookShelf; 5 | import pers.hai.sample.dp.iterator.Iterator; 6 | import org.junit.Test; 7 | 8 | /** 9 | * TODO 10 | *

11 | * Create Time: 2019-05-29 16:38 12 | * Last Modify: 2019-05-29 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class IteratorTests extends Testable { 18 | 19 | @Test 20 | public void test1() { 21 | BookShelf bookShelf = new BookShelf(5); 22 | bookShelf.appendBook(new Book("Java 编程思想")); 23 | bookShelf.appendBook(new Book("深入理解 Java 虚拟机")); 24 | bookShelf.appendBook(new Book("Java 核心技术·卷I:基础知识")); 25 | bookShelf.appendBook(new Book("Java 核心技术·卷II: 高级特性")); 26 | bookShelf.appendBook(new Book("Effective Java")); 27 | 28 | Iterator iterator = bookShelf.iterator(); 29 | while (iterator.hasNext()) { 30 | logger.info(iterator.next()); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/prototype/UnderlinePen.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.prototype; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019/5/21 21:49 7 | * Last Modify: 2019/5/21 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class UnderlinePen implements Product { 13 | 14 | private char ulchar; 15 | 16 | public UnderlinePen(char ulchar) { 17 | this.ulchar = ulchar; 18 | } 19 | 20 | public void use(String s) { 21 | int length = s.getBytes().length; 22 | System.out.println("\"" + s + "\""); 23 | System.out.print(" "); 24 | for (int i = 0; i < length; i++) { 25 | System.out.print(ulchar); 26 | } 27 | 28 | System.out.println(""); 29 | } 30 | 31 | @Override 32 | public Product createClone() { 33 | Product p = null; 34 | try { 35 | p = (Product) clone(); 36 | } catch (CloneNotSupportedException ex) { 37 | ex.printStackTrace(); 38 | } 39 | 40 | return p; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/bridge/StringDisplayImpl.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.bridge; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 18:01 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class StringDisplayImpl extends DisplayImpl { 13 | 14 | private String label; 15 | private int width; 16 | 17 | public StringDisplayImpl(String label) { 18 | this.label = label; 19 | this.width = label.getBytes().length; 20 | } 21 | 22 | @Override 23 | public void rawOpen() { 24 | printLine(); 25 | } 26 | 27 | @Override 28 | public void rawPrint() { 29 | System.out.println(String.format("|%s|", label)); 30 | } 31 | 32 | @Override 33 | public void rawClose() { 34 | printLine(); 35 | } 36 | 37 | private void printLine() { 38 | System.out.print("+"); 39 | for (int i = 0; i < width; i++) { 40 | System.out.print("-"); 41 | } 42 | System.out.println("+"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/StatePatternTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import pers.hai.sample.dp.state.Lift; 4 | import pers.hai.sample.dp.state.StoppingState; 5 | import org.junit.Test; 6 | 7 | /** 8 | * TODO 9 | * 10 | * Create Time: 2019-04-10 16:40 11 | * Last Modify: 2019-05-24 12 | * 13 | * @author Q-WHai 14 | * @see https://github.com/qwhai 15 | */ 16 | public class StatePatternTest { 17 | 18 | // 正常情况下的测试 19 | @Test 20 | public void test1() { 21 | Lift context = new Lift(new StoppingState()); 22 | context.open(); 23 | context.close(); 24 | context.run(); 25 | context.stop(); 26 | context.open(); 27 | context.close(); 28 | } 29 | 30 | // 异常情况下的测试 31 | @Test 32 | public void test2() { 33 | Lift context = new Lift(new StoppingState()); 34 | context.close(); 35 | context.open(); 36 | context.close(); 37 | context.run(); 38 | context.open(); 39 | context.stop(); 40 | context.open(); 41 | context.close(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/BuilderTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.builder.Director; 5 | import pers.hai.sample.dp.builder.HTMLBuilder; 6 | import pers.hai.sample.dp.builder.TextBuilder; 7 | 8 | /** 9 | * TODO 10 | *

11 | * Create Time: 2019/5/25 23:36 12 | * Last Modify: 2019/5/25 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class BuilderTests extends Testable { 18 | 19 | @Test 20 | public void testPlain() { 21 | TextBuilder builder = new TextBuilder(); 22 | Director director = new Director(builder); 23 | director.construct(); 24 | 25 | String result = builder.getResult(); 26 | logger.info(result); 27 | } 28 | 29 | @Test 30 | public void testHTML() { 31 | HTMLBuilder builder = new HTMLBuilder(); 32 | Director director = new Director(builder); 33 | director.construct(); 34 | 35 | String fileName = builder.getResult(); 36 | logger.info(String.format("%s文件编写完成", fileName)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/interpreter/CommandListNode.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.interpreter; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * TODO 8 | *

9 | * Create Time: 2019-06-14 17:49 10 | * Last Modify: 2019-06-14 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class CommandListNode extends Node { 16 | 17 | private List list = new ArrayList<>(); 18 | 19 | @Override 20 | public void parse(Context context) throws ParseException { 21 | while (true) { 22 | if (null == context.currentToken()) 23 | throw new ParseException("Missing 'end'"); 24 | else if (context.currentToken().equals("end")) { 25 | context.skipToken("end"); 26 | break; 27 | } else { 28 | Node commandNode = new CommandNode(); 29 | commandNode.parse(context); 30 | list.add(commandNode); 31 | } 32 | } 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return list.toString(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/ObserverPatternTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import pers.hai.sample.dp.observer.framework.NumberGenerator; 4 | import pers.hai.sample.dp.observer.framework.Observer; 5 | import org.junit.Test; 6 | import pers.hai.sample.dp.observer.*; 7 | 8 | public class ObserverPatternTest { 9 | 10 | @Test 11 | public void testObserver() { 12 | Observer o1 = new DigitObserver(); 13 | Observer o2 = new GraphObserver(); 14 | Observer o3 = new CycleObserver(); 15 | 16 | NumberGenerator g1 = new RandomNumberGenerator(); 17 | g1.registerChangedObserver(o1); 18 | g1.registerChangedObserver(o2); 19 | g1.registerCycleObserver(o3, 2); 20 | for (int i = 0; i < 5; i++) { 21 | g1.generate(); 22 | g1.publish(); 23 | System.out.println(); 24 | } 25 | 26 | NumberGenerator g2 = new IncrementNumberGenerator(); 27 | g2.registerChangedObserver(o1); 28 | g2.registerChangedObserver(o2); 29 | for (int i = 0; i < 5; i++) { 30 | g2.generate(); 31 | g2.publish(); 32 | System.out.println(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/VisitorTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.visitor.ConcreteVisitor; 5 | import pers.hai.sample.dp.visitor.FloatElement; 6 | import pers.hai.sample.dp.visitor.StringElement; 7 | import pers.hai.sample.dp.visitor.Visitor; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Collection; 11 | 12 | /** 13 | * TODO 14 | *

15 | * Create Time: 2019-06-13 18:40 16 | * Last Modify: 2019-06-13 17 | * 18 | * @author Q-WHai 19 | * @see https://github.com/qwhai 20 | */ 21 | public class VisitorTests extends Testable { 22 | 23 | @Test 24 | public void test1() { 25 | Visitor visitor = new ConcreteVisitor(); 26 | StringElement stringE = new StringElement("I am a String"); 27 | visitor.visitString(stringE); 28 | Collection list = new ArrayList(); 29 | list.add(new StringElement("I am a String1")); 30 | list.add(new StringElement("I am a String2")); 31 | list.add(new FloatElement(new Float(12))); 32 | list.add(new StringElement("I am a String3")); 33 | visitor.visitCollection(list); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/factory/method/idcard/IDCard.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.factory.method.idcard; 2 | 3 | import pers.hai.sample.dp.factory.method.framework.Product; 4 | import pers.hai.sample.dp.factory.method.model.Account; 5 | 6 | /** 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class IDCard extends Product { 13 | 14 | private Account account = new Account(); 15 | 16 | public IDCard(String name){ 17 | account.setName(name); 18 | account.setBalance(0); 19 | } 20 | 21 | @Override 22 | public void recharge(double x) { 23 | account.setBalance(account.getBalance() + x); 24 | System.out.println(String.format("向 %s 的账户充值 %d 元,余额:%d元", account.getName(), (int)x, (int)account.getBalance())); 25 | } 26 | 27 | @Override 28 | public void use(double x) { 29 | account.setBalance(account.getBalance() - x); 30 | System.out.println(String.format("从 %s 的账户消费 %d 元,余额:%d元", account.getName(), (int)x, (int)account.getBalance())); 31 | } 32 | 33 | public String getOwner() { 34 | return account.getName(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/strategy/Player.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.strategy; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 18:33 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class Player { 13 | private String name; 14 | private Strategy strategy; 15 | private int wincount; 16 | private int losecount; 17 | private int gamecount; 18 | 19 | public Player(String name, Strategy strategy) { 20 | this.name = name; 21 | this.strategy = strategy; 22 | } 23 | 24 | public Hand nextHand() { 25 | return strategy.nextHand(); 26 | } 27 | 28 | public void win() { 29 | strategy.study(true); 30 | wincount++; 31 | gamecount++; 32 | } 33 | 34 | public void lose() { 35 | strategy.study(false); 36 | losecount++; 37 | gamecount++; 38 | } 39 | 40 | public void even() { 41 | gamecount++; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return String.format("[%s:%d games, %d win, %d lose.]", name, gamecount, wincount, losecount); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/builder/TextBuilder.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.builder; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019/5/25 23:20 7 | * Last Modify: 2019/5/25 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class TextBuilder extends Builder { 13 | 14 | private StringBuilder sb = new StringBuilder(); 15 | 16 | @Override 17 | public void makeTitle(String title) { 18 | sb.append("=========================\n"); 19 | sb.append(String.format("『%s』\n", title)); 20 | sb.append("\n"); 21 | } 22 | 23 | @Override 24 | public void makeString(String content) { 25 | sb.append(String.format("·%s\n", content)); 26 | sb.append("\n"); 27 | } 28 | 29 | @Override 30 | public void makeItems(String[] items) { 31 | for (String item : items) { 32 | sb.append(String.format(" ·%s\n", item)); 33 | } 34 | sb.append("\n"); 35 | } 36 | 37 | @Override 38 | public void close() { 39 | sb.append("=========================\n"); 40 | } 41 | 42 | public String getResult() { 43 | return sb.toString(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/decorator/FullBorder.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.decorator; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 18:01 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class FullBorder extends Border { 13 | 14 | private Display display; 15 | 16 | public FullBorder(Display display) { 17 | this.display = display; 18 | } 19 | 20 | @Override 21 | int getRows() { 22 | return 1 + display.getRows() + 1; 23 | } 24 | 25 | @Override 26 | int getColumns() { 27 | return 1 + display.getColumns() + 1; 28 | } 29 | 30 | @Override 31 | String getRowText(int row) { 32 | if (0 == row || getRows() - 1 == row) return generateLine(); 33 | return String.format("|%s|", display.getRowText(row - 1)); 34 | } 35 | 36 | private String generateLine() { 37 | StringBuilder sb = new StringBuilder(); 38 | sb.append('+'); 39 | for (int i = 0; i < display.getColumns(); i++) { 40 | sb.append('-'); 41 | } 42 | sb.append('+'); 43 | 44 | return sb.toString(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/flyweight/ShapeFactory.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.flyweight; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * TODO 8 | *

9 | * Create Time: 2019-06-03 18:04 10 | * Last Modify: 2019-06-03 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class ShapeFactory { 16 | 17 | private Map cirMap = new HashMap<>(); 18 | private Map rectMap = new HashMap<>(); 19 | public static ShapeFactory instance; 20 | 21 | private ShapeFactory() { } 22 | 23 | public static ShapeFactory getInstance() { 24 | if (null == instance) 25 | instance = new ShapeFactory(); 26 | 27 | return instance; 28 | } 29 | 30 | public Circular createCirculer(String state) { 31 | if (!cirMap.containsKey(state)) 32 | cirMap.put(state, new Circular(state)); 33 | return cirMap.get(state); 34 | } 35 | 36 | public Rectangle createRectangle(String state) { 37 | if (!rectMap.containsKey(state)) 38 | rectMap.put(state, new Rectangle(state)); 39 | return rectMap.get(state); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/cmd/AddCommand.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command.cmd; 2 | 3 | import pers.hai.sample.dp.command.CommandAttachable; 4 | import pers.hai.sample.dp.command.Computable; 5 | 6 | /** 7 | * 加法 8 | * 9 | * Create Time: 2019-05-20 10:33 10 | * Last Modify: 2019-05-20 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class AddCommand implements Command { 16 | 17 | private double x; 18 | private Computable computable; 19 | 20 | public AddCommand(double x, Computable computable) { 21 | this.x = x; 22 | this.computable = computable; 23 | } 24 | 25 | @Override 26 | public void calculate() { 27 | computable.add(x); 28 | if (computable instanceof CommandAttachable) { 29 | ((CommandAttachable) computable).attachUndo(this); 30 | } 31 | } 32 | 33 | @Override 34 | public void undo() { 35 | computable.sub(x); 36 | if (computable instanceof CommandAttachable) { 37 | ((CommandAttachable) computable).attachRedo(this); 38 | } 39 | } 40 | 41 | @Override 42 | public void redo() { 43 | calculate(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/cmd/DivCommand.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command.cmd; 2 | 3 | import pers.hai.sample.dp.command.CommandAttachable; 4 | import pers.hai.sample.dp.command.Computable; 5 | 6 | /** 7 | * 除尘 8 | * 9 | * Create Time: 2019-05-20 14:55 10 | * Last Modify: 2019-05-20 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class DivCommand implements Command { 16 | 17 | private double x; 18 | private Computable computable; 19 | 20 | public DivCommand(double x, Computable computable) { 21 | this.x = x; 22 | this.computable = computable; 23 | } 24 | 25 | @Override 26 | public void calculate() { 27 | computable.div(x); 28 | if (computable instanceof CommandAttachable) { 29 | ((CommandAttachable) computable).attachUndo(this); 30 | } 31 | } 32 | 33 | @Override 34 | public void undo() { 35 | computable.mul(x); 36 | if (computable instanceof CommandAttachable) { 37 | ((CommandAttachable) computable).attachRedo(this); 38 | } 39 | } 40 | 41 | @Override 42 | public void redo() { 43 | calculate(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/cmd/MulCommand.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command.cmd; 2 | 3 | import pers.hai.sample.dp.command.CommandAttachable; 4 | import pers.hai.sample.dp.command.Computable; 5 | 6 | /** 7 | * 乘法 8 | * 9 | * Create Time: 2019-05-20 14:53 10 | * Last Modify: 2019-05-20 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class MulCommand implements Command { 16 | 17 | private double x; 18 | private Computable computable; 19 | 20 | public MulCommand(double x, Computable computable) { 21 | this.x = x; 22 | this.computable = computable; 23 | } 24 | 25 | @Override 26 | public void calculate() { 27 | computable.mul(x); 28 | if (computable instanceof CommandAttachable) { 29 | ((CommandAttachable) computable).attachUndo(this); 30 | } 31 | } 32 | 33 | @Override 34 | public void undo() { 35 | computable.div(x); 36 | if (computable instanceof CommandAttachable) { 37 | ((CommandAttachable) computable).attachRedo(this); 38 | } 39 | } 40 | 41 | @Override 42 | public void redo() { 43 | calculate(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/cmd/SubCommand.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command.cmd; 2 | 3 | import pers.hai.sample.dp.command.CommandAttachable; 4 | import pers.hai.sample.dp.command.Computable; 5 | 6 | /** 7 | * 减法 8 | * 9 | * Create Time: 2019-05-20 14:51 10 | * Last Modify: 2019-05-20 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class SubCommand implements Command { 16 | 17 | private double x; 18 | private Computable computable; 19 | 20 | public SubCommand(double x, Computable computable) { 21 | this.x = x; 22 | this.computable = computable; 23 | } 24 | 25 | @Override 26 | public void calculate() { 27 | computable.sub(x); 28 | if (computable instanceof CommandAttachable) { 29 | ((CommandAttachable) computable).attachUndo(this); 30 | } 31 | } 32 | 33 | @Override 34 | public void undo() { 35 | computable.add(x); 36 | if (computable instanceof CommandAttachable) { 37 | ((CommandAttachable) computable).attachRedo(this); 38 | } 39 | } 40 | 41 | @Override 42 | public void redo() { 43 | calculate(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/prototype/MessageBox.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.prototype; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019/5/21 21:45 7 | * Last Modify: 2019/5/21 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class MessageBox implements Product { 13 | private char decochar; 14 | 15 | public MessageBox(char decochar) { 16 | this.decochar = decochar; 17 | } 18 | 19 | public void use(String s) { 20 | int length = s.getBytes().length; 21 | for (int i = 0; i < length + 4; i++) { 22 | System.out.print(decochar); 23 | } 24 | 25 | System.out.println(""); 26 | System.out.println(decochar + " " + s + " " + decochar); 27 | 28 | for (int i = 0; i < length + 4; i++) { 29 | System.out.print(decochar); 30 | } 31 | System.out.println(""); 32 | } 33 | 34 | @Override 35 | public Product createClone() { 36 | Product p = null; 37 | try { 38 | p = (Product) clone(); 39 | } catch (CloneNotSupportedException ex) { 40 | ex.printStackTrace(); 41 | } 42 | 43 | return p; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/decorator/SideBorder.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.decorator; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 18:01 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class SideBorder extends Border { 13 | 14 | private Display display; 15 | private char left = '{'; 16 | private char right = '}'; 17 | 18 | public SideBorder(Display display) { 19 | this.display = display; 20 | } 21 | 22 | public SideBorder(Display display, char ch) { 23 | this.display = display; 24 | this.left = ch; 25 | this.right = ch; 26 | } 27 | 28 | public SideBorder(Display display, char left, char right) { 29 | this.display = display; 30 | this.left = left; 31 | this.right = right; 32 | } 33 | 34 | @Override 35 | int getRows() { 36 | return display.getRows(); 37 | } 38 | 39 | @Override 40 | int getColumns() { 41 | return 1 + display.getColumns() + 1; 42 | } 43 | 44 | @Override 45 | String getRowText(int row) { 46 | return String.format("%s%s%s", left, display.getRowText(row), right); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/flyweight/Rectangle.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.flyweight; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-06-03 18:18 9 | * Last Modify: 2019-06-03 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class Rectangle implements Shape { 15 | 16 | private final Logger logger = Logger.getLogger(Rectangle.class); 17 | 18 | private String color; 19 | private double x; 20 | private double y; 21 | private double width; 22 | private double height; 23 | 24 | public Rectangle(String color) { 25 | this.color = color; 26 | } 27 | 28 | public void setX(double x) { 29 | this.x = x; 30 | } 31 | 32 | public void setY(double y) { 33 | this.y = y; 34 | } 35 | 36 | public void setWidth(double width) { 37 | this.width = width; 38 | } 39 | 40 | public void setHeight(double height) { 41 | this.height = height; 42 | } 43 | 44 | @Override 45 | public void draw() { 46 | logger.info(String.format("Rectangle: color = %s, x = %s, y = %s, width = %s, height = %s", color, x, y , width, height)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/access/WriterProxy.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.access; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * 作者(题主)代理 7 | * 8 | * Create Time: 2019-04-07 20:15 9 | * Last Modify: 2019-05-24 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class WriterProxy implements Forum { 15 | 16 | private Logger logger = Logger.getLogger(WriterProxy.class); 17 | 18 | @Override 19 | public void visit() { 20 | logger.info("题主正在访问话题"); 21 | } 22 | 23 | @Override 24 | public void comment() { 25 | logger.info("题主正在评论话题"); 26 | } 27 | 28 | @Override 29 | public void createTopic() throws UnauthorizedException { 30 | logger.info("题主正在创建话题"); 31 | } 32 | 33 | @Override 34 | public void moidfyTopic() throws UnauthorizedException{ 35 | logger.info("题主正在修改话题"); 36 | } 37 | 38 | @Override 39 | public void deleteTopic() throws UnauthorizedException{ 40 | logger.info("题主正在删除话题"); 41 | } 42 | 43 | @Override 44 | public boolean auditTopic(String topicId) throws UnauthorizedException{ 45 | throw new UnauthorizedException("题主无权审核话题"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/PrototypeTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import pers.hai.sample.dp.prototype.Manager; 4 | import pers.hai.sample.dp.prototype.MessageBox; 5 | import pers.hai.sample.dp.prototype.Product; 6 | import pers.hai.sample.dp.prototype.UnderlinePen; 7 | import org.junit.Test; 8 | 9 | /** 10 | * TODO 11 | *

12 | * Create Time: 2019-05-21 21:51 13 | * Last Modify: 2019-05-24 14 | * 15 | * @author Q-WHai 16 | * @see https://github.com/qwhai 17 | */ 18 | public class PrototypeTest { 19 | 20 | @Test 21 | public void test1() { 22 | Manager manager = new Manager(); 23 | UnderlinePen upen = new UnderlinePen('~'); 24 | MessageBox mbox = new MessageBox('*'); 25 | MessageBox sbox = new MessageBox('/'); 26 | 27 | manager.register("strong message", upen); 28 | manager.register("warning box", mbox); 29 | manager.register("slash box", sbox); 30 | 31 | Product p1 = manager.create("strong message"); 32 | p1.use("Hello, world."); 33 | 34 | Product p2 = manager.create("warning box"); 35 | p2.use("Hello, world."); 36 | 37 | Product p3 = manager.create("slash box"); 38 | p3.use("Hello, world."); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/SingletonPatternTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import pers.hai.sample.dp.singleton.Settings; 4 | import pers.hai.sample.dp.singleton.Settings2; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | 8 | /** 9 | * TODO 10 | * 11 | * Create Time: 2019-04-12 18:10 12 | * Last Modify: 2019-05-24 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class SingletonPatternTest { 18 | 19 | @Test 20 | public void test1() { 21 | Settings s1 = Settings.getInstance(); 22 | Settings s2 = Settings.getInstance(); 23 | 24 | System.out.println(String.format("settings 1 : %s", s1.getUuid())); 25 | System.out.println(String.format("settings 2 : %s", s2.getUuid())); 26 | 27 | Assert.assertEquals(s1.getUuid(), s2.getUuid()); 28 | } 29 | 30 | @Test 31 | public void test2() { 32 | Settings2 s1 = Settings2.getInstance(); 33 | Settings2 s2 = Settings2.getInstance(); 34 | 35 | System.out.println(String.format("settings 1 : %s", s1.getUuid())); 36 | System.out.println(String.format("settings 2 : %s", s2.getUuid())); 37 | 38 | Assert.assertEquals(s1.getUuid(), s2.getUuid()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/access/TouristProxy.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.access; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * 游客,访客代理 7 | * 8 | * Create Time: 2019-04-07 20:15 9 | * Last Modify: 2019-05-24 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class TouristProxy implements Forum { 15 | 16 | private Logger logger = Logger.getLogger(TouristProxy.class); 17 | 18 | @Override 19 | public void visit() { 20 | logger.info("访客正在访问话题"); 21 | } 22 | 23 | @Override 24 | public void comment() { 25 | logger.info("访客正在评论话题"); 26 | } 27 | 28 | @Override 29 | public void createTopic() throws UnauthorizedException { 30 | throw new UnauthorizedException("访客无权创建话题"); 31 | } 32 | 33 | @Override 34 | public void moidfyTopic() throws UnauthorizedException{ 35 | throw new UnauthorizedException("访客无权修改话题"); 36 | } 37 | 38 | @Override 39 | public void deleteTopic() throws UnauthorizedException{ 40 | throw new UnauthorizedException("访客无权删除话题"); 41 | } 42 | 43 | @Override 44 | public boolean auditTopic(String topicId) throws UnauthorizedException{ 45 | throw new UnauthorizedException("访客无权审核话题"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/InterpreterTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.interpreter.Context; 5 | import pers.hai.sample.dp.interpreter.Node; 6 | import pers.hai.sample.dp.interpreter.ParseException; 7 | import pers.hai.sample.dp.interpreter.ProgramNode; 8 | 9 | import java.io.BufferedReader; 10 | import java.io.FileReader; 11 | import java.io.IOException; 12 | 13 | /** 14 | * TODO 15 | *

16 | * Create Time: 2019-06-14 17:36 17 | * Last Modify: 2019-06-14 18 | * 19 | * @author Q-WHai 20 | * @see https://github.com/qwhai 21 | */ 22 | public class InterpreterTests extends Testable { 23 | 24 | @Test 25 | public void test1() { 26 | try { 27 | BufferedReader reader = new BufferedReader(new FileReader("H:\\program.txt")); 28 | String text; 29 | while (null != (text = reader.readLine())) { 30 | logger.info(String.format("text = %s", text)); 31 | Node node = new ProgramNode(); 32 | node.parse(new Context(text)); 33 | logger.info(String.format("node = %s", node)); 34 | } 35 | } catch (IOException | ParseException ex) { 36 | logger.error(ex.getMessage()); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /design.pattern.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/access/ManagerProxy.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.access; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * 管理员代理 7 | * Create Time: 2019-04-07 20:15 8 | * Last Modify: 2019-05-24 9 | * 10 | * @author Q-WHai 11 | * @see https://github.com/qwhai 12 | */ 13 | public class ManagerProxy implements Forum { 14 | 15 | private Logger logger = Logger.getLogger(ManagerProxy.class); 16 | 17 | @Override 18 | public void visit() { 19 | logger.info("管理员正在访问话题"); 20 | } 21 | 22 | @Override 23 | public void comment() throws UnauthorizedException { 24 | throw new UnauthorizedException("管理员无权评论话题"); 25 | } 26 | 27 | @Override 28 | public void createTopic() throws UnauthorizedException { 29 | throw new UnauthorizedException("管理员无权创建话题"); 30 | } 31 | 32 | @Override 33 | public void moidfyTopic() throws UnauthorizedException{ 34 | throw new UnauthorizedException("管理员无权修改话题"); 35 | } 36 | 37 | @Override 38 | public void deleteTopic() throws UnauthorizedException{ 39 | logger.info("管理员正在删除话题"); 40 | } 41 | 42 | @Override 43 | public boolean auditTopic(String topicId) throws UnauthorizedException{ 44 | logger.info("管理员正在审核话题"); 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/virtual2/Printer.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.virtual2; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * TODO 7 | * 8 | * Create Time: 2019-04-07 18:05 9 | * Last Modify: 2019-05-24 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class Printer implements Printable { 15 | 16 | private Logger logger = Logger.getLogger(Printer.class); 17 | private String name; 18 | 19 | public Printer(String name) { 20 | this.name = name; 21 | heavyJob(); 22 | } 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | public String getName() { 29 | return this.name; 30 | } 31 | 32 | @Override 33 | public void print(String content) { 34 | logger.info(String.format("打印机[%s]正在打印内容:%s", this.name, content)); 35 | } 36 | 37 | private void heavyJob() { 38 | try { 39 | for (int i = 0; i < 5; i++) { 40 | logger.info(String.format("打印机[%s]正在初始化...", this.name)); 41 | Thread.sleep(1000); 42 | } 43 | logger.info(String.format("打印机[%s]初始化完成", this.name)); 44 | } catch (InterruptedException ex) { 45 | ex.printStackTrace(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/cor/Support.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.cor; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-06-14 17:09 9 | * Last Modify: 2019-06-14 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public abstract class Support { 15 | 16 | private final Logger logger = Logger.getLogger(Support.class); 17 | 18 | private String name; 19 | private Support next; 20 | 21 | Support(String name) { 22 | this.name = name; 23 | } 24 | 25 | public Support setNext(Support support) { 26 | this.next = support; 27 | return this.next; 28 | } 29 | 30 | public final void support(Trouble trouble) { 31 | if (resolve(trouble)) 32 | done(trouble); 33 | else if (null != next) 34 | next.support(trouble); 35 | else 36 | fail(trouble); 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return String.format("[%s]", name); 42 | } 43 | 44 | protected abstract boolean resolve(Trouble trouble); 45 | 46 | private void done(Trouble trouble) { 47 | logger.info(String.format("%s is resolved by %s.", trouble, this)); 48 | } 49 | 50 | private void fail(Trouble trouble) { 51 | logger.info(String.format("%s cannot be resolved.", trouble)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/virtual1/NanjingStation.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.virtual1; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * 南京站 10 | * 11 | * Create Time: 2019-04-05 22:23 12 | * Last Modify: 2019-05-24 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class NanjingStation implements IStation { 18 | 19 | private Logger logger = Logger.getLogger(NanjingStation.class); 20 | 21 | private Map _ticketSurplus = new HashMap() { 22 | { 23 | put("nanjing|shanghaihongqiao", 20); 24 | put("nanjingnan|shanghaihongqiao", 16); 25 | put("wuhan|changshanan", 7); 26 | } 27 | }; 28 | 29 | @Override 30 | public double ticketPrice(String start, String end) { 31 | return ticketMap.get(String.format("%s|%s", start, end)); 32 | } 33 | 34 | @Override 35 | public int ticketSurplus(String start, String end) { 36 | return _ticketSurplus.get(String.format("%s|%s", start, end)); 37 | } 38 | 39 | @Override 40 | public void booking(String start, String end) { 41 | logger.info(String.format("南京站正在出票,从 %s 到 %s", start, end)); 42 | _ticketSurplus.replace(String.format("%s|%s", start, end), _ticketSurplus.get(String.format("%s|%s", start, end)) - 1); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/strategy/Hand.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.strategy; 2 | 3 | /** 4 | * TODO 5 | *

6 | * Create Time: 2019-05-29 18:18 7 | * Last Modify: 2019-05-29 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class Hand { 13 | 14 | public static final int HANDVALUE_GUU = 0; // 表示石头的值 15 | public static final int HANDVALUE_CHO = 1; // 表示剪刀的值 16 | public static final int HANDVALUE_PAA = 2; // 表示布的值 17 | 18 | public static final Hand[] hands = { 19 | new Hand(Hand.HANDVALUE_GUU), 20 | new Hand(Hand.HANDVALUE_CHO), 21 | new Hand(Hand.HANDVALUE_PAA) 22 | }; 23 | 24 | private static final String[] names = { 25 | " 石头 ", " 剪刀 ", "布" 26 | }; 27 | 28 | private int handval; 29 | public Hand(int handval) { 30 | this.handval = handval; 31 | } 32 | 33 | public static Hand getHand(int handval) { 34 | return hands[handval]; 35 | } 36 | 37 | public boolean isStrongerThan(Hand h) { 38 | return 1 == fight(h); 39 | } 40 | 41 | public boolean isWeakerThan(Hand h) { 42 | return -1 == fight(h); 43 | } 44 | 45 | private int fight(Hand h) { 46 | return this == h ? 0 : ((this.handval + 1) % 3 == h.handval) ? 1 : -1; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return names[handval]; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/virtual1/NanjingnanStation.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.virtual1; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * 南京南站 10 | * 11 | * Create Time: 2019-04-05 22:27 12 | * Last Modify: 2019-05-24 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class NanjingnanStation implements IStation { 18 | 19 | private Logger logger = Logger.getLogger(NanjingnanStation.class); 20 | 21 | private Map _ticketSurplus = new HashMap() { 22 | { 23 | put("nanjing|shanghaihongqiao", 10); 24 | put("nanjingnan|shanghaihongqiao", 60); 25 | put("wuhan|changshanan", 23); 26 | } 27 | }; 28 | 29 | @Override 30 | public double ticketPrice(String start, String end) { 31 | return ticketMap.get(String.format("%s|%s", start, end)); 32 | } 33 | 34 | @Override 35 | public int ticketSurplus(String start, String end) { 36 | return _ticketSurplus.get(String.format("%s|%s", start, end)); 37 | } 38 | 39 | @Override 40 | public void booking(String start, String end) { 41 | logger.info(String.format("南京南站正在出票,从 %s 到 %s", start, end)); 42 | _ticketSurplus.replace(String.format("%s|%s", start, end), _ticketSurplus.get(String.format("%s|%s", start, end)) - 1); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/DecoratorPatternTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.decorator.*; 5 | 6 | /** 7 | * TODO 8 | * 9 | * Create Time: 2019-04-10 17:51 10 | * Last Modify: 2019-05-24 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class DecoratorPatternTest { 16 | 17 | @Test 18 | public void test1() { 19 | Display display = new StringDisplay("Hello world."); 20 | display.show(); 21 | } 22 | 23 | @Test 24 | public void test2() { 25 | Display d1 = new StringDisplay("Hello world."); 26 | 27 | Border b1 = new SideBorder(d1); 28 | b1.show(); 29 | 30 | Border b2 = new SideBorder(d1, '#'); 31 | b2.show(); 32 | 33 | Border b3 = new SideBorder(d1, '[', ']'); 34 | b3.show(); 35 | } 36 | 37 | @Test 38 | public void test3() { 39 | Display d1 = new StringDisplay("Hello world."); 40 | 41 | Border b1 = new SideBorder(d1, '#'); 42 | Border b2 = new FullBorder(b1); 43 | b2.show(); 44 | } 45 | 46 | @Test 47 | public void test4() { 48 | Display d1 = new StringDisplay("Hello world."); 49 | 50 | Border b1 = new SideBorder(d1); 51 | Border b2 = new FullBorder(b1); 52 | Border b3 = new SideBorder(b2, '#'); 53 | Border b4 = new FullBorder(b3); 54 | b4.show(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/MementoTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.memento.Gamer; 5 | import pers.hai.sample.dp.memento.Memento; 6 | 7 | /** 8 | * TODO 9 | *

10 | * Create Time: 2019-06-13 17:09 11 | * Last Modify: 2019-06-13 12 | * 13 | * @author Q-WHai 14 | * @see https://github.com/qwhai 15 | */ 16 | public class MementoTests extends Testable { 17 | 18 | @Test 19 | public void test1() { 20 | Gamer gamer = new Gamer(100); 21 | Memento memento = gamer.createMemento(); 22 | for (int i = 0; i < 100; i++) { 23 | logger.info(String.format("--------> ROUND %d", i + 1)); 24 | logger.info(String.format("当前状态:%s", gamer)); 25 | 26 | gamer.bet(); 27 | 28 | logger.info(String.format("所持金币数:%d", gamer.getMoney())); 29 | if (gamer.getMoney() > memento.getMoney()) { 30 | logger.info("所持金币增加过多,保存游戏当前状态"); 31 | memento = gamer.createMemento(); 32 | } else if (gamer.getMoney() < memento.getMoney() / 2) { 33 | logger.info("所持金币减少过多,恢复到之前保存的状态"); 34 | gamer.restoreMemento(memento); 35 | } 36 | 37 | try { 38 | Thread.sleep(1000); 39 | } catch (InterruptedException ex) { 40 | logger.error(ex.getMessage()); 41 | } 42 | 43 | System.out.println(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/composite/Directory.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.composite; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | /** 8 | * TODO 9 | *

10 | * Create Time: 2019-05-30 09:44 11 | * Last Modify: 2019-05-30 12 | * 13 | * @author Q-WHai 14 | * @see https://github.com/qwhai 15 | */ 16 | public class Directory extends Entry { 17 | 18 | private String name; 19 | private List directory = new ArrayList<>(); 20 | 21 | public Directory(String name) { 22 | this.name = name; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | @Override 31 | public int getSize() { 32 | int size = 0; 33 | Iterator iterator = directory.iterator(); 34 | while (iterator.hasNext()) { 35 | Entry entry = (Entry) iterator.next(); 36 | size += entry.getSize(); 37 | } 38 | 39 | return size; 40 | } 41 | 42 | @Override 43 | public Entry add(Entry entry) { 44 | directory.add(entry); 45 | return this; 46 | } 47 | @Override 48 | protected void printList(String prefix) { 49 | System.out.println(String.format("%s/%s", prefix, this)); 50 | Iterator iterator = directory.iterator(); 51 | while (iterator.hasNext()) { 52 | Entry entry = (Entry) iterator.next(); 53 | entry.printList(String.format("%s/%s", prefix, this)); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/virtual1/StationProxy.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.virtual1; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | /** 6 | * 代售点 7 | * 8 | * Create Time: 2019-04-05 22:28 9 | * Last Modify: 2019-05-24 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class StationProxy implements ITicketable { 15 | 16 | private Logger logger = Logger.getLogger(StationProxy.class); 17 | 18 | private IStation njnStation; 19 | private IStation njStation; 20 | 21 | public StationProxy() { 22 | njnStation = new NanjingnanStation(); 23 | njStation = new NanjingStation(); 24 | } 25 | 26 | @Override 27 | public double ticketPrice(String start, String end) { 28 | return ticketMap.get(String.format("%s|%s", start, end)); 29 | } 30 | 31 | @Override 32 | public void booking(String start, String end) { 33 | if (0 == njnStation.ticketSurplus(start, end)) logger.info(String.format("南京南站:%s到%s车票已售罄", start, end)); 34 | if (0 == njStation.ticketSurplus(start, end)) logger.info(String.format("南京站:%s到%s车票已售罄", start, end)); 35 | 36 | if (0 != njnStation.ticketSurplus(start, end)) { 37 | njnStation.booking(start, end); 38 | logger.info(String.format("通过代售点在南京南站买到了从%s到%s的火车票", start, end)); 39 | } else if (0 != njStation.ticketSurplus(start, end)) { 40 | njStation.booking(start, end); 41 | logger.info(String.format("通过代售点在南京站买到了从%s到%s的火车票", start, end)); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/interpreter/Context.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.interpreter; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import java.util.StringTokenizer; 6 | 7 | /** 8 | * TODO 9 | *

10 | * Create Time: 2019-06-14 17:48 11 | * Last Modify: 2019-06-14 12 | * 13 | * @author Q-WHai 14 | * @see https://github.com/qwhai 15 | */ 16 | public class Context { 17 | 18 | private final Logger logger = Logger.getLogger(Context.class); 19 | 20 | private StringTokenizer tokenizer; 21 | private String currentToken; 22 | 23 | public Context(String text) { 24 | tokenizer = new StringTokenizer(text); 25 | nextToken(); 26 | } 27 | 28 | public String nextToken() { 29 | if (tokenizer.hasMoreTokens()) 30 | currentToken = tokenizer.nextToken(); 31 | else 32 | currentToken = null; 33 | 34 | return currentToken; 35 | } 36 | 37 | public String currentToken() { 38 | return currentToken; 39 | } 40 | 41 | public void skipToken(String token) throws ParseException { 42 | if (!token.equals(currentToken)) 43 | throw new ParseException(String.format("Warning: %s is expected, but %s is found.", token, currentToken)); 44 | 45 | nextToken(); 46 | } 47 | 48 | public int currentNumber() throws ParseException { 49 | int number = 0; 50 | try { 51 | number = Integer.parseInt(currentToken); 52 | } catch (NumberFormatException ex) { 53 | logger.error(ex.getMessage()); 54 | } 55 | 56 | return number; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/StrategyTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.strategy.*; 5 | 6 | /** 7 | * TODO 8 | *

9 | * Create Time: 2019-05-29 18:17 10 | * Last Modify: 2019-05-29 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class StrategyTests { 16 | 17 | @Test 18 | public void test1() { 19 | String[] args = new String[] { 20 | "123", 21 | "32" 22 | }; 23 | 24 | int seed1 = Integer.parseInt(args[0]); 25 | int seed2 = Integer.parseInt(args[1]); 26 | 27 | Player player1 = new Player("Taro", new WinningStrategy(seed1)); 28 | Player player2 = new Player("Hana", new ProbStrategy(seed2)); 29 | 30 | for (int i = 0; i < 1000; i++) { 31 | Hand nextHand1 = player1.nextHand(); 32 | Hand nextHand2 = player2.nextHand(); 33 | 34 | if (nextHand1.isStrongerThan(nextHand2)) { 35 | System.out.println(String.format("Winner: %s", player1)); 36 | player1.win(); 37 | player2.lose(); 38 | } else if (nextHand2.isStrongerThan(nextHand1)) { 39 | System.out.println(String.format("Winner: %s", player2)); 40 | player1.lose(); 41 | player2.win(); 42 | } else { 43 | System.out.println("Even..."); 44 | player1.even(); 45 | player2.even(); 46 | } 47 | } 48 | 49 | System.out.println("Total result:"); 50 | System.out.println(player1); 51 | System.out.println(player2); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/strategy/ProbStrategy.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.strategy; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * TODO 7 | *

8 | * Create Time: 2019-05-29 18:27 9 | * Last Modify: 2019-05-29 10 | * 11 | * @author Q-WHai 12 | * @see https://github.com/qwhai 13 | */ 14 | public class ProbStrategy implements Strategy { 15 | private Random random; 16 | private int prevHandValue = 0; 17 | private int currentHandValue = 0; 18 | 19 | private int[][] history = { 20 | { 1, 1, 1 }, 21 | { 1, 1, 1 }, 22 | { 1, 1, 1 } 23 | }; 24 | 25 | public ProbStrategy(int seed) { 26 | random = new Random(seed); 27 | } 28 | 29 | public Hand nextHand() { 30 | int bet = random.nextInt(getSum(currentHandValue)); 31 | int handval = 0; 32 | if (bet < history[currentHandValue][0]) 33 | handval = 0; 34 | else if (bet < history[currentHandValue][0] + history[currentHandValue][1]) 35 | handval = 1; 36 | else 37 | handval = 2; 38 | 39 | prevHandValue = currentHandValue; 40 | currentHandValue = handval; 41 | return Hand.getHand(handval); 42 | } 43 | 44 | private int getSum(int hv) { 45 | int sum = 0; 46 | for (int i = 0; i < 3; i++) { 47 | sum += history[hv][i]; 48 | } 49 | 50 | return sum; 51 | } 52 | 53 | public void study(boolean win) { 54 | if (win) 55 | history[prevHandValue][currentHandValue]++; 56 | else { 57 | history[prevHandValue][(currentHandValue + 1) % 3]++; 58 | history[prevHandValue][(currentHandValue + 2) % 3]++; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/builder/HTMLBuilder.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.builder; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import java.io.FileWriter; 6 | import java.io.IOException; 7 | import java.io.PrintWriter; 8 | 9 | /** 10 | * TODO 11 | *

12 | * Create Time: 2019/5/25 23:20 13 | * Last Modify: 2019/5/25 14 | * 15 | * @author Q-WHai 16 | * @see https://github.com/qwhai 17 | */ 18 | public class HTMLBuilder extends Builder { 19 | 20 | private final Logger logger = Logger.getLogger(HTMLBuilder.class); 21 | private String fileName; 22 | private PrintWriter writer; 23 | 24 | @Override 25 | public void makeTitle(String title) { 26 | fileName = String.format("%s.html", title); 27 | 28 | try { 29 | writer = new PrintWriter(new FileWriter(fileName)); 30 | } catch (IOException ex) { 31 | logger.error(ex.getMessage()); 32 | } 33 | 34 | writer.println(String.format("%s", title)); 35 | writer.println(String.format("

%s

", title)); 36 | } 37 | 38 | @Override 39 | public void makeString(String content) { 40 | writer.println(String.format("

%s

", content)); 41 | } 42 | 43 | @Override 44 | public void makeItems(String[] items) { 45 | writer.println(""); 50 | } 51 | 52 | @Override 53 | public void close() { 54 | writer.println(""); 55 | writer.close(); 56 | } 57 | 58 | public String getResult() { 59 | return fileName; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/observer/IncrementNumberGenerator.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.observer; 2 | 3 | import pers.hai.sample.dp.observer.framework.NumberGenerator; 4 | import pers.hai.sample.dp.observer.framework.Observer; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Last Modify: 2019-05-24 11 | * 12 | * @author Q-WHai 13 | * @see https://github.com/qwhai 14 | */ 15 | public class IncrementNumberGenerator implements NumberGenerator { 16 | 17 | private int number = 0; 18 | private int cycle = 4; 19 | private List observers = new ArrayList<>(); 20 | private List cycleObservers = new ArrayList<>(); 21 | 22 | @Override 23 | public void registerChangedObserver(Observer observer) { 24 | observers.add(observer); 25 | } 26 | 27 | @Override 28 | public void generate() { 29 | number += 3; 30 | } 31 | 32 | @Override 33 | public void publish() { 34 | changed(); 35 | cycle(); 36 | } 37 | 38 | @Override 39 | public void registerCycleObserver(Observer observer, int t) { 40 | cycleObservers.add(observer); 41 | cycle = t; 42 | } 43 | 44 | private void changed() { 45 | for (Observer o : observers) { 46 | o.update(this); 47 | 48 | } 49 | } 50 | 51 | private void cycle() { 52 | if (0 != (number % cycle)) return; 53 | 54 | for (Observer o : cycleObservers) { 55 | o.update(this); 56 | } 57 | } 58 | 59 | @Override 60 | public int getNumber() { 61 | return number; 62 | } 63 | 64 | @Override 65 | public String getName() { 66 | return "Increment Number Generator"; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/observer/RandomNumberGenerator.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.observer; 2 | 3 | import pers.hai.sample.dp.observer.framework.NumberGenerator; 4 | import pers.hai.sample.dp.observer.framework.Observer; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Random; 9 | 10 | /** 11 | * Last Modify: 2019-05-24 12 | * 13 | * @author Q-WHai 14 | * @see https://github.com/qwhai 15 | */ 16 | public class RandomNumberGenerator implements NumberGenerator { 17 | 18 | private int number = 0; 19 | private int cycle = 3; 20 | private List observers = new ArrayList<>(); 21 | private List cycleObservers = new ArrayList<>(); 22 | 23 | @Override 24 | public void registerChangedObserver(Observer observer) { 25 | observers.add(observer); 26 | } 27 | 28 | @Override 29 | public void generate() { 30 | number = new Random().nextInt(20) + 1; 31 | } 32 | 33 | @Override 34 | public void publish() { 35 | changed(); 36 | cycle(); 37 | } 38 | 39 | @Override 40 | public void registerCycleObserver(Observer observer, int t) { 41 | cycleObservers.add(observer); 42 | cycle = t; 43 | } 44 | 45 | private void changed() { 46 | for (Observer o : observers) { 47 | o.update(this); 48 | 49 | } 50 | } 51 | 52 | private void cycle() { 53 | if (0 != (number % cycle)) return; 54 | 55 | for (Observer o : cycleObservers) { 56 | o.update(this); 57 | } 58 | } 59 | 60 | @Override 61 | public int getNumber() { 62 | return number; 63 | } 64 | 65 | @Override 66 | public String getName() { 67 | return "Random Number Generator"; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/state/Lift.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.state; 2 | 3 | /** 4 | * TODO 5 | * 6 | * Create Time: 2019-04-10 16:51 7 | * Last Modify: 2019-05-24 8 | * 9 | * @author Q-WHai 10 | * @see https://github.com/qwhai 11 | */ 12 | public class Lift { 13 | 14 | static final State openningState = new OpenningState(); 15 | static final State closingState = new ClosingState(); 16 | static final State runningState = new RunningState(); 17 | static final State stoppingState = new StoppingState(); 18 | 19 | private State state; 20 | 21 | public Lift(State state) { 22 | switchState(state); 23 | } 24 | 25 | void switchState(State state) { 26 | this.state = state; 27 | this.state.setContext(this); 28 | } 29 | 30 | public boolean open() { 31 | try{ 32 | state.open(); 33 | } catch (StateLimitException ex) { 34 | ex.printStackTrace(); 35 | return false; 36 | } 37 | 38 | return true; 39 | } 40 | 41 | public boolean close() { 42 | try{ 43 | state.close(); 44 | } catch (StateLimitException ex) { 45 | ex.printStackTrace(); 46 | return false; 47 | } 48 | 49 | return true; 50 | } 51 | 52 | public boolean run() { 53 | try{ 54 | state.run(); 55 | } catch (StateLimitException ex) { 56 | ex.printStackTrace(); 57 | return false; 58 | } 59 | 60 | return true; 61 | } 62 | 63 | public boolean stop() { 64 | try{ 65 | state.stop(); 66 | } catch (StateLimitException ex) { 67 | ex.printStackTrace(); 68 | return false; 69 | } 70 | 71 | return true; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/command/MobileCalculator.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.command; 2 | 3 | import pers.hai.sample.dp.command.cmd.Command; 4 | 5 | import java.util.Stack; 6 | 7 | /** 8 | * 手机计算器对象(用于当作ComputeCore的代理) 9 | * 10 | * Create Time: 2019-05-20 10:32 11 | * Last Modify: 2019-05-20 12 | * 13 | * @author Q-WHai 14 | * @see https://github.com/qwhai 15 | */ 16 | public class MobileCalculator implements Computable, CommandAttachable { 17 | 18 | private ComputeCore core = new ComputeCore(); 19 | private ComputeResult result = new ComputeResult(); 20 | 21 | // 历史命令,用于命令撤消 22 | private Stack undoCmdStack = new Stack<>(); 23 | // 撤消历史命令,用于命令还原 24 | private Stack redoCmdStack = new Stack<>(); 25 | 26 | @Override 27 | public void add(double x) { 28 | result.setResult(core.add(result.getResult(), x)); 29 | } 30 | 31 | @Override 32 | public void sub(double x) { 33 | result.setResult(core.sub(result.getResult(), x)); 34 | } 35 | 36 | @Override 37 | public void mul(double x) { 38 | result.setResult(core.mul(result.getResult(), x)); 39 | } 40 | 41 | @Override 42 | public void div(double x) { 43 | result.setResult(core.div(result.getResult(), x)); 44 | } 45 | 46 | @Override 47 | public void attachUndo(Command command) { 48 | undoCmdStack.add(command); 49 | } 50 | 51 | @Override 52 | public void attachRedo(Command command) { 53 | redoCmdStack.add(command); 54 | } 55 | 56 | @Override 57 | public void undo() { 58 | Command cmd = undoCmdStack.pop(); 59 | cmd.undo(); 60 | } 61 | 62 | @Override 63 | public void redo() { 64 | Command cmd = redoCmdStack.pop(); 65 | cmd.redo(); 66 | } 67 | 68 | public double getResult() { 69 | return result.getResult(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/CompositeTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Test; 4 | import pers.hai.sample.dp.composite.Directory; 5 | import pers.hai.sample.dp.composite.File; 6 | import pers.hai.sample.dp.composite.FileTreatMentException; 7 | 8 | /** 9 | * TODO 10 | *

11 | * Create Time: 2019-05-30 09:35 12 | * Last Modify: 2019-05-30 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class CompositeTests extends Testable { 18 | 19 | @Test 20 | public void test1() { 21 | try { 22 | System.out.println("Making root entries..."); 23 | Directory rootdir = new Directory("root"); 24 | Directory bindir = new Directory("bin"); 25 | Directory tmpdir = new Directory("tmp"); 26 | Directory usrdir = new Directory("usr"); 27 | rootdir.add(bindir); 28 | rootdir.add(tmpdir); 29 | rootdir.add(usrdir); 30 | 31 | bindir.add(new File("vi", 1000)); 32 | bindir.add(new File("latex", 2000)); 33 | rootdir.printList(); 34 | 35 | System.out.println(); 36 | System.out.println("Making user entries..."); 37 | Directory yukidir = new Directory("yuki"); 38 | Directory hanakodir = new Directory("hanako"); 39 | Directory tomuradir = new Directory("tomura"); 40 | usrdir.add(yukidir); 41 | usrdir.add(hanakodir); 42 | usrdir.add(tomuradir); 43 | yukidir.add(new File("diary.html", 100)); 44 | yukidir.add(new File("Composite.java", 200)); 45 | hanakodir.add(new File("memo.tex", 300)); 46 | tomuradir.add(new File("game.doc", 400)); 47 | tomuradir.add(new File("junk.mail", 500)); 48 | rootdir.printList(); 49 | } catch (FileTreatMentException ex) { 50 | logger.error(ex.getMessage()); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/dynamic/jdk/DynamicProxyHandler.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.dynamic.jdk; 2 | 3 | import pers.hai.sample.dp.proxy.dynamic.IStation; 4 | import pers.hai.sample.dp.proxy.dynamic.model.StationPort; 5 | import org.apache.log4j.Logger; 6 | 7 | import java.lang.reflect.InvocationHandler; 8 | import java.lang.reflect.Method; 9 | import java.lang.reflect.Proxy; 10 | 11 | /** 12 | * Create Time: 2019-04-10 10:46 13 | * Last Modify: 2019-05-24 14 | * 15 | * @author Q-WHai 16 | * @see https://github.com/qwhai 17 | */ 18 | public class DynamicProxyHandler implements InvocationHandler { 19 | 20 | private Logger logger = Logger.getLogger(DynamicProxyHandler.class); 21 | private IStation station; 22 | 23 | public DynamicProxyHandler(IStation station) { 24 | this.station = station; 25 | } 26 | 27 | public IStation newProxyInstance() { 28 | return (IStation) Proxy.newProxyInstance( 29 | station.getClass().getClassLoader(), 30 | station.getClass().getInterfaces(), 31 | this); 32 | } 33 | 34 | @Override 35 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 36 | logBefore(method); 37 | 38 | Object o = method.invoke(station, args); 39 | 40 | logAfter(method); 41 | 42 | if (method.getName().equals("booking")) { 43 | StationPort from = (StationPort) args[0]; 44 | StationPort to = (StationPort) args[1]; 45 | if (0 > station.ticketSurplus(from, to)) { 46 | logger.info("安全检查到车票已售罄"); 47 | station.amendTicketSurplus(from, to); 48 | logger.info("车票余量已修正"); 49 | } 50 | } 51 | 52 | return o; 53 | } 54 | 55 | private void logBefore(Method method) { 56 | logger.info(String.format("在{%s}方法调用前开启的日志功能", method.getName())); 57 | } 58 | 59 | private void logAfter(Method method) { 60 | logger.info(String.format("在{%s}方法调用后开启的日志功能", method.getName())); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/dynamic/cglib/CglibProxy.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.dynamic.cglib; 2 | 3 | import pers.hai.sample.dp.proxy.dynamic.IStation; 4 | import pers.hai.sample.dp.proxy.dynamic.model.StationPort; 5 | import net.sf.cglib.proxy.Enhancer; 6 | import net.sf.cglib.proxy.MethodInterceptor; 7 | import net.sf.cglib.proxy.MethodProxy; 8 | import org.apache.log4j.Logger; 9 | 10 | import java.lang.reflect.Method; 11 | 12 | /** 13 | * TODO 14 | * 15 | * Create Time: 2019-04-10 16:07 16 | * Last Modify: 2019-05-24 17 | * 18 | * @author Q-WHai 19 | * @see https://github.com/qwhai 20 | */ 21 | public class CglibProxy implements MethodInterceptor { 22 | 23 | private Logger logger = Logger.getLogger(CglibProxy.class); 24 | private Enhancer enhancer = new Enhancer(); 25 | 26 | public Object getProxy(Class clazz) { 27 | // 设置需要创建的子类 28 | enhancer.setSuperclass(clazz); 29 | enhancer.setCallback(this); 30 | 31 | // 通过字节码技术动态创建子类实例 32 | return enhancer.create(); 33 | } 34 | 35 | @Override 36 | public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { 37 | logBefore(methodProxy); 38 | 39 | Object o = methodProxy.invokeSuper(obj, args); 40 | 41 | logAfter(methodProxy); 42 | 43 | if (method.getName().equals("booking")) { 44 | StationPort from = (StationPort) args[0]; 45 | StationPort to = (StationPort) args[1]; 46 | if (0 > ((IStation)obj).ticketSurplus(from, to)) { 47 | logger.info("安全检查到车票已售罄"); 48 | ((IStation)obj).amendTicketSurplus(from, to); 49 | logger.info("车票余量已修正"); 50 | } 51 | } 52 | 53 | return o; 54 | } 55 | 56 | private void logBefore(MethodProxy methodProxy) { 57 | logger.info(String.format("在{%s}方法调用前开启的日志功能", methodProxy.getSuperName())); 58 | } 59 | 60 | private void logAfter(MethodProxy methodProxy) { 61 | logger.info(String.format("在{%s}方法调用后开启的日志功能", methodProxy.getSuperName())); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/dynamic/NanjingnanStation.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.dynamic; 2 | 3 | import pers.hai.sample.dp.proxy.dynamic.model.StationPort; 4 | import pers.hai.sample.dp.proxy.dynamic.model.TravelPorts; 5 | import org.apache.log4j.Logger; 6 | 7 | import java.text.DecimalFormat; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * TODO 13 | * 14 | * Create Time: 2019-04-10 10:49 15 | * Last Modify: 2019-05-24 16 | * 17 | * @author Q-WHai 18 | * @see https://github.com/qwhai 19 | */ 20 | public class NanjingnanStation implements IStation { 21 | 22 | private Logger logger = Logger.getLogger(NanjingnanStation.class); 23 | 24 | private Map _ticketSurplus = new HashMap() { 25 | { 26 | put(new TravelPorts("南京", "上海虹桥"), 10); 27 | put(new TravelPorts("南京南", "上海虹桥"), 60); 28 | put(new TravelPorts("武汉", "长沙"), 23); 29 | } 30 | }; 31 | 32 | private DecimalFormat df = new DecimalFormat("######0.00"); 33 | @Override 34 | public double ticketPrice(StationPort from, StationPort to) { 35 | 36 | double price = ticketMap.get(new TravelPorts(from.getName(), to.getName())); 37 | logger.info(String.format("从 %s 到 %s 的票价为:%s", from, to, df.format(price))); 38 | 39 | return price; 40 | } 41 | 42 | @Override 43 | public int ticketSurplus(StationPort from, StationPort to) { 44 | return _ticketSurplus.get(new TravelPorts(from.getName(), to.getName())); 45 | } 46 | 47 | @Override 48 | public void amendTicketSurplus(StationPort from, StationPort to) { 49 | _ticketSurplus.replace(new TravelPorts(from.getName(), to.getName()), 0); 50 | } 51 | 52 | @Override 53 | public boolean booking(StationPort from, StationPort to) { 54 | _ticketSurplus.replace(new TravelPorts(from.getName(), to.getName()), _ticketSurplus.get(new TravelPorts(from.getName(), to.getName())) - 1); 55 | logger.info(String.format("南京南站正在出票,从 %s 到 %s,余票:%d", from, to, ticketSurplus(from, to))); 56 | 57 | return true; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/proxy/dynamic/NanjingStation.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.proxy.dynamic; 2 | 3 | import pers.hai.sample.dp.proxy.dynamic.model.StationPort; 4 | import pers.hai.sample.dp.proxy.dynamic.model.TravelPorts; 5 | import org.apache.log4j.Logger; 6 | 7 | import java.text.DecimalFormat; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * TODO 13 | * 14 | * Create Time: 2019-04-10 10:51 15 | * Last Modify: 2019-05-24 16 | * 17 | * @author Q-WHai 18 | * @see https://github.com/qwhai 19 | */ 20 | public class NanjingStation implements IStation { 21 | 22 | private Logger logger = Logger.getLogger(NanjingStation.class); 23 | 24 | private Map _ticketSurplus = new HashMap() { 25 | { 26 | put(new TravelPorts("南京", "上海虹桥"), 20); 27 | put(new TravelPorts("南京南", "上海虹桥"), 16); 28 | put(new TravelPorts("武汉", "长沙"), 7); 29 | } 30 | }; 31 | 32 | private DecimalFormat df = new DecimalFormat("######0.00"); 33 | @Override 34 | public double ticketPrice(StationPort from, StationPort to) { 35 | 36 | double price = ticketMap.get(new TravelPorts(from.getName(), to.getName())); 37 | logger.info(String.format("从 %s 到 %s 的票价为:%s", from, to, df.format(price))); 38 | 39 | return price; 40 | } 41 | 42 | @Override 43 | public int ticketSurplus(StationPort from, StationPort to) { 44 | return _ticketSurplus.get(new TravelPorts(from.getName(), to.getName())); 45 | } 46 | 47 | @Override 48 | public void amendTicketSurplus(StationPort from, StationPort to) { 49 | _ticketSurplus.replace(new TravelPorts(from.getName(), to.getName()), 0); 50 | } 51 | 52 | @Override 53 | public boolean booking(StationPort from, StationPort to) { 54 | 55 | int tp = _ticketSurplus.get(new TravelPorts(from.getName(), to.getName())); 56 | _ticketSurplus.replace(new TravelPorts(from.getName(), to.getName()), tp - 1); 57 | logger.info(String.format("南京南站正在出票,从 %s 到 %s,余票:%d", from, to, ticketSurplus(from, to))); 58 | return true; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/FlyweightTests.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.apache.log4j.Logger; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | import pers.hai.sample.dp.flyweight.*; 7 | 8 | /** 9 | * TODO 10 | *

11 | * Create Time: 2019-06-03 15:12 12 | * Last Modify: 2019-06-03 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class FlyweightTests extends Testable { 18 | 19 | private final Logger logger = Logger.getLogger(FlyweightTests.class); 20 | 21 | @Test 22 | public void test1() { 23 | ShapeFactory factory = ShapeFactory.getInstance(); 24 | Circular cir1 = factory.createCirculer("red"); 25 | cir1.setX(100); 26 | cir1.setY(100); 27 | cir1.setR(100); 28 | cir1.draw(); 29 | 30 | Circular cir2 = factory.createCirculer("blue"); 31 | cir2.setX(100); 32 | cir2.setY(300); 33 | cir2.setR(200); 34 | cir2.draw(); 35 | 36 | Circular cir3 = factory.createCirculer("red"); 37 | cir3.setX(20); 38 | cir3.setY(50); 39 | cir3.setR(300); 40 | cir3.draw(); 41 | 42 | Assert.assertNotSame(cir1, cir2); 43 | Assert.assertNotSame(cir2, cir3); 44 | Assert.assertSame(cir1, cir3); 45 | } 46 | 47 | @Test 48 | public void test2() { 49 | ShapeFactory factory = ShapeFactory.getInstance(); 50 | Rectangle rect1 = factory.createRectangle("red"); 51 | rect1.setX(12); 52 | rect1.setY(23); 53 | rect1.setWidth(13); 54 | rect1.setHeight(565); 55 | rect1.draw(); 56 | 57 | Rectangle rect2 = factory.createRectangle("black"); 58 | rect2.setX(122); 59 | rect2.setY(11); 60 | rect2.setWidth(13); 61 | rect2.setHeight(98); 62 | rect2.draw(); 63 | 64 | Rectangle rect3 = factory.createRectangle("red"); 65 | rect3.setX(212); 66 | rect3.setY(12); 67 | rect3.setWidth(66); 68 | rect3.setHeight(76); 69 | rect3.draw(); 70 | 71 | Assert.assertNotSame(rect1, rect2); 72 | Assert.assertNotSame(rect2, rect3); 73 | Assert.assertSame(rect1, rect3); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## design-pattern 2 | 基于Java的设计模式集合示例 3 | 4 | ![](https://img.shields.io/badge/java-1.8-red.svg) 5 | ![](https://img.shields.io/badge/intellij%20idea-2018.3.3-brown.svg) 6 | ![](https://img.shields.io/badge/maven-3.6.0-thistle.svg) 7 | 8 | ------------------------------------------ 9 | 10 | ## 设计模式列单 11 | 12 | - 创建模式 13 | - [工厂模式 Factory](https://qwhai.blog.csdn.net/article/details/46225213) 14 | - [单例模式 Singleton](https://qwhai.blog.csdn.net/article/details/46006071) 15 | - [构建模式 Builder](https://qwhai.blog.csdn.net/article/details/50246499) 16 | - [原型模式 Prototype](https://qwhai.blog.csdn.net/article/details/50787390) 17 | - 结构模式 18 | - [享元模式 Flyweight](https://qwhai.blog.csdn.net/article/details/51241598) 19 | - [桥接模式 Bridge](https://qwhai.blog.csdn.net/article/details/51024127) 20 | - [装饰者模式 Decorator](https://qwhai.blog.csdn.net/article/details/45870027) 21 | - [组合模式 Composite](https://qwhai.blog.csdn.net/article/details/51437883) 22 | - [适配器模式 Adapter](https://qwhai.blog.csdn.net/article/details/50326851) 23 | - [代理模式 Proxy](https://qwhai.blog.csdn.net/article/details/50326817) 24 | - [外观模式 Facade](https://qwhai.blog.csdn.net/article/details/51592617) 25 | - 行为模式 26 | - [迭代器模式 Iterator](https://qwhai.blog.csdn.net/article/details/50799562) 27 | - [模板方法模式 Template Method](src/main/java/pers/hai/sample/dp/template) 28 | - [责任链模式 Chain of Responsibility](src/main/java/pers/hai/sample/dp/cor) 29 | - [备忘录模式 Memento](src/main/java/pers/hai/sample/dp/memento) 30 | - [中介者模式 Mediator](src/main/java/pers/hai/sample/dp/mediator) 31 | - [解释器模式 Interpreter](src/main/java/pers/hai/sample/dp/interpreter) 32 | - [策略模式 Strategy](https://qwhai.blog.csdn.net/article/details/45894511) 33 | - [状态模式 State](https://qwhai.blog.csdn.net/article/details/51596556) 34 | - [观察者模式 Observer](https://qwhai.blog.csdn.net/article/details/45483511) 35 | - [访问者模式 Visitor](src/main/java/pers/hai/sample/dp/visitor) 36 | - [命令模式 Command](src/main/java/pers/hai/sample/dp/command) 37 | - IO 38 | - [反应堆模式 Reactor]() 39 | 40 | ------------------------------------------ 41 | 42 | - [CSDN](https://qwhai.blog.csdn.net/) 43 | - [Design pattern special column](http://blog.csdn.net/column/details/java-designpattern-w.html) 44 | - [Github](https://github.com/qwhai) 45 | - [E-mail](return_zero0@163.com) 46 | -------------------------------------------------------------------------------- /src/main/java/pers/hai/sample/dp/memento/Gamer.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp.memento; 2 | 3 | import org.apache.log4j.Logger; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Iterator; 7 | import java.util.List; 8 | import java.util.Random; 9 | 10 | /** 11 | * TODO 12 | *

13 | * Create Time: 2019-06-13 17:16 14 | * Last Modify: 2019-06-13 15 | * 16 | * @author Q-WHai 17 | * @see https://github.com/qwhai 18 | */ 19 | public class Gamer { 20 | 21 | private final Logger logger = Logger.getLogger(Gamer.class); 22 | 23 | private int money; 24 | private List fruits = new ArrayList<>(); 25 | private Random random = new Random(); 26 | 27 | private static String[] fruitNames = { 28 | " 苹果 ", " 香蕉 ", " 桔子 ", " 葡萄 " 29 | }; 30 | 31 | public Gamer(int money) { 32 | this.money = money; 33 | } 34 | 35 | public int getMoney() { 36 | return this.money; 37 | } 38 | 39 | public void bet() { 40 | int dict = random.nextInt(6) + 1; 41 | switch (dict) { 42 | case 1: 43 | money += 100; 44 | logger.info("所持金币增加了"); 45 | break; 46 | case 2: 47 | money /= 2; 48 | logger.info("所持金币减半了"); 49 | break; 50 | case 6: 51 | String fruit = getFruit(); 52 | logger.info(String.format("获得了水果(%s)", fruit)); 53 | fruits.add(fruit); 54 | break; 55 | default: 56 | logger.info("什么都没发生"); 57 | break; 58 | } 59 | } 60 | 61 | public Memento createMemento() { 62 | Memento memento = new Memento(money); 63 | Iterator iterator = fruits.iterator(); 64 | while (iterator.hasNext()) { 65 | String fruit = (String) iterator.next(); 66 | if (fruit.startsWith("好吃的")) 67 | memento.addFruit(fruit); 68 | } 69 | 70 | return memento; 71 | } 72 | 73 | public void restoreMemento(Memento memento) { 74 | this.money = memento.getMoney(); 75 | this.fruits = memento.getFruits(); 76 | } 77 | 78 | @Override 79 | public String toString() { 80 | return String.format("{money: %d, friuts: %s}", getMoney(), fruits); 81 | } 82 | 83 | private String getFruit() { 84 | String prefix = ""; 85 | if (random.nextBoolean()) { 86 | prefix = "好吃的"; 87 | } 88 | 89 | return String.format("%s%s", prefix, fruitNames[random.nextInt(fruitNames.length)]); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | git.qwhai 8 | design.pattern 9 | 1.0-SNAPSHOT 10 | 11 | design.pattern 12 | 13 | http://www.example.com 14 | 15 | 16 | UTF-8 17 | 12 18 | 12 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | 4.11 26 | 27 | 28 | 29 | log4j 30 | log4j 31 | 1.2.17 32 | 33 | 34 | 35 | org.javatuples 36 | javatuples 37 | 1.2 38 | 39 | 40 | 41 | cglib 42 | cglib-nodep 43 | 2.2.2 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | maven-clean-plugin 53 | 3.1.0 54 | 55 | 56 | 57 | maven-resources-plugin 58 | 3.0.2 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-compiler-plugin 63 | 3.8.0 64 | 65 | 12 66 | 12 67 | 68 | 69 | 70 | maven-surefire-plugin 71 | 2.22.1 72 | 73 | 74 | maven-jar-plugin 75 | 3.0.2 76 | 77 | 78 | maven-install-plugin 79 | 2.5.2 80 | 81 | 82 | maven-deploy-plugin 83 | 2.8.2 84 | 85 | 86 | 87 | maven-site-plugin 88 | 3.7.1 89 | 90 | 91 | maven-project-info-reports-plugin 92 | 3.0.0 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/CommandPatternTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import pers.hai.sample.dp.command.cmd.*; 6 | import pers.hai.sample.dp.command.Computable; 7 | import pers.hai.sample.dp.command.MobileCalculator; 8 | 9 | /** 10 | * TODO 11 | * Create Time: 2019-04-12 18:05 12 | * Last Modify: 2019-05-24 13 | * 14 | * @author Q-WHai 15 | * @see https://github.com/qwhai 16 | */ 17 | public class CommandPatternTest extends Testable { 18 | 19 | 20 | @Test 21 | public void test1() { 22 | Computable computable = new MobileCalculator(); 23 | Command cmd1 = new AddCommand(1, computable); 24 | Command cmd2 = new AddCommand(2, computable); 25 | 26 | cmd1.calculate(); 27 | cmd2.calculate(); 28 | 29 | Assert.assertEquals(3.0, ((MobileCalculator) computable).getResult(), 0); 30 | } 31 | 32 | @Test 33 | public void test2() { 34 | Computable computable = new MobileCalculator(); 35 | Command cmd1 = new AddCommand(10, computable); 36 | Command cmd2 = new SubCommand(2, computable); 37 | 38 | cmd1.calculate(); 39 | cmd2.calculate(); 40 | 41 | Assert.assertEquals(8.0, ((MobileCalculator) computable).getResult(), 0); 42 | } 43 | 44 | @Test 45 | public void test3() { 46 | Computable computable = new MobileCalculator(); 47 | Command cmd1 = new AddCommand(3, computable); 48 | Command cmd2 = new MulCommand(2, computable); 49 | 50 | cmd1.calculate(); 51 | cmd2.calculate(); 52 | 53 | Assert.assertEquals(6.0, ((MobileCalculator) computable).getResult(), 0); 54 | } 55 | 56 | @Test 57 | public void test4() { 58 | Computable computable = new MobileCalculator(); 59 | Command cmd1 = new AddCommand(8, computable); 60 | Command cmd2 = new DivCommand(2, computable); 61 | 62 | cmd1.calculate(); 63 | cmd2.calculate(); 64 | 65 | Assert.assertEquals(4.0, ((MobileCalculator) computable).getResult(), 0); 66 | } 67 | 68 | @Test 69 | public void test5() { 70 | Computable computable = new MobileCalculator(); 71 | Command cmd1 = new AddCommand(8, computable); 72 | Command cmd2 = new AddCommand(2, computable); 73 | 74 | cmd1.calculate(); 75 | cmd2.calculate(); 76 | 77 | // + 运算后 78 | Assert.assertEquals(10.0, ((MobileCalculator) computable).getResult(), 0); 79 | 80 | computable.undo(); 81 | // undo 运算后 82 | Assert.assertEquals(8.0, ((MobileCalculator) computable).getResult(), 0); 83 | 84 | Command cmd3 = new SubCommand(6, computable); 85 | cmd3.calculate(); 86 | // - 运算后 87 | Assert.assertEquals(2.0, ((MobileCalculator) computable).getResult(), 0); 88 | 89 | computable.undo(); 90 | // undo 运算后 91 | Assert.assertEquals(8.0, ((MobileCalculator) computable).getResult(), 0); 92 | 93 | Command cmd4 = new MulCommand(2, computable); 94 | cmd4.calculate(); 95 | // × 运算后 96 | Assert.assertEquals(16.0, ((MobileCalculator) computable).getResult(), 0); 97 | 98 | computable.undo(); 99 | // undo 运算后 100 | Assert.assertEquals(8.0, ((MobileCalculator) computable).getResult(), 0); 101 | 102 | Command cmd5 = new DivCommand(4, computable); 103 | cmd5.calculate(); 104 | // ÷ 运算后 105 | Assert.assertEquals(2.0, ((MobileCalculator) computable).getResult(), 0); 106 | 107 | computable.undo(); 108 | // undo 运算后 109 | Assert.assertEquals(8.0, ((MobileCalculator) computable).getResult(), 0); 110 | } 111 | 112 | @Test 113 | public void test6() { 114 | Computable computable = new MobileCalculator(); 115 | Command cmd1 = new AddCommand(8, computable); 116 | Command cmd2 = new AddCommand(2, computable); 117 | 118 | cmd1.calculate(); 119 | cmd2.calculate(); 120 | 121 | // + 运算后 122 | Assert.assertEquals(10.0, ((MobileCalculator) computable).getResult(), 0); 123 | 124 | computable.undo(); 125 | // undo 运算后 126 | Assert.assertEquals(8.0, ((MobileCalculator) computable).getResult(), 0); 127 | 128 | computable.redo(); 129 | // redo 运算后 130 | Assert.assertEquals(10.0, ((MobileCalculator) computable).getResult(), 0); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/test/java/pers/hai/sample/dp/ProxyPatternTest.java: -------------------------------------------------------------------------------- 1 | package pers.hai.sample.dp; 2 | 3 | import pers.hai.sample.dp.proxy.dynamic.cglib.CglibProxy; 4 | import pers.hai.sample.dp.proxy.dynamic.IStation; 5 | import pers.hai.sample.dp.proxy.dynamic.NanjingStation; 6 | import pers.hai.sample.dp.proxy.dynamic.NanjingnanStation; 7 | import pers.hai.sample.dp.proxy.dynamic.jdk.DynamicProxyHandler; 8 | import pers.hai.sample.dp.proxy.dynamic.model.StationPort; 9 | import pers.hai.sample.dp.proxy.virtual1.ITicketable; 10 | import pers.hai.sample.dp.proxy.virtual1.StationProxy; 11 | import pers.hai.sample.dp.proxy.virtual2.PrinterProxy; 12 | import org.apache.log4j.Logger; 13 | import org.junit.Assert; 14 | import org.junit.Test; 15 | import pers.hai.sample.dp.proxy.access.*; 16 | 17 | import java.lang.reflect.Proxy; 18 | 19 | /** 20 | * Create Time: 2019-03-27 17:11 21 | * Last Modify: 2019-05-24 22 | * 23 | * @author Q-WHai 24 | * @see https://github.com/qwhai 25 | */ 26 | public class ProxyPatternTest { 27 | 28 | private Logger logger = Logger.getLogger(ProxyPatternTest.class); 29 | 30 | // 测试虚代理1 31 | @Test 32 | public void test1() { 33 | ITicketable ticketable = new StationProxy(); 34 | double price = ticketable.ticketPrice("nanjingnan", "shanghaihongqiao"); 35 | Assert.assertEquals(144.5, price, 0); 36 | 37 | for (int i = 0; i < 100; i++) { 38 | ticketable.booking("nanjingnan", "shanghaihongqiao"); 39 | } 40 | } 41 | 42 | // 测试虚代理2 43 | @Test 44 | public void test2() { 45 | PrinterProxy printerProxy = new PrinterProxy("打印机-1"); 46 | printerProxy.print("[这里是第一次打印内容]"); 47 | printerProxy.setName("打印机-2"); 48 | printerProxy.print("[这里是第二次打印内容]"); 49 | } 50 | 51 | // 测试Access代理:访客 52 | @Test 53 | public void test3() { 54 | Forum forum1 = new TouristProxy(); 55 | try { 56 | forum1.createTopic(); 57 | } catch (UnauthorizedException ex) { 58 | ex.printStackTrace(); 59 | } 60 | 61 | try { 62 | forum1.moidfyTopic(); 63 | } catch (UnauthorizedException ex) { 64 | ex.printStackTrace(); 65 | } 66 | 67 | try { 68 | forum1.deleteTopic(); 69 | } catch (UnauthorizedException ex) { 70 | ex.printStackTrace(); 71 | } 72 | 73 | try { 74 | forum1.auditTopic("123"); 75 | } catch (UnauthorizedException ex) { 76 | ex.printStackTrace(); 77 | } 78 | 79 | try { 80 | forum1.visit(); 81 | } catch (UnauthorizedException ex) { 82 | ex.printStackTrace(); 83 | } 84 | 85 | try { 86 | forum1.comment(); 87 | } catch (UnauthorizedException ex) { 88 | ex.printStackTrace(); 89 | } 90 | } 91 | 92 | // 测试Access代理:题主 93 | @Test 94 | public void test4() { 95 | Forum forum1 = new WriterProxy(); 96 | try { 97 | forum1.createTopic(); 98 | } catch (UnauthorizedException ex) { 99 | ex.printStackTrace(); 100 | } 101 | 102 | try { 103 | forum1.moidfyTopic(); 104 | } catch (UnauthorizedException ex) { 105 | ex.printStackTrace(); 106 | } 107 | 108 | try { 109 | forum1.deleteTopic(); 110 | } catch (UnauthorizedException ex) { 111 | ex.printStackTrace(); 112 | } 113 | 114 | try { 115 | forum1.auditTopic("123"); 116 | } catch (UnauthorizedException ex) { 117 | ex.printStackTrace(); 118 | } 119 | 120 | try { 121 | forum1.visit(); 122 | } catch (UnauthorizedException ex) { 123 | ex.printStackTrace(); 124 | } 125 | 126 | try { 127 | forum1.comment(); 128 | } catch (UnauthorizedException ex) { 129 | ex.printStackTrace(); 130 | } 131 | } 132 | 133 | // 测试Access代理:管理员 134 | @Test 135 | public void test5() { 136 | Forum forum1 = new ManagerProxy(); 137 | try { 138 | forum1.createTopic(); 139 | } catch (UnauthorizedException ex) { 140 | ex.printStackTrace(); 141 | } 142 | 143 | try { 144 | forum1.moidfyTopic(); 145 | } catch (UnauthorizedException ex) { 146 | ex.printStackTrace(); 147 | } 148 | 149 | try { 150 | forum1.deleteTopic(); 151 | } catch (UnauthorizedException ex) { 152 | ex.printStackTrace(); 153 | } 154 | 155 | try { 156 | forum1.auditTopic("123"); 157 | } catch (UnauthorizedException ex) { 158 | ex.printStackTrace(); 159 | } 160 | 161 | try { 162 | forum1.visit(); 163 | } catch (UnauthorizedException ex) { 164 | ex.printStackTrace(); 165 | } 166 | 167 | try { 168 | forum1.comment(); 169 | } catch (UnauthorizedException ex) { 170 | ex.printStackTrace(); 171 | } 172 | } 173 | 174 | // 测试Dynamic代理 175 | @Test 176 | public void test6() { 177 | // 测试动态代理南京南站售票 178 | IStation station1 = new NanjingnanStation(); 179 | 180 | DynamicProxyHandler handler1 = new DynamicProxyHandler(station1); 181 | IStation proxy1 = (IStation) Proxy.newProxyInstance(station1.getClass().getClassLoader(), station1.getClass().getInterfaces(), handler1); 182 | 183 | double price1 = proxy1.ticketPrice(new StationPort("南京南"), new StationPort("上海虹桥")); 184 | Assert.assertEquals(144.5, price1, 0); 185 | for (int i = 0; i < 10; i++) { 186 | proxy1.booking(new StationPort("南京南"), new StationPort("上海虹桥")); 187 | } 188 | 189 | // 测试动态代理南京站售票 190 | IStation station2 = new NanjingStation(); 191 | DynamicProxyHandler handler2 = new DynamicProxyHandler(station2); 192 | IStation proxy2 = (IStation) Proxy.newProxyInstance(station2.getClass().getClassLoader(), station2.getClass().getInterfaces(), handler2); 193 | 194 | double price2 = proxy2.ticketPrice(new StationPort("武汉"), new StationPort("长沙")); 195 | Assert.assertEquals(164.5, price2, 0); 196 | for (int i = 0; i < 10; i++) { 197 | proxy2.booking(new StationPort("武汉"), new StationPort("长沙")); 198 | } 199 | } 200 | 201 | // 测试Dynamic代理 202 | @Test 203 | public void test7() { 204 | // 测试动态代理南京南站售票 205 | DynamicProxyHandler handler = new DynamicProxyHandler(new NanjingnanStation()); 206 | IStation proxy = (IStation) Proxy.newProxyInstance( 207 | IStation.class.getClassLoader(), 208 | new Class[] { IStation.class }, 209 | handler); 210 | 211 | double price = proxy.ticketPrice(new StationPort("南京南"), new StationPort("上海虹桥")); 212 | Assert.assertEquals(144.5, price, 0); 213 | for (int i = 0; i < 70; i++) { 214 | if (60 == i) { 215 | System.out.println(i); 216 | } 217 | 218 | boolean bf = proxy.booking(new StationPort("南京南"), new StationPort("上海虹桥")); 219 | Assert.assertTrue(bf); 220 | } 221 | } 222 | 223 | // 测试基于JDK方式的Dynamic代理 224 | @Test 225 | public void test8() { 226 | // 测试动态代理南京南站售票 227 | DynamicProxyHandler handler = new DynamicProxyHandler(new NanjingnanStation()); 228 | IStation proxy = handler.newProxyInstance(); 229 | 230 | double price = proxy.ticketPrice(new StationPort("南京南"), new StationPort("上海虹桥")); 231 | Assert.assertEquals(144.5, price, 0); 232 | for (int i = 0; i < 70; i++) { 233 | boolean bf = proxy.booking(new StationPort("南京南"), new StationPort("上海虹桥")); 234 | Assert.assertTrue(bf); 235 | } 236 | } 237 | 238 | // 测试基于CGLIB方式的Dynamic代理 239 | @Test 240 | public void test9() { 241 | CglibProxy proxy = new CglibProxy(); 242 | IStation station = (IStation) proxy.getProxy(NanjingnanStation.class); // 通过动态生成子类的方式创建代理类 243 | 244 | double price = station.ticketPrice(new StationPort("南京南"), new StationPort("上海虹桥")); 245 | logger.info(String.format("查询到票价:%s", price)); 246 | Assert.assertEquals(144.5, price, 0); 247 | for (int i = 0; i < 70; i++) { 248 | boolean bf = station.booking(new StationPort("南京南"), new StationPort("上海虹桥")); 249 | Assert.assertTrue(bf); 250 | } 251 | } 252 | } 253 | --------------------------------------------------------------------------------