├── .gitignore ├── LICENSE.txt ├── README ├── jpatterns.iml ├── jpatterns.iws ├── lib ├── cglib-nodep-2.2.jar └── easymock-3.0.jar ├── pom.xml ├── src ├── main │ └── java │ │ └── org │ │ └── jpatterns │ │ ├── core │ │ ├── DesignPattern.java │ │ ├── Refactoring.java │ │ ├── Source.java │ │ └── Type.java │ │ ├── doc │ │ ├── PatternComment.java │ │ └── PatternParticipants.java │ │ ├── gof │ │ ├── AbstractFactoryPattern.java │ │ ├── AdapterPattern.java │ │ ├── BridgePattern.java │ │ ├── BuilderPattern.java │ │ ├── ChainOfResponsibilityPattern.java │ │ ├── CommandPattern.java │ │ ├── CompositePattern.java │ │ ├── DecoratorPattern.java │ │ ├── FacadePattern.java │ │ ├── FactoryMethodPattern.java │ │ ├── FlyweightPattern.java │ │ ├── InterpreterPattern.java │ │ ├── IteratorPattern.java │ │ ├── MediatorPattern.java │ │ ├── MementoPattern.java │ │ ├── ObserverPattern.java │ │ ├── PrototypePattern.java │ │ ├── ProxyPattern.java │ │ ├── SingletonPattern.java │ │ ├── StatePattern.java │ │ ├── StrategyPattern.java │ │ ├── TemplateMethodPattern.java │ │ └── VisitorPattern.java │ │ ├── jee │ │ ├── BusinessDelegatePattern.java │ │ ├── DataAccessObjectPattern.java │ │ ├── ModelViewController.java │ │ └── package-info.java │ │ ├── package-info.java │ │ └── plopd │ │ └── NullObjectPattern.java └── test │ └── java │ └── org │ └── jpatterns │ ├── gof │ ├── AbstractFactoryTest.java │ ├── AdapterTest.java │ ├── BridgeTest.java │ ├── BuilderTest.java │ ├── ChainOfResponsibilityTest.java │ ├── CommandGUIActionTest.java │ ├── CommandTest.java │ ├── CompositeTest.java │ ├── DecoratorTest.java │ ├── FacadeTest.java │ ├── FactoryMethodTest.java │ ├── FlyweightTest.java │ ├── ProxyTest.java │ ├── SingletonEagerTest.java │ ├── SingletonLazyTest.java │ ├── SingletonTest.java │ ├── StrategyTest.java │ └── TemplateMethodTest.java │ ├── jee │ ├── BusinessDelegateTest.java │ ├── DataAccessObjectTest.java │ └── ModelViewControllerTest.java │ └── plopd │ └── NullObjectTest.java └── uml ├── ee ├── BusinessDelegateStructure.gif ├── DaoStructure.gif └── MVCStructure.gif └── gof ├── AbstractFactoryStructure.gif ├── AbstractFactoryUserViewStructure.gif ├── BridgeStructure.gif ├── ChainOfResponsibilityStructure.gif ├── ClassAdapterStructure.gif ├── CommandStructure.gif ├── CompositeStructure.gif ├── DecoratorStructure.gif ├── FacadeStructure.gif ├── FactoryMethodStructure.gif ├── FlyweightStructure.gif ├── IteratorStructure.gif ├── MementoStructure.gif ├── ObjectAdapterStructure.gif ├── ObserverStructure.gif ├── ProxyStructure.gif ├── SingletonStructure.gif ├── StateStructure.gif ├── StrategyStructure.gif ├── TemplateMethodStructure.gif └── VisitorStructure.gif /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .classpath 3 | .project 4 | .settings 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2010 Heinz Kabutz 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | JPatterns is a collection of annotations that should make it easier to communicate 2 | the use of (Design)Patterns within your code to your fellow developers and 3 | your future self. 4 | 5 | -------------------------------------------------------------------------------- /jpatterns.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /lib/cglib-nodep-2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/lib/cglib-nodep-2.2.jar -------------------------------------------------------------------------------- /lib/easymock-3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/lib/easymock-3.0.jar -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.sonatype.oss 8 | oss-parent 9 | 7 10 | 11 | 12 | org.jpatterns 13 | jpatterns 14 | 0.0.1 15 | jar 16 | Java Design Pattern Annotations 17 | 18 | Design Patterns are typically encoded into Java code in an ad-hoc fashion. 19 | They are either embedded into the names of the classes or written into the 20 | Javadocs. 21 | Unfortunately it is impossible to accurately determine a pattern based 22 | solely on the 23 | class structure without knowing the intent of the code author. 24 | 25 | JPatterns is a collection of annotations that make it easy to communicate 26 | the use 27 | of (Design)Patterns within your code to your fellow developers and your 28 | future self. 29 | 30 | http://jpatterns.org 31 | 32 | 33 | The Apache Software License, Version 2.0 34 | http://www.apache.org/licenses/LICENSE-2.0.txt 35 | repo 36 | 37 | 38 | 39 | http://github.com/jexp/jpatterns 40 | git://github.com/jexp/jpatterns.git 41 | git@github.com:jexp/jpatterns.git 42 | 43 | 44 | 45 | 46 | 47 | org.apache.maven.plugins 48 | maven-compiler-plugin 49 | 2.3.2 50 | 51 | 1.5 52 | 1.5 53 | 54 | 55 | 56 | org.apache.maven.plugins 57 | maven-javadoc-plugin 58 | 2.7 59 | 60 | 61 | attach-javadocs 62 | 63 | jar 64 | 65 | 66 | 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-source-plugin 71 | 72 | 73 | attach-sources 74 | 75 | jar 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | junit 86 | junit-dep 87 | 4.5 88 | test 89 | 90 | 91 | org.easymock 92 | easymock 93 | 2.4 94 | test 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/core/DesignPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.core; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author Michael Hunger 7 | * @since 2010-07-14 8 | */ 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Target(ElementType.ANNOTATION_TYPE) 11 | @Documented 12 | @Inherited 13 | public @interface DesignPattern { 14 | Source source() default Source.GoF; 15 | 16 | Type type(); 17 | 18 | String[] urls() default {}; 19 | 20 | Refactoring[] refactorings() default {}; 21 | 22 | Class[] related() default {}; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/core/Refactoring.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.core; 2 | 3 | /** 4 | * @author Michael Hunger 5 | * @since 2010-08-08 6 | */ 7 | public enum Refactoring { 8 | ExtractMethodObject, ExtractParameterObject 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/core/Source.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.core; 2 | 3 | /** 4 | * @author Michael Hunger 5 | * @since 2010-07-14 6 | */ 7 | public enum Source { 8 | GoF, POSA, PoEAA, PLoPD3, CoreJ2EE, Other, Hophe 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/core/Type.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.core; 2 | 3 | /** 4 | * @author Michael Hunger 5 | * @since 2010-07-14 6 | */ 7 | public enum Type { 8 | CREATIONAL, STRUCTURAL, BEHAVIORAL, USER_INTERFACE, MESSAGING, ENTERPRISE 9 | } -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/doc/PatternComment.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.doc; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author Heinz Kabutz 7 | * @since 2010-08-09 8 | * @deprecated Please use the comment = "..." attribute in future 9 | */ 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target({ 12 | ElementType.TYPE, 13 | ElementType.CONSTRUCTOR, 14 | ElementType.FIELD, 15 | ElementType.LOCAL_VARIABLE, 16 | ElementType.METHOD, 17 | ElementType.PARAMETER 18 | }) 19 | @Documented 20 | @Inherited 21 | @Deprecated 22 | public @interface PatternComment { 23 | String value(); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/doc/PatternParticipants.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.doc; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author Heinz Kabutz 7 | * @since 2010-08-09 8 | * @deprecated Please use the participants = {...} attribute in future 9 | */ 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target({ 12 | ElementType.TYPE, 13 | ElementType.CONSTRUCTOR, 14 | ElementType.FIELD, 15 | ElementType.LOCAL_VARIABLE, 16 | ElementType.METHOD, 17 | ElementType.PARAMETER 18 | }) 19 | @Documented 20 | @Inherited 21 | @Deprecated 22 | public @interface PatternParticipants { 23 | Class[] value(); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/AbstractFactoryPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 87]: Provide an interface for creating families of 9 | * related or dependent objects without specifying their concrete classes. 10 | *

11 | * 12 | *

13 | * 14 | * 15 | * @author Heinz Kabutz, Michael Hunger 16 | * @since 2010-08-09 17 | */ 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @Target(ElementType.TYPE) 20 | @Documented 21 | @DesignPattern(type = Type.CREATIONAL, 22 | related = {FactoryMethodPattern.class, PrototypePattern.class, 23 | SingletonPattern.class}) 24 | public @interface AbstractFactoryPattern { 25 | Class[] participants() default {}; 26 | 27 | String comment() default ""; 28 | 29 | @Retention(RetentionPolicy.RUNTIME) 30 | @Target(ElementType.TYPE) 31 | @Documented 32 | public @interface AbstractProduct { 33 | Class[] participants() default {}; 34 | 35 | String comment() default ""; 36 | } 37 | 38 | @Retention(RetentionPolicy.RUNTIME) 39 | @Target(ElementType.TYPE) 40 | @Documented 41 | public @interface ConcreteProduct { 42 | Class[] participants() default {}; 43 | 44 | String comment() default ""; 45 | } 46 | 47 | @Retention(RetentionPolicy.RUNTIME) 48 | @Target(ElementType.METHOD) 49 | @Documented 50 | public @interface FactoryMethod { 51 | Class[] participants() default {}; 52 | 53 | String comment() default ""; 54 | } 55 | 56 | @Retention(RetentionPolicy.RUNTIME) 57 | @Target(ElementType.TYPE) 58 | @Documented 59 | public @interface AbstractFactory { 60 | Class[] participants() default {}; 61 | 62 | String comment() default ""; 63 | } 64 | 65 | @Retention(RetentionPolicy.RUNTIME) 66 | @Target(ElementType.TYPE) 67 | @Documented 68 | public @interface ConcreteFactory { 69 | Class[] participants() default {}; 70 | 71 | String comment() default ""; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/AdapterPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 139]: Convert the interface of a class into another 9 | * interface clients expect. Adapter lets classes work together that couldn't 10 | * otherwise because of incompatible interfaces. 11 | *

12 | * The structure for an object adapter is: 13 | *

14 | * 15 | *

16 | * The structure for a class adapter is: 17 | *

18 | * 19 | * 20 | * @author Heinz Kabutz 21 | * @since 2010-07-28 22 | */ 23 | @Retention(RetentionPolicy.RUNTIME) 24 | @Target(ElementType.TYPE) 25 | @Documented 26 | @DesignPattern(type = Type.STRUCTURAL, 27 | related = {BridgePattern.class, DecoratorPattern.class, ProxyPattern.class}) 28 | public @interface AdapterPattern { 29 | Class[] participants() default {}; 30 | 31 | String comment() default ""; 32 | 33 | @Retention(RetentionPolicy.RUNTIME) 34 | @Target(ElementType.TYPE) 35 | @Documented 36 | public @interface Adapter { 37 | Class[] participants() default {}; 38 | 39 | String comment() default ""; 40 | 41 | Variation value() default Variation.OBJECT; 42 | } 43 | 44 | /** 45 | * We would hardly ever use this annotation as the adaptee is 46 | * usually not aware that he is being adapted. 47 | */ 48 | @Retention(RetentionPolicy.RUNTIME) 49 | @Target(ElementType.TYPE) 50 | @Documented 51 | public @interface Adaptee { 52 | Class[] participants() default {}; 53 | 54 | String comment() default ""; 55 | } 56 | 57 | public enum Variation { 58 | OBJECT, 59 | CLASS, 60 | /** 61 | * See http://www.javaspecialists.eu/archive/Issue108.html 62 | */ 63 | DYNAMIC 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/BridgePattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 151]: Decouple an abstraction from its implementation 9 | * so that the two can vary independently. 10 | *

11 | * 12 | * 13 | * @author Heinz Kabutz 14 | * @since 2010-07-28 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target(ElementType.TYPE) 18 | @Documented 19 | @DesignPattern(type = Type.STRUCTURAL, 20 | related = {AbstractFactoryPattern.class, AdapterPattern.class}) 21 | public @interface BridgePattern { 22 | Class[] participants() default {}; 23 | 24 | String comment() default ""; 25 | 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Target(ElementType.TYPE) 28 | @Documented 29 | public @interface Abstraction { 30 | Class[] participants() default {}; 31 | 32 | String comment() default ""; 33 | } 34 | 35 | @Retention(RetentionPolicy.RUNTIME) 36 | @Target(ElementType.TYPE) 37 | @Documented 38 | public @interface RefinedAbstraction { 39 | Class[] participants() default {}; 40 | 41 | String comment() default ""; 42 | } 43 | 44 | @Retention(RetentionPolicy.RUNTIME) 45 | @Target(ElementType.TYPE) 46 | @Documented 47 | public @interface Implementor { 48 | Class[] participants() default {}; 49 | 50 | String comment() default ""; 51 | } 52 | 53 | @Retention(RetentionPolicy.RUNTIME) 54 | @Target(ElementType.TYPE) 55 | @Documented 56 | public @interface ConcreteImplementor { 57 | Class[] participants() default {}; 58 | 59 | String comment() default ""; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/BuilderPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 97]: Separate the construction of a complex object 9 | * from its representation so that the same construction process can create 10 | * different representations. 11 | * 12 | * @author Heinz Kabutz 13 | * @since 2010-08-09 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.TYPE) 17 | @Documented 18 | @DesignPattern(type = Type.CREATIONAL, 19 | related = {AbstractFactoryPattern.class, CompositePattern.class}) 20 | public @interface BuilderPattern { 21 | Class[] participants() default {}; 22 | 23 | String comment() default ""; 24 | 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Target(ElementType.TYPE) 27 | @Documented 28 | public @interface Director { 29 | Class[] participants() default {}; 30 | 31 | String comment() default ""; 32 | } 33 | 34 | @Retention(RetentionPolicy.RUNTIME) 35 | @Target(ElementType.TYPE) 36 | @Documented 37 | public @interface Builder { 38 | Class[] participants() default {}; 39 | 40 | String comment() default ""; 41 | } 42 | 43 | @Retention(RetentionPolicy.RUNTIME) 44 | @Target(ElementType.TYPE) 45 | @Documented 46 | public @interface ConcreteBuilder { 47 | Class[] participants() default {}; 48 | 49 | String comment() default ""; 50 | } 51 | 52 | @Retention(RetentionPolicy.RUNTIME) 53 | @Target(ElementType.TYPE) 54 | @Documented 55 | public @interface Product { 56 | Class[] participants() default {}; 57 | 58 | String comment() default ""; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/ChainOfResponsibilityPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 223]: Avoid coupling the sender of a request to its 9 | * receiver by giving more than one object a chance to handle the request. Chain 10 | * the receiving objects and pass the request along the chain until an object 11 | * handles it. 12 | *

13 | * 14 | * 15 | * @author Heinz Kabutz 16 | * @since 2010-07-28 17 | */ 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @Target(ElementType.TYPE) 20 | @Documented 21 | @DesignPattern(type = Type.BEHAVIORAL, 22 | related = {CompositePattern.class}) 23 | public @interface ChainOfResponsibilityPattern { 24 | Class[] participants() default {}; 25 | 26 | String comment() default ""; 27 | 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Target(ElementType.TYPE) 30 | @Documented 31 | public @interface Handler { 32 | Class[] participants() default {}; 33 | 34 | String comment() default ""; 35 | } 36 | 37 | @Retention(RetentionPolicy.RUNTIME) 38 | @Target(ElementType.TYPE) 39 | @Documented 40 | public @interface ConcreteHandler { 41 | Class[] participants() default {}; 42 | 43 | String comment() default ""; 44 | 45 | boolean defaultHandler() default false; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/CommandPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 233]: Encapsulate a request as an object, thereby 9 | * letting you parameterize clients with different requests, queue or log 10 | * requests, and support undoable operations. 11 | *

12 | * 13 | * 14 | * @author Michael Hunger 15 | * @since 2010-08-08 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.TYPE) 19 | @Documented 20 | @DesignPattern(source = Source.GoF, 21 | type = Type.BEHAVIORAL, 22 | urls = {"http://en.wikipedia.org/wiki/Command_pattern", 23 | "http://home.earthlink.net/~huston2/dp/command.html"}, 24 | refactorings = { 25 | Refactoring.ExtractParameterObject, 26 | Refactoring.ExtractMethodObject}, 27 | related = {CompositePattern.class, MementoPattern.class, 28 | PrototypePattern.class}) 29 | 30 | public @interface CommandPattern { 31 | Class[] participants() default {}; 32 | 33 | String comment() default ""; 34 | 35 | @Retention(RetentionPolicy.RUNTIME) 36 | @Target(ElementType.TYPE) 37 | @Documented 38 | public @interface Command { 39 | Class[] participants() default {}; 40 | 41 | String comment() default ""; 42 | 43 | boolean undoable() default false; 44 | } 45 | 46 | @Retention(RetentionPolicy.RUNTIME) 47 | @Target(ElementType.TYPE) 48 | @Documented 49 | public @interface ConcreteCommand { 50 | Class[] participants() default {}; 51 | 52 | String comment() default ""; 53 | } 54 | 55 | @Retention(RetentionPolicy.RUNTIME) 56 | @Target(ElementType.TYPE) 57 | @Documented 58 | public @interface Invoker { 59 | Class[] participants() default {}; 60 | 61 | String comment() default ""; 62 | } 63 | 64 | @Retention(RetentionPolicy.RUNTIME) 65 | @Target(ElementType.TYPE) 66 | @Documented 67 | public @interface Receiver { 68 | Class[] participants() default {}; 69 | 70 | String comment() default ""; 71 | } 72 | 73 | @Retention(RetentionPolicy.RUNTIME) 74 | @Target(ElementType.TYPE) 75 | @Documented 76 | public @interface Client { 77 | Class[] participants() default {}; 78 | 79 | String comment() default ""; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/CompositePattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 163]: Compose objects into tree structures to 9 | * represent whole-part hierarchies. Composite lets clients treat individual 10 | * objects and compositions of objects uniformly. 11 | *

12 | * 13 | * 14 | * @author Heinz Kabutz 15 | * @since 2010-07-28 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.TYPE) 19 | @Documented 20 | @DesignPattern(type = Type.STRUCTURAL, 21 | related = {ChainOfResponsibilityPattern.class, DecoratorPattern.class, 22 | FlyweightPattern.class, IteratorPattern.class, VisitorPattern.class}) 23 | public @interface CompositePattern { 24 | Class[] participants() default {}; 25 | 26 | String comment() default ""; 27 | 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Target(ElementType.TYPE) 30 | @Documented 31 | public @interface Component { 32 | Class[] participants() default {}; 33 | 34 | String comment() default ""; 35 | } 36 | 37 | @Retention(RetentionPolicy.RUNTIME) 38 | @Target(ElementType.TYPE) 39 | @Documented 40 | public @interface Leaf { 41 | Class[] participants() default {}; 42 | 43 | String comment() default ""; 44 | } 45 | 46 | @Retention(RetentionPolicy.RUNTIME) 47 | @Target(ElementType.TYPE) 48 | @Documented 49 | public @interface Composite { 50 | Class[] participants() default {}; 51 | 52 | String comment() default ""; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/DecoratorPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 175]: Attach additional responsibilities to an object 9 | * dynamically. Decorators provide a flexible alternative to subclassing for 10 | * extending functionality. 11 | *

12 | * 13 | * 14 | * @author Heinz Kabutz 15 | * @since 2010-08-09 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.TYPE) 19 | @Documented 20 | @DesignPattern(type = Type.STRUCTURAL, 21 | related = {AdapterPattern.class, CompositePattern.class, 22 | StrategyPattern.class}) 23 | public @interface DecoratorPattern { 24 | Class[] participants() default {}; 25 | 26 | String comment() default ""; 27 | 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Target(ElementType.TYPE) 30 | @Documented 31 | public @interface Component { 32 | Class[] participants() default {}; 33 | 34 | String comment() default ""; 35 | } 36 | 37 | @Retention(RetentionPolicy.RUNTIME) 38 | @Target(ElementType.TYPE) 39 | @Documented 40 | public @interface Decorator { 41 | Class[] participants() default {}; 42 | 43 | String comment() default ""; 44 | } 45 | 46 | @Retention(RetentionPolicy.RUNTIME) 47 | @Target(ElementType.TYPE) 48 | @Documented 49 | public @interface ConcreteComponent { 50 | Class[] participants() default {}; 51 | 52 | String comment() default ""; 53 | } 54 | 55 | @Retention(RetentionPolicy.RUNTIME) 56 | @Target(ElementType.TYPE) 57 | @Documented 58 | public @interface ConcreteDecorator { 59 | Class[] participants() default {}; 60 | 61 | String comment() default ""; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/FacadePattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 185]: Provide a unified interface to a set of 9 | * interfaces in a subsystem. Facade defines a higher-level interface that makes 10 | * the subsystem easier to use. 11 | *

12 | * 13 | * 14 | * @author Heinz Kabutz 15 | * @since 2010-07-28 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.TYPE) 19 | @Documented 20 | @DesignPattern(type = Type.STRUCTURAL, 21 | related = {AbstractFactoryPattern.class, MediatorPattern.class, 22 | SingletonPattern.class}) 23 | public @interface FacadePattern { 24 | Class[] participants() default {}; 25 | 26 | String comment() default ""; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/FactoryMethodPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 107]: Define an interface for creating an object, but 9 | * let subclasses decide which class to instantiate. Factory Method lets a class 10 | * defer instantiation to subclasses. 11 | *

12 | * This pattern refers to the GoF factory method, which differs greatly from the 13 | * static factory method commonly found in the refactoring literature. 14 | *

15 | * 16 | * 17 | * @author Heinz Kabutz 18 | * @since 2010-08-09 19 | */ 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Target(ElementType.TYPE) 22 | @Documented 23 | @DesignPattern(type = Type.CREATIONAL, 24 | related = {AbstractFactoryPattern.class, TemplateMethodPattern.class, 25 | PrototypePattern.class}) 26 | public @interface FactoryMethodPattern { 27 | Class[] participants() default {}; 28 | 29 | String comment() default ""; 30 | 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target(ElementType.TYPE) 33 | @Documented 34 | public @interface Creator { 35 | Class[] participants() default {}; 36 | 37 | String comment() default ""; 38 | } 39 | 40 | @Retention(RetentionPolicy.RUNTIME) 41 | @Target(ElementType.TYPE) 42 | @Documented 43 | public @interface Product { 44 | Class[] participants() default {}; 45 | 46 | String comment() default ""; 47 | } 48 | 49 | @Retention(RetentionPolicy.RUNTIME) 50 | @Target(ElementType.TYPE) 51 | @Documented 52 | public @interface ConcreteCreator { 53 | Class[] participants() default {}; 54 | 55 | String comment() default ""; 56 | } 57 | 58 | @Retention(RetentionPolicy.RUNTIME) 59 | @Target(ElementType.TYPE) 60 | @Documented 61 | public @interface ConcreteProduct { 62 | Class[] participants() default {}; 63 | 64 | String comment() default ""; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/FlyweightPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 195]: Use sharing to support large numbers of 9 | * fine-grained objects efficiently. 10 | *

11 | * 12 | * 13 | * @author Heinz Kabutz 14 | * @since 2010-07-28 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target(ElementType.TYPE) 18 | @Documented 19 | @DesignPattern(type = Type.STRUCTURAL, 20 | related = {CompositePattern.class, StatePattern.class, 21 | StrategyPattern.class}) 22 | public @interface FlyweightPattern { 23 | Class[] participants() default {}; 24 | 25 | String comment() default ""; 26 | 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target(ElementType.TYPE) 29 | @Documented 30 | public @interface FlyweightFactory { 31 | Class[] participants() default {}; 32 | 33 | String comment() default ""; 34 | } 35 | 36 | @Retention(RetentionPolicy.RUNTIME) 37 | @Target(ElementType.TYPE) 38 | @Documented 39 | public @interface Flyweight { 40 | Class[] participants() default {}; 41 | 42 | String comment() default ""; 43 | } 44 | 45 | @Retention(RetentionPolicy.RUNTIME) 46 | @Target(ElementType.TYPE) 47 | @Documented 48 | public @interface UnsharedConcreteFlyweight { 49 | Class[] participants() default {}; 50 | 51 | String comment() default ""; 52 | } 53 | 54 | @Retention(RetentionPolicy.RUNTIME) 55 | @Target(ElementType.TYPE) 56 | @Documented 57 | public @interface ConcreteFlyweight { 58 | Class[] participants() default {}; 59 | 60 | String comment() default ""; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/InterpreterPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 243]: Given a language, define a represention for its 9 | * grammar along with an interpreter that uses the representation to interpret 10 | * sentences in the language. 11 | * 12 | * @author Heinz Kabutz 13 | * @since 2010-08-09 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.TYPE) 17 | @Documented 18 | @DesignPattern(type = Type.BEHAVIORAL, 19 | related = {CompositePattern.class, FlyweightPattern.class, 20 | IteratorPattern.class, VisitorPattern.class}) 21 | public @interface InterpreterPattern { 22 | Class[] participants() default {}; 23 | 24 | String comment() default ""; 25 | 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Target(ElementType.TYPE) 28 | @Documented 29 | public @interface Context { 30 | Class[] participants() default {}; 31 | 32 | String comment() default ""; 33 | } 34 | 35 | @Retention(RetentionPolicy.RUNTIME) 36 | @Target(ElementType.TYPE) 37 | @Documented 38 | public @interface AbstractExpression { 39 | Class[] participants() default {}; 40 | 41 | String comment() default ""; 42 | } 43 | 44 | @Retention(RetentionPolicy.RUNTIME) 45 | @Target(ElementType.TYPE) 46 | @Documented 47 | public @interface TerminalExpression { 48 | Class[] participants() default {}; 49 | 50 | String comment() default ""; 51 | } 52 | 53 | @Retention(RetentionPolicy.RUNTIME) 54 | @Target(ElementType.TYPE) 55 | @Documented 56 | public @interface NonterminalExpression { 57 | Class[] participants() default {}; 58 | 59 | String comment() default ""; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/IteratorPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 257]: Provide a way to access the elements of an 9 | * aggregate object sequentially without exposing its underlying representation. 10 | *

11 | * 12 | * 13 | * @author Heinz Kabutz 14 | * @since 2010-08-09 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target(ElementType.TYPE) 18 | @Documented 19 | @DesignPattern(type = Type.BEHAVIORAL, 20 | related = {CompositePattern.class, FactoryMethodPattern.class, 21 | MementoPattern.class}) 22 | public @interface IteratorPattern { 23 | Class[] participants() default {}; 24 | 25 | String comment() default ""; 26 | 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target(ElementType.TYPE) 29 | @Documented 30 | public @interface Aggregate { 31 | Class[] participants() default {}; 32 | 33 | String comment() default ""; 34 | } 35 | 36 | @Retention(RetentionPolicy.RUNTIME) 37 | @Target(ElementType.TYPE) 38 | @Documented 39 | public @interface Iterator { 40 | Class[] participants() default {}; 41 | 42 | String comment() default ""; 43 | } 44 | 45 | @Retention(RetentionPolicy.RUNTIME) 46 | @Target(ElementType.TYPE) 47 | @Documented 48 | public @interface ConcreteAggregate { 49 | Class[] participants() default {}; 50 | 51 | String comment() default ""; 52 | } 53 | 54 | @Retention(RetentionPolicy.RUNTIME) 55 | @Target(ElementType.TYPE) 56 | @Documented 57 | public @interface ConcreteIterator { 58 | Class[] participants() default {}; 59 | 60 | String comment() default ""; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/MediatorPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 273]: Define an object that encapsulates how a set of 9 | * objects interact. Mediator promotes loose coupling by keeping objects from 10 | * referring to each other explicitly, and it lets you vary their interaction 11 | * independently. 12 | *

13 | * 14 | * 15 | * @author Heinz Kabutz 16 | * @since 2010-08-09 17 | */ 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @Target(ElementType.TYPE) 20 | @Documented 21 | @DesignPattern(type = Type.BEHAVIORAL, 22 | related = {FacadePattern.class, ObserverPattern.class}) 23 | public @interface MediatorPattern { 24 | Class[] participants() default {}; 25 | 26 | String comment() default ""; 27 | 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Target(ElementType.TYPE) 30 | @Documented 31 | public @interface Mediator { 32 | Class[] participants() default {}; 33 | 34 | String comment() default ""; 35 | } 36 | 37 | @Retention(RetentionPolicy.RUNTIME) 38 | @Target(ElementType.TYPE) 39 | @Documented 40 | public @interface Colleague { 41 | Class[] participants() default {}; 42 | 43 | String comment() default ""; 44 | } 45 | 46 | @Retention(RetentionPolicy.RUNTIME) 47 | @Target(ElementType.TYPE) 48 | @Documented 49 | public @interface ConcreteMediator { 50 | Class[] participants() default {}; 51 | 52 | String comment() default ""; 53 | } 54 | 55 | @Retention(RetentionPolicy.RUNTIME) 56 | @Target(ElementType.TYPE) 57 | @Documented 58 | public @interface ConcreteColleague { 59 | Class[] participants() default {}; 60 | 61 | String comment() default ""; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/MementoPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 283]: Without violating encapsulation, capture and 9 | * externalize an object's internal state so that the object can be restored to 10 | * this state later. 11 | *

12 | * 13 | * 14 | * @author Heinz Kabutz 15 | * @since 2010-08-09 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.TYPE) 19 | @Documented 20 | @DesignPattern(type = Type.BEHAVIORAL, 21 | related = {FacadePattern.class, ObserverPattern.class}) 22 | public @interface MementoPattern { 23 | Class[] participants() default {}; 24 | 25 | String comment() default ""; 26 | 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target(ElementType.TYPE) 29 | @Documented 30 | public @interface Originator { 31 | Class[] participants() default {}; 32 | 33 | String comment() default ""; 34 | } 35 | 36 | @Retention(RetentionPolicy.RUNTIME) 37 | @Target(ElementType.TYPE) 38 | @Documented 39 | public @interface Memento { 40 | Class[] participants() default {}; 41 | 42 | String comment() default ""; 43 | } 44 | 45 | @Retention(RetentionPolicy.RUNTIME) 46 | @Target(ElementType.TYPE) 47 | @Documented 48 | public @interface MementoImpl { 49 | Class[] participants() default {}; 50 | 51 | String comment() default ""; 52 | } 53 | 54 | @Retention(RetentionPolicy.RUNTIME) 55 | @Target(ElementType.TYPE) 56 | @Documented 57 | public @interface Caretaker { 58 | Class[] participants() default {}; 59 | 60 | String comment() default ""; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/ObserverPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 293]: Define a one-to-many dependency between objects 9 | * so that when one object changes state, all its dependents are notified and 10 | * updated automatically. 11 | *

12 | * 13 | * 14 | * @author Heinz Kabutz 15 | * @since 2010-08-09 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.TYPE) 19 | @Documented 20 | @DesignPattern(type = Type.BEHAVIORAL, 21 | related = {MediatorPattern.class, SingletonPattern.class}) 22 | public @interface ObserverPattern { 23 | Class[] participants() default {}; 24 | 25 | String comment() default ""; 26 | 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target(ElementType.TYPE) 29 | @Documented 30 | public @interface Observer { 31 | Class[] participants() default {}; 32 | 33 | String comment() default ""; 34 | } 35 | 36 | @Retention(RetentionPolicy.RUNTIME) 37 | @Target(ElementType.TYPE) 38 | @Documented 39 | public @interface Subject { 40 | Class[] participants() default {}; 41 | 42 | String comment() default ""; 43 | } 44 | 45 | @Retention(RetentionPolicy.RUNTIME) 46 | @Target(ElementType.TYPE) 47 | @Documented 48 | public @interface ConcreteObserver { 49 | Class[] participants() default {}; 50 | 51 | String comment() default ""; 52 | } 53 | 54 | @Retention(RetentionPolicy.RUNTIME) 55 | @Target(ElementType.TYPE) 56 | @Documented 57 | public @interface ConcreteSubject { 58 | Class[] participants() default {}; 59 | 60 | String comment() default ""; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/PrototypePattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 117]: Specify the kinds of objects to create using a 9 | * prototypical instance, and create new objects by copying this prototype. 10 | * 11 | * @author Heinz Kabutz 12 | * @since 2010-08-09 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.TYPE) 16 | @Documented 17 | @DesignPattern(type = Type.CREATIONAL, 18 | related = {AbstractFactoryPattern.class, CompositePattern.class, 19 | DecoratorPattern.class}) 20 | public @interface PrototypePattern { 21 | Class[] participants() default {}; 22 | 23 | String comment() default ""; 24 | 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Target(ElementType.TYPE) 27 | @Documented 28 | public @interface Prototype { 29 | Class[] participants() default {}; 30 | 31 | String comment() default ""; 32 | } 33 | 34 | @Retention(RetentionPolicy.RUNTIME) 35 | @Target(ElementType.TYPE) 36 | @Documented 37 | public @interface ConcretePrototype { 38 | Class[] participants() default {}; 39 | 40 | String comment() default ""; 41 | } 42 | 43 | @Retention(RetentionPolicy.RUNTIME) 44 | @Target(ElementType.METHOD) 45 | @Documented 46 | public @interface Operation { 47 | Class[] participants() default {}; 48 | 49 | String comment() default ""; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/ProxyPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 207]: Provide a surrogate or placeholder for another 9 | * object to control access to it. 10 | *

11 | * 12 | * 13 | * @author Heinz Kabutz 14 | * @since 2010-07-28 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target({ElementType.TYPE, ElementType.FIELD, 18 | ElementType.LOCAL_VARIABLE}) 19 | @Documented 20 | @DesignPattern(type = Type.STRUCTURAL, 21 | related = {AdapterPattern.class, DecoratorPattern.class}) 22 | public @interface ProxyPattern { 23 | Class[] participants() default {}; 24 | 25 | String comment() default ""; 26 | 27 | Variation variation() default Variation.STATIC_MANUAL; 28 | 29 | @Retention(RetentionPolicy.RUNTIME) 30 | @Target(ElementType.TYPE) 31 | @Documented 32 | public @interface Subject { 33 | Class[] participants() default {}; 34 | 35 | String comment() default ""; 36 | } 37 | 38 | @Retention(RetentionPolicy.RUNTIME) 39 | @Target(ElementType.TYPE) 40 | @Documented 41 | public @interface RealSubject { 42 | Class[] participants() default {}; 43 | 44 | String comment() default ""; 45 | } 46 | 47 | @Retention(RetentionPolicy.RUNTIME) 48 | @Target(ElementType.TYPE) 49 | @Documented 50 | public @interface Proxy { 51 | Class[] participants() default {}; 52 | 53 | String comment() default ""; 54 | 55 | Variation variation() default Variation.STATIC_MANUAL; 56 | 57 | Type type() default Type.UNDEFINED; 58 | } 59 | 60 | @Retention(RetentionPolicy.RUNTIME) 61 | @Target({ElementType.TYPE, ElementType.FIELD, 62 | ElementType.LOCAL_VARIABLE}) 63 | @Documented 64 | public @interface Client { 65 | Class[] participants() default {}; 66 | 67 | String comment() default ""; 68 | } 69 | 70 | public static enum Variation { 71 | STATIC_MANUAL, STATIC_GENERATED, DYNAMIC 72 | } 73 | 74 | public static enum Type { 75 | UNDEFINED, VIRTUAL, REMOTE, PROTECTION 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/SingletonPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 127]: Ensure a class only has one instance, and 9 | * provide a global point of access to it. 10 | *

11 | * 12 | * 13 | * @author Alex Gout 14 | * @since 2010-08-08 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target(ElementType.TYPE) 18 | @Documented 19 | @DesignPattern(type = Type.CREATIONAL, 20 | related = {AbstractFactoryPattern.class, BuilderPattern.class, 21 | PrototypePattern.class}) 22 | public @interface SingletonPattern { 23 | Class[] participants() default {}; 24 | 25 | String comment() default ""; 26 | 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target(ElementType.TYPE) 29 | @Documented 30 | public @interface Singleton { 31 | Class[] participants() default {}; 32 | 33 | String comment() default ""; 34 | 35 | Variation variation() default Variation.LAZY; 36 | } 37 | 38 | @Retention(RetentionPolicy.RUNTIME) 39 | @Target(ElementType.METHOD) 40 | @Documented 41 | public @interface SingletonMethod { 42 | Class[] participants() default {}; 43 | 44 | String comment() default ""; 45 | } 46 | 47 | public enum Variation { 48 | LAZY, EAGER 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/StatePattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 305]: Allow an object to alter its behavior when its 9 | * internal state changes. The object will appear to change its class. 10 | *

11 | * 12 | * 13 | * @author Heinz Kabutz 14 | * @since 2010-08-09 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target(ElementType.TYPE) 18 | @Documented 19 | @DesignPattern(type = Type.BEHAVIORAL, 20 | related = {FlyweightPattern.class, SingletonPattern.class}) 21 | public @interface StatePattern { 22 | Class[] participants() default {}; 23 | 24 | String comment() default ""; 25 | 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Target(ElementType.TYPE) 28 | @Documented 29 | public @interface Context { 30 | Class[] participants() default {}; 31 | 32 | String comment() default ""; 33 | } 34 | 35 | @Retention(RetentionPolicy.RUNTIME) 36 | @Target(ElementType.TYPE) 37 | @Documented 38 | public @interface State { 39 | Class[] participants() default {}; 40 | 41 | String comment() default ""; 42 | } 43 | 44 | @Retention(RetentionPolicy.RUNTIME) 45 | @Target(ElementType.TYPE) 46 | @Documented 47 | public @interface ConcreteState { 48 | Class[] participants() default {}; 49 | 50 | String comment() default ""; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/StrategyPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 315]: Define a family of algorithms, encapsulate each 9 | * one, and make them interchangeable. Strategy lets the algorithm vary 10 | * independently from clients that use it. 11 | *

12 | * 13 | * 14 | * @author Heinz Kabutz 15 | * @since 2010-07-28 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.TYPE) 19 | @Documented 20 | @DesignPattern(type = Type.BEHAVIORAL, 21 | related = {FlyweightPattern.class}) 22 | public @interface StrategyPattern { 23 | Class[] participants() default {}; 24 | 25 | String comment() default ""; 26 | 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target(ElementType.TYPE) 29 | @Documented 30 | public @interface Context { 31 | Class[] participants() default {}; 32 | 33 | String comment() default ""; 34 | } 35 | 36 | @Retention(RetentionPolicy.RUNTIME) 37 | @Target(ElementType.TYPE) 38 | @Documented 39 | public @interface Strategy { 40 | Class[] participants() default {}; 41 | 42 | String comment() default ""; 43 | } 44 | 45 | @Retention(RetentionPolicy.RUNTIME) 46 | @Target(ElementType.FIELD) 47 | @Documented 48 | public @interface StrategyField { 49 | Class[] participants() default {}; 50 | 51 | String comment() default ""; 52 | } 53 | 54 | @Retention(RetentionPolicy.RUNTIME) 55 | @Target(ElementType.TYPE) 56 | @Documented 57 | public @interface ConcreteStrategy { 58 | Class[] participants() default {}; 59 | 60 | String comment() default ""; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/TemplateMethodPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 325]: Define the skeleton of an algorithm in an 9 | * operation, deferring some steps to subclasses. Template Method lets 10 | * subclasses redefine certain steps of an algorithm without changing the 11 | * algorithm's structure. 12 | *

13 | * 14 | * 15 | * @author Heinz Kabutz 16 | * @since 2010-07-28 17 | */ 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @Target({ElementType.TYPE, ElementType.METHOD}) 20 | @Documented 21 | @DesignPattern(type = Type.BEHAVIORAL, 22 | related = {FactoryMethodPattern.class, StrategyPattern.class}) 23 | public @interface TemplateMethodPattern { 24 | Class[] participants() default {}; 25 | 26 | String comment() default ""; 27 | 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Target(ElementType.TYPE) 30 | @Documented 31 | public @interface AbstractClass { 32 | Class[] participants() default {}; 33 | 34 | String comment() default ""; 35 | } 36 | 37 | @Retention(RetentionPolicy.RUNTIME) 38 | @Target(ElementType.TYPE) 39 | @Documented 40 | public @interface ConcreteClass { 41 | Class[] participants() default {}; 42 | 43 | String comment() default ""; 44 | } 45 | 46 | @Retention(RetentionPolicy.RUNTIME) 47 | @Target(ElementType.METHOD) 48 | @Documented 49 | public @interface TemplateMethod { 50 | Class[] participants() default {}; 51 | 52 | String comment() default ""; 53 | } 54 | 55 | 56 | /** 57 | * @deprecated Misnamed, please use @PrimitiveOperation instead. 58 | */ 59 | @Deprecated 60 | @Retention(RetentionPolicy.RUNTIME) 61 | @Target(ElementType.METHOD) 62 | @Documented 63 | public @interface PrimitiveMethod { 64 | Class[] participants() default {}; 65 | 66 | String comment() default ""; 67 | } 68 | 69 | @Retention(RetentionPolicy.RUNTIME) 70 | @Target(ElementType.METHOD) 71 | @Documented 72 | public @interface PrimitiveOperation { 73 | Class[] participants() default {}; 74 | 75 | String comment() default ""; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/gof/VisitorPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent [GoF, pg 331]: Represent an operation to be performed on the 9 | * elements of an object structure. Visitor lets you define a new operation 10 | * without changing the classes of the elements on which it operates. 11 | *

12 | * 13 | * 14 | * @author Heinz Kabutz 15 | * @since 2010-08-09 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.TYPE) 19 | @Documented 20 | @DesignPattern(type = Type.BEHAVIORAL, 21 | related = {CompositePattern.class, InterpreterPattern.class}) 22 | public @interface VisitorPattern { 23 | Class[] participants() default {}; 24 | 25 | String comment() default ""; 26 | 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target(ElementType.TYPE) 29 | @Documented 30 | public @interface Visitor { 31 | Class[] participants() default {}; 32 | 33 | String comment() default ""; 34 | } 35 | 36 | @Retention(RetentionPolicy.RUNTIME) 37 | @Target(ElementType.TYPE) 38 | @Documented 39 | public @interface ConcreteVisitor { 40 | Class[] participants() default {}; 41 | 42 | String comment() default ""; 43 | } 44 | 45 | @Retention(RetentionPolicy.RUNTIME) 46 | @Target(ElementType.TYPE) 47 | @Documented 48 | public @interface Element { 49 | Class[] participants() default {}; 50 | 51 | String comment() default ""; 52 | } 53 | 54 | @Retention(RetentionPolicy.RUNTIME) 55 | @Target(ElementType.TYPE) 56 | @Documented 57 | public @interface ConcreteElement { 58 | Class[] participants() default {}; 59 | 60 | String comment() default ""; 61 | } 62 | 63 | @Retention(RetentionPolicy.RUNTIME) 64 | @Target(ElementType.TYPE) 65 | @Documented 66 | public @interface ObjectStructure { 67 | Class[] participants() default {}; 68 | 69 | String comment() default ""; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/jee/BusinessDelegatePattern.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.jpatterns.jee; 5 | 6 | import org.jpatterns.core.*; 7 | import org.jpatterns.gof.AdapterPattern.Adapter; 8 | import org.jpatterns.gof.FacadePattern; 9 | 10 | import java.lang.annotation.*; 11 | 12 | /** 13 | * Intent [Core J2EE Patterns, pg 249]: use a BusinessDelegate to reduce 14 | * coupling between presentation-tier clients and business services. The 15 | * BusinessDelegate hides the underlying implementation details of the business 16 | * service [...]. 17 | *

18 | * 19 | *

20 | * 21 | * @author Marco Tedone 22 | * @since 2010-08-21 23 | */ 24 | @Retention(RetentionPolicy.RUNTIME) 25 | @Target({ElementType.TYPE}) 26 | @Documented 27 | @DesignPattern(source = Source.CoreJ2EE, type = Type.ENTERPRISE, 28 | related = {Adapter.class, FacadePattern.class}) 29 | public @interface BusinessDelegatePattern { 30 | Class[] participants() default {}; 31 | 32 | String comment() default ""; 33 | 34 | @Retention(RetentionPolicy.RUNTIME) 35 | @Target({ElementType.TYPE, ElementType.FIELD, ElementType.LOCAL_VARIABLE, 36 | ElementType.PARAMETER}) 37 | @Documented 38 | public @interface BusinessDelegate { 39 | Class[] participants() default {}; 40 | 41 | String comment() default ""; 42 | } 43 | 44 | @Retention(RetentionPolicy.RUNTIME) 45 | @Target({ElementType.TYPE, ElementType.FIELD, ElementType.LOCAL_VARIABLE, 46 | ElementType.PARAMETER}) 47 | @Documented 48 | public @interface BusinessService { 49 | Class[] participants() default {}; 50 | 51 | String comment() default ""; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/jee/DataAccessObjectPattern.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package org.jpatterns.jee; 5 | 6 | import org.jpatterns.core.*; 7 | 8 | import java.lang.annotation.*; 9 | 10 | /** 11 | * Intent [Core J2EE Patterns, pg 391]: Abstract and encapsulate all 12 | * access to the data source. The DAO manages the connection with the data 13 | * source to obtain and store data 14 | *

15 | * 16 | *

17 | * 18 | * @author Marco Tedone 19 | * @since 2010-08-19 20 | */ 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @Target(ElementType.TYPE) 23 | @Documented 24 | @DesignPattern(source = Source.CoreJ2EE, 25 | type = Type.ENTERPRISE) 26 | public @interface DataAccessObjectPattern { 27 | Class[] participants() default {}; 28 | 29 | String comment() default ""; 30 | 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ElementType.TYPE, ElementType.FIELD, 33 | ElementType.LOCAL_VARIABLE, ElementType.PARAMETER}) 34 | @Documented 35 | public @interface BusinessObject { 36 | Class[] participants() default {}; 37 | 38 | String comment() default ""; 39 | } 40 | 41 | @Retention(RetentionPolicy.RUNTIME) 42 | @Target({ElementType.TYPE, ElementType.FIELD, 43 | ElementType.LOCAL_VARIABLE, ElementType.PARAMETER}) 44 | @Documented 45 | public @interface Dao { 46 | Class[] participants() default {}; 47 | 48 | String comment() default ""; 49 | } 50 | 51 | @Retention(RetentionPolicy.RUNTIME) 52 | @Target({ElementType.TYPE, ElementType.FIELD, 53 | ElementType.LOCAL_VARIABLE, ElementType.PARAMETER}) 54 | @Documented 55 | public @interface DataSource { 56 | Class[] participants() default {}; 57 | 58 | String comment() default ""; 59 | 60 | // Giving users the possibility to specify which datasource they are using 61 | // might be useful for maintainance. The information is optional anyway 62 | 63 | DataSourceType dataSourceType() default DataSourceType.UNDEFINED; 64 | } 65 | 66 | @Retention(RetentionPolicy.RUNTIME) 67 | @Target({ElementType.TYPE, ElementType.FIELD, 68 | ElementType.LOCAL_VARIABLE, ElementType.PARAMETER}) 69 | @Documented 70 | public @interface ValueObject { 71 | Class[] participants() default {}; 72 | 73 | String comment() default ""; 74 | } 75 | 76 | public enum DataSourceType { 77 | HIBERNATE, SPRING, ORACLE, DB2, MYSQL, SQLSERVER, SYBASE, BERKELEY, 78 | UNDEFINED 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/jee/ModelViewController.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.jee; 2 | 3 | import org.jpatterns.core.*; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * Intent: The Model View Controller (MVC) pattern divides an application in 9 | * three components: The View, the Controller and the Model. 10 | *

18 | *

19 | * 20 | *

21 | * 22 | * @author Marco Tedone 23 | * @since 2010-08-21 24 | */ 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Target({ElementType.TYPE}) 27 | @Documented 28 | @DesignPattern(source = Source.Other, 29 | type = Type.ENTERPRISE) 30 | public @interface ModelViewController { 31 | Class[] participants() default {}; 32 | 33 | String comment() default ""; 34 | 35 | @Retention(RetentionPolicy.RUNTIME) 36 | @Target(ElementType.TYPE) 37 | @Documented 38 | public @interface View { 39 | Class[] participants() default {}; 40 | 41 | String comment() default ""; 42 | } 43 | 44 | @Retention(RetentionPolicy.RUNTIME) 45 | @Target(ElementType.TYPE) 46 | @Documented 47 | public @interface Controller { 48 | Class[] participants() default {}; 49 | 50 | String comment() default ""; 51 | } 52 | 53 | @Retention(RetentionPolicy.RUNTIME) 54 | @Target(ElementType.TYPE) 55 | @Documented 56 | public @interface Model { 57 | Class[] participants() default {}; 58 | 59 | String comment() default ""; 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/jee/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This file contains {@link org.jpatterns.core.Type#ENTERPRISE} patterns as 3 | * described in the CORE J2EE Patterns 2nd Edition - Best Practices and Design 4 | * Strategies book. 5 | * 6 | *

7 | * Although some of the EE patterns described in this book are obsolete, 8 | * others are still actual and defined in this package. 9 | * 10 | * @author Marco Tedone 11 | * @since 2010-08-19 12 | */ 13 | package org.jpatterns.jee; -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * jpatterns.org was conceived during one of the Java Specialists Club design 3 | * patterns sessions as a way to clearly label classes as belonging to some 4 | * pattern structure using Java annotations. The project is led by Michael 5 | * Hunger and Heinz Kabutz. 6 | */ 7 | package org.jpatterns; -------------------------------------------------------------------------------- /src/main/java/org/jpatterns/plopd/NullObjectPattern.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.plopd; 2 | 3 | import org.jpatterns.core.*; 4 | import org.jpatterns.gof.*; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * Intent [PLoPD3, pg 5]: A Null Object provides a surrogate for another 10 | * object that shares the same interface but does nothing. Thus, the Null 11 | * Object encapsulates the implementation decisions of how to do nothing and 12 | * hides those details from its collaborators. 13 | * 14 | * @author Heinz Kabutz 15 | * @since 2010-09-01 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target({ElementType.TYPE, ElementType.FIELD, 19 | ElementType.LOCAL_VARIABLE}) 20 | @Documented 21 | @DesignPattern( 22 | source = Source.PLoPD3, 23 | type = Type.BEHAVIORAL, 24 | related = {FlyweightPattern.class, StrategyPattern.class, 25 | SingletonPattern.class}) 26 | public @interface NullObjectPattern { 27 | public abstract Class[] participants() default {}; 28 | 29 | public abstract String comment() default ""; 30 | 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target(ElementType.TYPE) 33 | @Documented 34 | public @interface AbstractObject { 35 | public abstract Class[] participants() default {}; 36 | 37 | public abstract String comment() default ""; 38 | } 39 | 40 | @Retention(RetentionPolicy.RUNTIME) 41 | @Target(ElementType.TYPE) 42 | @Documented 43 | public @interface RealObject { 44 | public abstract Class[] participants() default {}; 45 | 46 | public abstract String comment() default ""; 47 | } 48 | 49 | @Retention(RetentionPolicy.RUNTIME) 50 | @Target(ElementType.TYPE) 51 | @Documented 52 | public @interface NullObject { 53 | public abstract Class[] participants() default {}; 54 | 55 | public abstract String comment() default ""; 56 | } 57 | 58 | @Retention(RetentionPolicy.RUNTIME) 59 | @Target({ElementType.TYPE, ElementType.FIELD, 60 | ElementType.LOCAL_VARIABLE}) 61 | @Documented 62 | public @interface Client { 63 | public abstract Class[] participants() default {}; 64 | 65 | public abstract String comment() default ""; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/AbstractFactoryTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.junit.Test; 4 | 5 | import static junit.framework.Assert.assertEquals; 6 | 7 | /** 8 | * @author Alex Gout 9 | * @since 2010-09-06 10 | */ 11 | public class AbstractFactoryTest { 12 | private String configuredLocale; 13 | 14 | @AbstractFactoryPattern.AbstractProduct(participants = AbstractLocalizedAnimalFactory.class) 15 | private static interface LocalizedAnimal { 16 | String talk(); 17 | } 18 | 19 | @AbstractFactoryPattern.ConcreteProduct 20 | private static class DutchCat implements LocalizedAnimal { 21 | public String talk() { 22 | return "Miauw"; 23 | } 24 | } 25 | 26 | @AbstractFactoryPattern.ConcreteProduct 27 | private static class EnglishCat implements LocalizedAnimal { 28 | public String talk() { 29 | return "Meow"; 30 | } 31 | } 32 | 33 | @AbstractFactoryPattern.ConcreteProduct 34 | private static class DutchChicken implements LocalizedAnimal { 35 | public String talk() { 36 | return "Tok tok"; 37 | } 38 | } 39 | 40 | @AbstractFactoryPattern.ConcreteProduct 41 | private static class EnglishChicken implements LocalizedAnimal { 42 | public String talk() { 43 | return "Cluck cluck"; 44 | } 45 | } 46 | 47 | @AbstractFactoryPattern.AbstractFactory(participants = LocalizedAnimal.class) 48 | private static interface AbstractLocalizedAnimalFactory { 49 | LocalizedAnimal createCat(); 50 | 51 | LocalizedAnimal createChicken(); 52 | } 53 | 54 | @AbstractFactoryPattern.ConcreteFactory 55 | private static class DutchAnimalFactory implements AbstractLocalizedAnimalFactory { 56 | @AbstractFactoryPattern.FactoryMethod 57 | public LocalizedAnimal createCat() { 58 | return new DutchCat(); 59 | } 60 | 61 | @AbstractFactoryPattern.FactoryMethod 62 | public LocalizedAnimal createChicken() { 63 | return new DutchChicken(); 64 | } 65 | } 66 | 67 | @AbstractFactoryPattern.ConcreteFactory 68 | private static class EnglishAnimalFactory implements AbstractLocalizedAnimalFactory { 69 | public LocalizedAnimal createCat() { 70 | return new EnglishCat(); 71 | } 72 | 73 | public LocalizedAnimal createChicken() { 74 | return new EnglishChicken(); 75 | } 76 | } 77 | 78 | 79 | private AbstractLocalizedAnimalFactory getFactoryForConfiguredLocale() { 80 | if ("NL".equals(getConfigureLocale())) { 81 | return new DutchAnimalFactory(); 82 | } else { 83 | return new EnglishAnimalFactory(); 84 | } 85 | } 86 | 87 | private void configureLocale(String _locale) { 88 | this.configuredLocale = _locale; 89 | } 90 | 91 | private String getConfigureLocale() { 92 | return this.configuredLocale; 93 | } 94 | 95 | @Test 96 | public void testDutchAnimals() { 97 | configureLocale("NL"); 98 | 99 | AbstractLocalizedAnimalFactory dutchFactory = getFactoryForConfiguredLocale(); 100 | LocalizedAnimal dutchCat = dutchFactory.createCat(); 101 | LocalizedAnimal dutchChicken = dutchFactory.createChicken(); 102 | 103 | 104 | assertEquals("Miauw", dutchCat.talk()); 105 | assertEquals("Tok tok", dutchChicken.talk()); 106 | 107 | } 108 | 109 | @Test 110 | public void testEnglishAnimals() { 111 | configureLocale("EN"); 112 | 113 | AbstractLocalizedAnimalFactory englishFactory = getFactoryForConfiguredLocale(); 114 | LocalizedAnimal englishCat = englishFactory.createCat(); 115 | LocalizedAnimal englishChicken = englishFactory.createChicken(); 116 | 117 | assertEquals("Meow", englishCat.talk()); 118 | assertEquals("Cluck cluck", englishChicken.talk()); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/AdapterTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import org.junit.Test; 5 | 6 | /** 7 | * @author Heinz Kabutz 8 | * @since 2010-08-09 9 | */ 10 | public class AdapterTest { 11 | private static interface Singer { 12 | String sing(); 13 | } 14 | 15 | private static class Soprano implements Singer { 16 | public String sing() { 17 | return "Soprano is singing"; 18 | } 19 | } 20 | 21 | 22 | @AdapterPattern.Adaptee 23 | private static class Rapper { 24 | public String talk() { 25 | return "Vulgar lyrics deleted..."; 26 | } 27 | } 28 | 29 | @AdapterPattern.Adapter(AdapterPattern.Variation.OBJECT) 30 | private static class RapperObjectAdapter implements Singer { 31 | private final Rapper rapper; 32 | 33 | public RapperObjectAdapter(Rapper rapper) { 34 | this.rapper = rapper; 35 | } 36 | 37 | public RapperObjectAdapter() { 38 | this(new Rapper()); 39 | } 40 | 41 | public String sing() { 42 | return rapper.talk(); 43 | } 44 | } 45 | 46 | @AdapterPattern.Adapter(value = AdapterPattern.Variation.CLASS, 47 | participants = {Rapper.class, Singer.class}) 48 | private static class RapperClassAdapter extends Rapper 49 | implements Singer { 50 | public String sing() { 51 | return talk(); 52 | } 53 | } 54 | 55 | @Test 56 | public void testRapperClassRapsInsteadOfSinging() { 57 | Singer rapperClassAdapter = new RapperClassAdapter(); 58 | assertEquals("rapper talks", new Rapper().talk(), rapperClassAdapter.sing()); 59 | } 60 | 61 | @Test 62 | public void testRapperObjectAdapterRapsInsteadOfSinging() { 63 | Singer rapperObjectAdapter = new RapperObjectAdapter(new Rapper()); 64 | assertEquals("rapper talks", new Rapper().talk(), rapperObjectAdapter.sing()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/BridgeTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.junit.*; 4 | 5 | import java.util.*; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | /** 10 | * @author Alex Gout 11 | * @since 2010-09-10 12 | */ 13 | public class BridgeTest { 14 | ListImplementor list1; 15 | ListImplementor list2; 16 | 17 | @BridgePattern.Implementor(participants = ListLayout.class) 18 | private static interface ListImplementor { 19 | int getSize(); 20 | 21 | String getItem(int _index); 22 | 23 | void addItem(String _item); 24 | } 25 | 26 | @BridgePattern.ConcreteImplementor 27 | private static class SomeList implements ListImplementor { 28 | private List items = new ArrayList(); 29 | 30 | public int getSize() { 31 | return items.size(); 32 | } 33 | 34 | public String getItem(int _index) { 35 | return this.items.get(_index); 36 | } 37 | 38 | public void addItem(String _item) { 39 | this.items.add(_item); 40 | } 41 | } 42 | 43 | @BridgePattern.ConcreteImplementor 44 | private static class UppercaseList extends SomeList { 45 | 46 | public void addItem(String _item) { 47 | super.addItem(_item.toUpperCase()); 48 | } 49 | } 50 | 51 | @BridgePattern.Abstraction(participants = ListImplementor.class) 52 | private static class ListLayout { 53 | protected ListImplementor implementor; 54 | 55 | public void setImplementor(ListImplementor implementor) { 56 | this.implementor = implementor; 57 | } 58 | 59 | public void printList() { 60 | for (int i = 0; i < implementor.getSize(); i++) { 61 | System.out.println(getItem(i)); 62 | } 63 | } 64 | 65 | public String getItem(int _index) { 66 | return implementor.getItem(_index); 67 | } 68 | } 69 | 70 | @BridgePattern.RefinedAbstraction 71 | private static class NumberedListLayout extends ListLayout { 72 | 73 | @Override 74 | public String getItem(int _index) { 75 | return "item" + (_index + 1) + ":\t" + super.getItem(_index); 76 | } 77 | } 78 | 79 | @Before 80 | public void initializeLists() { 81 | 82 | list1 = new SomeList(); 83 | list1.addItem("someList:item1"); 84 | list1.addItem("someList:item2"); 85 | list1.addItem("someList:item3"); 86 | 87 | list2 = new UppercaseList(); 88 | list2.addItem("uppercaseList:item1"); 89 | list2.addItem("uppercaseList:item2"); 90 | list2.addItem("uppercaseList:item3"); 91 | } 92 | 93 | @Test 94 | public void SomeListBaseLayout() { 95 | ListLayout listLayout = new ListLayout(); 96 | listLayout.setImplementor(list1); 97 | String printedFirstItem = listLayout.getItem(0); 98 | 99 | assertEquals("someList:item1", printedFirstItem); 100 | } 101 | 102 | @Test 103 | public void SomeListNumberedLayout() { 104 | ListLayout listLayout = new NumberedListLayout(); 105 | listLayout.setImplementor(list1); 106 | String printedFirstItem = listLayout.getItem(0); 107 | 108 | assertEquals("item1:\tsomeList:item1", printedFirstItem); 109 | } 110 | 111 | @Test 112 | public void fullTest() { 113 | ListLayout listLayout = new ListLayout(); 114 | listLayout.setImplementor(list1); 115 | listLayout.printList(); 116 | 117 | listLayout.setImplementor(list2); 118 | listLayout.printList(); 119 | 120 | listLayout = new NumberedListLayout(); 121 | listLayout.setImplementor(list1); 122 | listLayout.printList(); 123 | 124 | listLayout.setImplementor(list2); 125 | listLayout.printList(); 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/BuilderTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * @author Alex Gout 9 | * @since 2010-09-09 10 | */ 11 | public class BuilderTest { 12 | @BuilderPattern.Product 13 | private static class Guitar { 14 | private String neck; 15 | private String elements; 16 | private String model; 17 | 18 | public void setNeck(String _neck) { 19 | this.neck = _neck; 20 | } 21 | 22 | public void setElements(String _elements) { 23 | this.elements = _elements; 24 | } 25 | 26 | public void setModel(String _model) { 27 | this.model = _model; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return this.model + ";" + this.neck + ";" + this.elements; 33 | } 34 | } 35 | 36 | @BuilderPattern.Builder(participants = {Guitar.class, GuitarMaker.class}) 37 | private static abstract class GuitarBuilder { 38 | protected Guitar guitar; 39 | 40 | public Guitar getGuitar() { 41 | return this.guitar; 42 | } 43 | 44 | public void createGuitar() { 45 | this.guitar = new Guitar(); 46 | } 47 | 48 | public abstract void buildNeck(); 49 | 50 | public abstract void buildModel(); 51 | 52 | public abstract void buildElements(); 53 | } 54 | 55 | @BuilderPattern.ConcreteBuilder 56 | private static class SteviesGuitarBuilder extends GuitarBuilder { 57 | 58 | @Override 59 | public void buildNeck() { 60 | guitar.setNeck("maple/Pau Ferro"); 61 | } 62 | 63 | @Override 64 | public void buildModel() { 65 | guitar.setModel("Stratocaster"); 66 | } 67 | 68 | @Override 69 | public void buildElements() { 70 | guitar.setElements("SSS"); 71 | } 72 | } 73 | 74 | @BuilderPattern.ConcreteBuilder 75 | private static class AngusGuitarBuilder extends GuitarBuilder { 76 | 77 | @Override 78 | public void buildNeck() { 79 | this.guitar.setNeck("mahogany/rosewood"); 80 | } 81 | 82 | @Override 83 | public void buildModel() { 84 | this.guitar.setModel("SG"); 85 | } 86 | 87 | @Override 88 | public void buildElements() { 89 | this.guitar.setElements("HH"); 90 | } 91 | } 92 | 93 | @BuilderPattern.Director 94 | private static class GuitarMaker { 95 | private GuitarBuilder guitarBuilder; 96 | 97 | public void setGuitarBuilder(GuitarBuilder _guitarBuilder) { 98 | this.guitarBuilder = _guitarBuilder; 99 | } 100 | 101 | public Guitar getGuitar() { 102 | return guitarBuilder.getGuitar(); 103 | } 104 | 105 | public void buildGuitar() { 106 | this.guitarBuilder.createGuitar(); 107 | this.guitarBuilder.buildModel(); 108 | this.guitarBuilder.buildNeck(); 109 | this.guitarBuilder.buildElements(); 110 | } 111 | } 112 | 113 | 114 | @Test 115 | public void testBuilderStevieGuitar() { 116 | GuitarMaker guitarMaker = new GuitarMaker(); 117 | guitarMaker.setGuitarBuilder(new SteviesGuitarBuilder()); 118 | 119 | guitarMaker.buildGuitar(); 120 | Guitar guitar = guitarMaker.getGuitar(); 121 | 122 | assertEquals("Stratocaster;maple/Pau Ferro;SSS", guitar.toString()); 123 | } 124 | 125 | @Test 126 | public void testBuilderAngusGuitar() { 127 | GuitarMaker guitarMaker = new GuitarMaker(); 128 | guitarMaker.setGuitarBuilder(new AngusGuitarBuilder()); 129 | 130 | guitarMaker.buildGuitar(); 131 | Guitar guitar = guitarMaker.getGuitar(); 132 | 133 | assertEquals("SG;mahogany/rosewood;HH", guitar.toString()); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/ChainOfResponsibilityTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.junit.*; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * @author Alex Gout 9 | * @since 2010-09-09 10 | */ 11 | 12 | public class ChainOfResponsibilityTest { 13 | private OrderHandler regularOrderHandler; 14 | private OrderHandler bigOrderHandler; 15 | private OrderHandler hugeOrderHandler; 16 | 17 | 18 | private static class Order { 19 | float orderAmount; 20 | String description; 21 | 22 | private Order(float orderAmount, String description) { 23 | this.orderAmount = orderAmount; 24 | this.description = description; 25 | } 26 | } 27 | 28 | @ChainOfResponsibilityPattern.Handler 29 | private static abstract class OrderHandler { 30 | protected OrderHandler successor; 31 | 32 | public String handleOrder(Order _order) { 33 | if (canHandle(_order)) { 34 | return processOrder(_order); 35 | } else { 36 | return this.successor.handleOrder(_order); 37 | } 38 | } 39 | 40 | protected abstract boolean canHandle(Order _order); 41 | 42 | protected abstract String processOrder(Order _order); 43 | 44 | public void setSuccessor(OrderHandler _handler) { 45 | this.successor = _handler; 46 | } 47 | } 48 | 49 | @ChainOfResponsibilityPattern.ConcreteHandler 50 | private static class RegularOrderHandler extends OrderHandler { 51 | private static final float MAX_AMOUNT = 100.00f; 52 | 53 | @Override 54 | protected boolean canHandle(Order _order) { 55 | return Float.compare(MAX_AMOUNT, _order.orderAmount) >= 0; 56 | } 57 | 58 | @Override 59 | protected String processOrder(Order _order) { 60 | return _order.description + " handled by RegularOrderHandler"; 61 | } 62 | } 63 | 64 | @ChainOfResponsibilityPattern.ConcreteHandler 65 | private static class BigOrderHandler extends OrderHandler { 66 | private static final float MAX_AMOUNT = 10000.00f; 67 | 68 | @Override 69 | protected boolean canHandle(Order _order) { 70 | return Float.compare(MAX_AMOUNT, _order.orderAmount) >= 0; 71 | } 72 | 73 | @Override 74 | protected String processOrder(Order _order) { 75 | return _order.description + " handled by BigOrderHandler"; 76 | } 77 | } 78 | 79 | @ChainOfResponsibilityPattern.ConcreteHandler 80 | private static class HugeOrderHandler extends OrderHandler { 81 | @Override 82 | protected boolean canHandle(Order _order) { 83 | return true; 84 | } 85 | 86 | @Override 87 | protected String processOrder(Order _order) { 88 | return _order.description + " handled by HugeOrderHandler"; 89 | } 90 | } 91 | 92 | 93 | @Before 94 | public void initializeHandlers() { 95 | this.regularOrderHandler = new RegularOrderHandler(); 96 | this.bigOrderHandler = new BigOrderHandler(); 97 | this.hugeOrderHandler = new HugeOrderHandler(); 98 | this.regularOrderHandler.setSuccessor(this.bigOrderHandler); 99 | this.bigOrderHandler.setSuccessor(this.hugeOrderHandler); 100 | } 101 | 102 | 103 | @Test 104 | public void testSmallOrder() { 105 | Order order = new Order(10, "smallOrder"); 106 | String handlerResponse = this.regularOrderHandler.handleOrder(order); 107 | assertEquals("smallOrder handled by RegularOrderHandler", handlerResponse); 108 | } 109 | 110 | @Test 111 | public void testBigOrder() { 112 | Order order = new Order(1000, "bigOrder"); 113 | String handlerResponse = this.regularOrderHandler.handleOrder(order); 114 | assertEquals("bigOrder handled by BigOrderHandler", handlerResponse); 115 | } 116 | 117 | @Test 118 | public void testHugeOrder() { 119 | Order order = new Order(100000, "hugeOrder"); 120 | String handlerResponse = this.regularOrderHandler.handleOrder(order); 121 | assertEquals("hugeOrder handled by HugeOrderHandler", handlerResponse); 122 | } 123 | } 124 | 125 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/CommandGUIActionTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.junit.Test; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | import java.awt.event.ActionEvent; 8 | 9 | /** 10 | * @author Heinz Kabutz 11 | * @since 2010-08-09 12 | */ 13 | public class CommandGUIActionTest { 14 | @CommandPattern.Invoker 15 | private static class MyButton extends JButton { 16 | public MyButton(javax.swing.Action a) { 17 | super(a); 18 | } 19 | } 20 | 21 | @CommandPattern.ConcreteCommand(participants = MyReceiver.class) 22 | private static class FooAction extends AbstractAction { 23 | private final MyReceiver receiver; 24 | 25 | private FooAction(MyReceiver receiver) { 26 | super("Foo"); 27 | this.receiver = receiver; 28 | } 29 | 30 | public void actionPerformed(ActionEvent e) { 31 | receiver.foo(); 32 | } 33 | } 34 | 35 | @CommandPattern.ConcreteCommand 36 | private static class BarAction extends AbstractAction { 37 | private final MyReceiver receiver; 38 | 39 | private BarAction(MyReceiver receiver) { 40 | super("Bar"); 41 | this.receiver = receiver; 42 | } 43 | 44 | public void actionPerformed(ActionEvent e) { 45 | receiver.bar(); 46 | } 47 | } 48 | 49 | @CommandPattern.Receiver 50 | private static class MyReceiver { 51 | public void foo() { 52 | System.out.println("foo was pressed"); 53 | } 54 | 55 | public void bar() { 56 | System.out.println("bar was pressed"); 57 | } 58 | } 59 | 60 | @CommandPattern.Client 61 | private static class MyClient extends JFrame { 62 | public MyClient(Action... actions) { 63 | super("MyClient"); 64 | setDefaultCloseOperation(EXIT_ON_CLOSE); 65 | setSize(400, 500); 66 | addActions(actions); 67 | setVisible(true); 68 | } 69 | 70 | private void addActions(Action... actions) { 71 | addButtons(actions); 72 | addMenus(actions); 73 | } 74 | 75 | private void addMenus(Action... actions) { 76 | JMenuBar menubar = new JMenuBar(); 77 | JMenu menu = new JMenu("MyActions"); 78 | menubar.add(menu); 79 | for (Action action : actions) { 80 | menu.add(new JMenuItem(action)); 81 | } 82 | setJMenuBar(menubar); 83 | } 84 | 85 | private void addButtons(Action... actions) { 86 | setLayout(new FlowLayout()); 87 | for (Action action : actions) { 88 | add(new MyButton(action)); 89 | } 90 | } 91 | } 92 | 93 | public static void main(String[] args) { 94 | MyReceiver receiver = new MyReceiver(); 95 | final FooAction foo_action = new FooAction(receiver); 96 | final BarAction bar_action = new BarAction(receiver); 97 | 98 | SwingUtilities.invokeLater(new Runnable() { 99 | public void run() { 100 | new MyClient(foo_action, bar_action); 101 | } 102 | }); 103 | } 104 | 105 | @Test 106 | public void bindUpReceivers() { 107 | MyReceiver receiver = new MyReceiver(); 108 | final FooAction foo_action = new FooAction(receiver); 109 | final BarAction bar_action = new BarAction(receiver); 110 | foo_action.actionPerformed(null); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/CommandTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import org.junit.Test; 5 | 6 | /** 7 | * @author Michael Hunger 8 | * @since 2010-07-14 9 | */ 10 | @CommandPattern.Invoker(participants = CommandTest.Command.class) 11 | public class CommandTest { 12 | @Test 13 | public void executeCommand() { 14 | final TestCommand command = new TestCommand(); 15 | new CommandReceiver().receive(command); 16 | assertEquals(true, command.ran); 17 | } 18 | 19 | @CommandPattern.Command(participants = CommandReceiver.class) 20 | interface Command { 21 | void execute(); 22 | } 23 | 24 | @CommandPattern.ConcreteCommand(comment = "This is our TestCommand") 25 | class TestCommand implements Command { 26 | private boolean ran; 27 | 28 | public void execute() { 29 | ran = true; 30 | } 31 | } 32 | 33 | @CommandPattern.Receiver(participants = Command.class) 34 | private class CommandReceiver { 35 | 36 | public void receive(Command command) { 37 | command.execute(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/CompositeTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static junit.framework.Assert.assertEquals; 4 | import org.junit.Test; 5 | 6 | import java.util.*; 7 | 8 | public class CompositeTest { 9 | @CompositePattern.Component(participants = {DistributionList.class, 10 | Person.class}) 11 | private static abstract class Contact { 12 | public abstract void sendMail(String msg); 13 | 14 | public void add(Contact contact) { 15 | } 16 | 17 | public void remove(Contact contact) { 18 | } 19 | } 20 | 21 | @CompositePattern.Leaf 22 | private static class Person extends Contact { 23 | private String lastMsg; 24 | private final String email; 25 | 26 | public Person(String email) { 27 | this.email = email; 28 | } 29 | 30 | public void sendMail(String msg) { 31 | System.out.println("here is the message: " + msg); 32 | lastMsg = msg; 33 | } 34 | 35 | private String getLastMessage() { 36 | return lastMsg; 37 | } 38 | } 39 | 40 | @CompositePattern.Composite(comment = "bla bla bla") 41 | private static class DistributionList extends Contact { 42 | private final Collection contacts = new ArrayList(); 43 | 44 | public void sendMail(String msg) { 45 | for (Contact contact : contacts) { 46 | contact.sendMail(msg); 47 | } 48 | } 49 | 50 | public void add(Contact contact) { 51 | contacts.add(contact); 52 | } 53 | 54 | public void remove(Contact contact) { 55 | contacts.remove(contact); 56 | } 57 | } 58 | 59 | @Test 60 | public void personWasSentMessage() { 61 | Person heinz = new Person("heinz@javaspecialists.eu"); 62 | Contact admins = new DistributionList(); 63 | admins.add(heinz); 64 | Contact all = new DistributionList(); 65 | all.add(admins); 66 | all.sendMail("hey there!"); 67 | assertEquals("hey there!", heinz.getLastMessage()); 68 | } 69 | } -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/DecoratorTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * @author Alex Gout 9 | * @since 2010-09-10 10 | */ 11 | public class DecoratorTest { 12 | @DecoratorPattern.Component(participants = HTMLDecorator.class) 13 | private static interface HTMLContent { 14 | String getContent(); 15 | } 16 | 17 | @DecoratorPattern.ConcreteComponent 18 | private static class SimpleHTMLContent implements HTMLContent { 19 | 20 | private String content; 21 | 22 | private SimpleHTMLContent(String _content) { 23 | this.content = _content; 24 | } 25 | 26 | public String getContent() { 27 | return this.content; 28 | } 29 | } 30 | 31 | @DecoratorPattern.Decorator(participants = HTMLContent.class) 32 | private static abstract class HTMLDecorator implements HTMLContent { 33 | protected HTMLContent htmlContent; 34 | 35 | 36 | protected HTMLDecorator(HTMLContent _content) { 37 | this.htmlContent = _content; 38 | } 39 | 40 | public String getContent() { 41 | return getStartTag() + this.htmlContent.getContent() + getEndTag(); 42 | 43 | } 44 | 45 | protected final String getStartTag() { 46 | return "<" + getTag() + ">"; 47 | } 48 | 49 | protected final String getEndTag() { 50 | return ""; 51 | } 52 | 53 | protected abstract String getTag(); 54 | 55 | 56 | } 57 | 58 | @DecoratorPattern.ConcreteDecorator 59 | private static class BoldDecorator extends HTMLDecorator { 60 | protected BoldDecorator(HTMLContent _content) { 61 | super(_content); 62 | } 63 | 64 | 65 | @Override 66 | protected String getTag() { 67 | return "strong"; 68 | } 69 | } 70 | 71 | @DecoratorPattern.ConcreteDecorator 72 | private static class SpanDecorator extends HTMLDecorator { 73 | protected SpanDecorator(HTMLContent _content) { 74 | super(_content); 75 | } 76 | 77 | @Override 78 | protected String getTag() { 79 | return "span"; 80 | } 81 | } 82 | 83 | @Test 84 | public void testBoldSpanText() { 85 | HTMLContent content = new SimpleHTMLContent("Hello JPatterns!!"); 86 | content = new BoldDecorator(content); 87 | content = new SpanDecorator(content); 88 | 89 | assertEquals("Hello JPatterns!!", content.getContent()); 90 | System.out.println(content.getContent()); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/FacadeTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static junit.framework.Assert.assertEquals; 4 | import org.junit.Test; 5 | 6 | /** 7 | * @author Heinz Kabutz 8 | * @since 2010-08-09 9 | */ 10 | public class FacadeTest { 11 | @FacadePattern 12 | public static class Tests { 13 | public void isEquals(Object expected, Object actual) { 14 | assertEquals(expected, actual); 15 | } 16 | } 17 | 18 | @Test 19 | public void facadeProvidesIsEquals() { 20 | new Tests().isEquals(1, Integer.valueOf(1)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/FactoryMethodTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.*; 6 | 7 | /** 8 | * @author Alex Gout 9 | * @since 2010-09-10 10 | */ 11 | public class FactoryMethodTest { 12 | 13 | @FactoryMethodPattern.Product(participants = NumberPrinter.class) 14 | private static interface NumberGenerator { 15 | public int next(); 16 | } 17 | 18 | @FactoryMethodPattern.Creator(participants = NumberGenerator.class) 19 | private static abstract class NumberPrinter { 20 | 21 | public void printNumbers(int _upto) { 22 | Collection result = new ArrayList(); 23 | NumberGenerator numberGenerator = createNumberGenerator(); 24 | int curNum = numberGenerator.next(); 25 | while (curNum < _upto) { 26 | result.add(Integer.valueOf(curNum)); 27 | curNum = numberGenerator.next(); 28 | } 29 | System.out.println(result); 30 | } 31 | 32 | protected abstract NumberGenerator createNumberGenerator(); 33 | } 34 | 35 | @FactoryMethodPattern.ConcreteProduct 36 | private static class PrimeGenerator implements NumberGenerator { 37 | int number = 0; 38 | 39 | 40 | public int next() { 41 | while (!isPrime(number)) { 42 | number++; 43 | } 44 | return number++; 45 | } 46 | 47 | boolean isPrime(int n) { 48 | if (n % 2 == 0) return false; 49 | for (int i = 3; i * i <= n; i += 2) { 50 | if (n % i == 0) 51 | return false; 52 | } 53 | return true; 54 | } 55 | } 56 | 57 | @FactoryMethodPattern.ConcreteCreator 58 | private static class PrimePrinter extends NumberPrinter { 59 | 60 | @Override 61 | protected NumberGenerator createNumberGenerator() { 62 | return new PrimeGenerator(); 63 | } 64 | } 65 | 66 | @FactoryMethodPattern.ConcreteProduct 67 | private static class FibonacciGenerator implements NumberGenerator { 68 | private int fibPos = 0; 69 | 70 | public int next() { 71 | return fibonacciNumber(fibPos++); 72 | } 73 | 74 | private int fibonacciNumber(int _pos) { 75 | if (_pos <= 1) return _pos; 76 | return fibonacciNumber(_pos - 1) + fibonacciNumber(_pos - 2); 77 | } 78 | } 79 | 80 | @FactoryMethodPattern.ConcreteCreator 81 | private static class FibonacciPrinter extends NumberPrinter { 82 | 83 | @Override 84 | protected NumberGenerator createNumberGenerator() { 85 | return new FibonacciGenerator(); 86 | } 87 | } 88 | 89 | @Test 90 | public void testFibonacciPrinter() { 91 | NumberPrinter numPrinter = new FibonacciPrinter(); 92 | numPrinter.printNumbers(1000); 93 | } 94 | 95 | @Test 96 | public void testPrimePrinter() { 97 | NumberPrinter numPrinter = new PrimePrinter(); 98 | numPrinter.printNumbers(1000); 99 | } 100 | 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/FlyweightTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import org.junit.Test; 4 | 5 | import java.awt.*; 6 | import java.lang.ref.WeakReference; 7 | import java.util.*; 8 | 9 | import static junit.framework.Assert.assertNotSame; 10 | import static org.junit.Assert.assertSame; 11 | import static org.junit.Assert.assertTrue; 12 | 13 | /** 14 | * @author Alex Gout 15 | * @since 2010-09-10 16 | */ 17 | public class FlyweightTest { 18 | enum AlienRace { 19 | Aldebarans, Bartledanians, Grebulons, Krikkiters, Shaltanacs, Poghrils, Humans 20 | } 21 | 22 | enum Location { 23 | Argabuthon, EroticonVI, Gagrakacka, Krikkit, Magrathea, NowWhat, ViltvodleVI, Vod, Xaxis 24 | } 25 | 26 | @FlyweightPattern.Flyweight(participants = {AnonymousAlien.class, KnownAlien.class}) 27 | private interface Alien { 28 | String getName(); 29 | } 30 | 31 | 32 | @FlyweightPattern.ConcreteFlyweight(participants = {Alien.class, KnownAlien.class}) 33 | @FlyweightPattern.FlyweightFactory(participants = {Alien.class, KnownAlien.class}) 34 | private static class AnonymousAlien implements Alien { 35 | private static final Map> anonymousAliens = new HashMap>(); 36 | 37 | private Color color; 38 | private AlienRace alienRace; 39 | private Location approximatePlaceOfBirth; 40 | 41 | private AnonymousAlien(Color _color, AlienRace _alienRace, Location _approximatePlaceOfBirth) { 42 | this.color = _color; 43 | this.alienRace = _alienRace; 44 | this.approximatePlaceOfBirth = _approximatePlaceOfBirth; 45 | } 46 | 47 | private static Alien getAnonymousAlienForKnownData(Color _color, AlienRace _race, Location _placeOfBirth) { 48 | Alien tmp = new AnonymousAlien(_color, _race, _placeOfBirth); 49 | 50 | WeakReference ref = anonymousAliens.get(tmp); 51 | 52 | Alien alien = null; 53 | if (ref == null) { 54 | alien = tmp; 55 | anonymousAliens.put(alien, new WeakReference(alien)); 56 | } else { 57 | alien = ref.get(); 58 | } 59 | return alien; 60 | } 61 | 62 | @Override 63 | public boolean equals(Object _object) { 64 | if (_object == this) { 65 | return true; 66 | } 67 | if (!(_object instanceof AnonymousAlien)) { 68 | return false; 69 | } 70 | AnonymousAlien that = (AnonymousAlien) _object; 71 | return (this.color == that.color) && (this.alienRace == that.alienRace) && (this.approximatePlaceOfBirth == that.approximatePlaceOfBirth); 72 | } 73 | 74 | @Override 75 | public int hashCode() { 76 | return (this.color.hashCode() * 13 + this.alienRace.hashCode() * 31) * this.approximatePlaceOfBirth.hashCode() * 11; 77 | } 78 | 79 | public String getName() { 80 | return "anonymous"; 81 | } 82 | } 83 | 84 | @FlyweightPattern.UnsharedConcreteFlyweight(participants = {Alien.class, AnonymousAlien.class}) 85 | private static class KnownAlien implements Alien { 86 | private String name; 87 | private AlienRace alienRace; 88 | 89 | private KnownAlien(String _name, AlienRace _alienRace) { 90 | this.name = _name; 91 | this.alienRace = _alienRace; 92 | } 93 | 94 | public String getName() { 95 | return this.name; 96 | } 97 | 98 | public AlienRace getAlienRace() { 99 | return this.alienRace; 100 | } 101 | } 102 | 103 | @Test 104 | public void testAnonymousAlien() { 105 | Alien alien = AnonymousAlien.getAnonymousAlienForKnownData(Color.BLUE, AlienRace.Krikkiters, Location.EroticonVI); 106 | Alien otherAlienSame = AnonymousAlien.getAnonymousAlienForKnownData(Color.BLUE, AlienRace.Krikkiters, Location.EroticonVI); 107 | Alien otherAlienOther = AnonymousAlien.getAnonymousAlienForKnownData(Color.YELLOW, AlienRace.Krikkiters, Location.EroticonVI); 108 | 109 | assertTrue(AnonymousAlien.anonymousAliens.size() == 2); 110 | assertSame(otherAlienSame, alien); 111 | assertNotSame(otherAlienOther, alien); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/ProxyTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertTrue; 5 | import org.junit.Test; 6 | 7 | /** 8 | * @author Heinz Kabutz 9 | * @since 2010-08-09 10 | */ 11 | public class ProxyTest { 12 | 13 | private static class Norwegian { 14 | @ProxyPattern.Client 15 | private final Lutefisk lutefisk; 16 | private boolean sick; 17 | 18 | private Norwegian(Lutefisk lutefisk) { 19 | this.lutefisk = lutefisk; 20 | lutefisk.storedBy(this); 21 | } 22 | 23 | public boolean isSick() { 24 | return sick; 25 | } 26 | 27 | public void becomeSick() { 28 | this.sick = true; 29 | } 30 | 31 | public void eatFisk() { 32 | lutefisk.eatenBy(this); 33 | } 34 | } 35 | 36 | @ProxyPattern.Subject(participants = {LutefiskProxy.class, 37 | LutefiskImpl.class}) 38 | private interface Lutefisk { 39 | void eatenBy(Norwegian eater); 40 | 41 | void storedBy(Norwegian owner); 42 | } 43 | 44 | @ProxyPattern.Proxy( 45 | variation = ProxyPattern.Variation.STATIC_MANUAL, 46 | type = ProxyPattern.Type.VIRTUAL) 47 | public static class LutefiskProxy implements Lutefisk { 48 | private Lutefisk realSubject; 49 | 50 | public void eatenBy(Norwegian eater) { 51 | if (realSubject == null) { 52 | realSubject = new LutefiskImpl(); 53 | } 54 | realSubject.eatenBy(eater); 55 | } 56 | 57 | public void storedBy(Norwegian owner) { 58 | // nothing happens 59 | } 60 | } 61 | 62 | @ProxyPattern.Subject 63 | private static class LutefiskImpl implements Lutefisk { 64 | public void eatenBy(Norwegian eater) { 65 | eater.becomeSick(); 66 | } 67 | 68 | public void storedBy(Norwegian owner) { 69 | owner.becomeSick(); 70 | } 71 | } 72 | 73 | @Test 74 | public void norwegianGetSickWhenBuyingRealLutefisk() { 75 | Norwegian norwegian = new Norwegian(new LutefiskImpl()); 76 | Lutefisk lutefisk = new LutefiskImpl(); 77 | assertTrue("sick from storing", norwegian.isSick()); 78 | norwegian.eatFisk(); 79 | assertTrue("sick from eating", norwegian.isSick()); 80 | } 81 | 82 | @Test 83 | public void norwegianGetSickWhenEatingLutefisk() { 84 | Norwegian norwegian = new Norwegian(new LutefiskProxy()); 85 | assertFalse("not sick from storing", norwegian.isSick()); 86 | norwegian.eatFisk(); 87 | assertTrue("sick from eating", norwegian.isSick()); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/SingletonEagerTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static junit.framework.Assert.assertNotNull; 4 | import org.junit.Test; 5 | 6 | public class SingletonEagerTest { 7 | @SingletonPattern.Singleton(variation = SingletonPattern.Variation.EAGER) 8 | public static class EagerSingleton { 9 | private final static EagerSingleton INSTANCE = new EagerSingleton(); 10 | 11 | private EagerSingleton() { 12 | } 13 | 14 | @SingletonPattern.SingletonMethod 15 | public static EagerSingleton getInstance() { 16 | return INSTANCE; 17 | } 18 | } 19 | 20 | @Test 21 | public void testEagerness() { 22 | assertNotNull(EagerSingleton.INSTANCE); 23 | assertNotNull(EagerSingleton.getInstance()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/SingletonLazyTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static junit.framework.Assert.assertNotNull; 4 | import static junit.framework.Assert.assertNull; 5 | import org.junit.Test; 6 | 7 | public class SingletonLazyTest { 8 | @SingletonPattern.Singleton(variation = SingletonPattern.Variation.LAZY) 9 | public static class LazySingleton { 10 | private volatile static LazySingleton INSTANCE; 11 | 12 | private LazySingleton() { 13 | } 14 | 15 | @SingletonPattern.SingletonMethod 16 | public static LazySingleton getInstance() { 17 | LazySingleton result = INSTANCE; 18 | if (result == null) { 19 | synchronized (LazySingleton.class) { 20 | result = INSTANCE; 21 | if (result == null) { 22 | INSTANCE = result = new LazySingleton(); 23 | } 24 | } 25 | } 26 | return result; 27 | } 28 | } 29 | 30 | @Test 31 | public void testLaziness() { 32 | assertNull(LazySingleton.INSTANCE); 33 | assertNotNull(LazySingleton.getInstance()); 34 | assertNotNull(LazySingleton.INSTANCE); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/SingletonTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static junit.framework.Assert.assertSame; 4 | import org.junit.Test; 5 | 6 | /** 7 | * @author Alex Gout 8 | * @since 2010-08-08 9 | */ 10 | public class SingletonTest { 11 | @Test 12 | public void testSameInstance() { 13 | Singleton singleton = Singleton.getInstance(); 14 | Singleton singleton2 = Singleton.getInstance(); 15 | 16 | assertSame(singleton, singleton2); 17 | } 18 | 19 | @SingletonPattern.Singleton(variation = SingletonPattern.Variation.EAGER) 20 | public static class Singleton { 21 | private final static Singleton INSTANCE = new Singleton(); 22 | 23 | private Singleton() { 24 | } 25 | 26 | @SingletonPattern.SingletonMethod 27 | public static final Singleton getInstance() { 28 | return INSTANCE; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/StrategyTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import org.junit.Test; 5 | 6 | import java.util.zip.Adler32; 7 | 8 | /** 9 | * @author Heinz Kabutz 10 | * @since 2010-08-09 11 | */ 12 | public class StrategyTest { 13 | @StrategyPattern.Strategy 14 | private static interface Checksum { 15 | public void update(int b); 16 | 17 | public void update(byte[] b); 18 | 19 | public void update(byte[] b, int off, int len); 20 | 21 | public long getValue(); 22 | 23 | public void reset(); 24 | } 25 | 26 | @StrategyPattern.ConcreteStrategy 27 | private static class MyAdler32 implements Checksum { 28 | private final Adler32 delegate = new Adler32(); 29 | 30 | public void update(int b) { 31 | delegate.update(b); 32 | } 33 | 34 | public void update(byte[] b, int off, int len) { 35 | delegate.update(b, off, len); 36 | } 37 | 38 | public void update(byte[] b) { 39 | delegate.update(b); 40 | } 41 | 42 | public void reset() { 43 | delegate.reset(); 44 | } 45 | 46 | public long getValue() { 47 | return delegate.getValue(); 48 | } 49 | } 50 | 51 | @StrategyPattern.ConcreteStrategy 52 | private static class Heinz57 implements Checksum { 53 | private long value = 57; 54 | 55 | public void update(int b) { 56 | value += b * 57; 57 | } 58 | 59 | public void update(byte[] b, int off, int len) { 60 | for (int i = 0; i < len; i++) { 61 | update(b[i + off]); 62 | } 63 | } 64 | 65 | public void update(byte[] b) { 66 | for (byte b1 : b) { 67 | update(b1); 68 | } 69 | } 70 | 71 | public void reset() { 72 | value = 57; 73 | } 74 | 75 | public long getValue() { 76 | return value; 77 | } 78 | } 79 | 80 | @Test 81 | public void adler32StrategyWorks() { 82 | final Checksum checksum = new MyAdler32(); 83 | byte[] bytes = {1, 2, 4, 8, 16}; 84 | for (byte value : bytes) { 85 | checksum.update(value); 86 | } 87 | final long crc = checksum.getValue(); 88 | checksum.reset(); 89 | checksum.update(bytes); 90 | assertEquals(crc, checksum.getValue()); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/gof/TemplateMethodTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.gof; 2 | 3 | import static org.easymock.EasyMock.*; 4 | import static org.junit.Assert.assertEquals; 5 | import org.junit.Test; 6 | 7 | import java.io.*; 8 | import java.sql.*; 9 | 10 | /** 11 | * @author Heinz Kabutz 12 | * @since 2010-08-09 13 | */ 14 | public class TemplateMethodTest { 15 | @TemplateMethodPattern.AbstractClass 16 | private static abstract class CloseHelper { 17 | @TemplateMethodPattern.TemplateMethod 18 | public final Object run(Object[] params) throws Exception { 19 | setUp(params); 20 | Exception ex = null; 21 | try { 22 | return doExecute(params); 23 | } catch (Exception ex1) { 24 | ex = ex1; 25 | } finally { 26 | try { 27 | tearDown(params); 28 | } catch (Exception ex1) { 29 | if (ex == null) { 30 | ex = ex1; 31 | } 32 | } 33 | } 34 | throw ex; 35 | } 36 | 37 | @TemplateMethodPattern.PrimitiveOperation 38 | protected abstract void setUp(Object[] params) throws Exception; 39 | 40 | @TemplateMethodPattern.PrimitiveOperation 41 | protected abstract Object doExecute(Object[] params) throws Exception; 42 | 43 | @TemplateMethodPattern.PrimitiveOperation 44 | protected abstract void tearDown(Object[] params) throws Exception; 45 | } 46 | 47 | @TemplateMethodPattern.ConcreteClass 48 | private static class DBHelper extends CloseHelper { 49 | private final Connection con; 50 | private Statement st; 51 | 52 | public DBHelper(Connection con) { 53 | this.con = con; 54 | } 55 | 56 | @TemplateMethodPattern.PrimitiveOperation 57 | protected void setUp(Object[] params) throws SQLException { 58 | st = con.createStatement(); 59 | } 60 | 61 | @TemplateMethodPattern.PrimitiveOperation 62 | protected Integer doExecute(Object[] params) throws SQLException { 63 | return st.executeUpdate((String) params[0]); 64 | } 65 | 66 | @TemplateMethodPattern.PrimitiveOperation 67 | protected void tearDown(Object[] params) throws SQLException { 68 | st.close(); 69 | } 70 | } 71 | 72 | @TemplateMethodPattern 73 | private static class FileHelper extends CloseHelper { 74 | private final String filename; 75 | private BufferedReader reader; 76 | 77 | public FileHelper(String filename) { 78 | this.filename = filename; 79 | } 80 | 81 | protected void setUp(Object[] params) throws FileNotFoundException { 82 | reader = new BufferedReader(new InputStreamReader( 83 | new FileInputStream(filename) 84 | )); 85 | } 86 | 87 | protected Integer doExecute(Object[] params) throws IOException { 88 | String s; 89 | int lines = 0; 90 | while ((s = reader.readLine()) != null) { 91 | lines++; 92 | System.out.printf("%05d: %s%n", lines, s); 93 | } 94 | return lines; 95 | } 96 | 97 | protected void tearDown(Object[] params) throws IOException { 98 | reader.close(); 99 | } 100 | } 101 | 102 | @Test 103 | public void databaseResourcesAreSetupUsedAndClosed() throws Exception { 104 | final String[] params = {"sql"}; 105 | final int rows = 1; 106 | 107 | final Statement statement = createMock(Statement.class); 108 | expect(statement.executeUpdate(params[0])).andReturn(rows); 109 | statement.close(); 110 | expectLastCall().once(); 111 | final Connection con = createMock(Connection.class); 112 | expect(con.createStatement()).andReturn(statement); 113 | 114 | replay(con, statement); 115 | 116 | final DBHelper dbHelper = new DBHelper(con); 117 | assertEquals((Integer) rows, dbHelper.run(params)); 118 | verify(con, statement); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/jee/BusinessDelegateTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.jee; 2 | 3 | import junit.framework.Assert; 4 | import org.junit.Test; 5 | 6 | public class BusinessDelegateTest { 7 | 8 | public static final String OP1_RET_VALUE = "operation1"; 9 | public static final String OP2_RET_VALUE = "operation2"; 10 | public static final String OP3_RET_VALUE = "operation3"; 11 | 12 | @BusinessDelegatePattern.BusinessDelegate 13 | class BusinessDelegate { 14 | 15 | @BusinessDelegatePattern.BusinessService 16 | private final BusinessService1 service1 = new BusinessService1(); 17 | 18 | @BusinessDelegatePattern.BusinessService 19 | private final BusinessService2 service2 = new BusinessService2(); 20 | 21 | @BusinessDelegatePattern.BusinessService 22 | private final BusinessService3 service3 = new BusinessService3(); 23 | 24 | public String operation1() { 25 | return service1.operation1(); 26 | } 27 | 28 | public String operation2() { 29 | return service2.operation2(); 30 | } 31 | 32 | public String operation3() { 33 | return service3.operation3(); 34 | } 35 | 36 | } 37 | 38 | @BusinessDelegatePattern.BusinessService 39 | class BusinessService1 { 40 | 41 | public String operation1() { 42 | return OP1_RET_VALUE; 43 | } 44 | 45 | } 46 | 47 | @BusinessDelegatePattern.BusinessService 48 | class BusinessService2 { 49 | 50 | public String operation2() { 51 | return OP2_RET_VALUE; 52 | } 53 | 54 | } 55 | 56 | @BusinessDelegatePattern.BusinessService 57 | class BusinessService3 { 58 | 59 | public String operation3() { 60 | return OP3_RET_VALUE; 61 | } 62 | 63 | } 64 | 65 | @Test 66 | public void testBusinessDelegate() { 67 | 68 | String expectedOp1 = OP1_RET_VALUE; 69 | String expectedOp2 = OP2_RET_VALUE; 70 | String expectedOp3 = OP3_RET_VALUE; 71 | 72 | @BusinessDelegatePattern.BusinessDelegate(comment = "The Business Delegate " 73 | + "should hide the complexity of all the Business Services which it uses") 74 | BusinessDelegate bd = new BusinessDelegate(); 75 | 76 | String actualOp1 = bd.operation1(); 77 | 78 | Assert.assertEquals("The actual " + actualOp1 + " and expected " 79 | + expectedOp1 + " are not the same", expectedOp1, actualOp1); 80 | 81 | String actualOp2 = bd.operation2(); 82 | Assert.assertEquals("The actual " + actualOp2 + " and expected " 83 | + expectedOp2 + " are not the same", expectedOp2, actualOp2); 84 | 85 | String actualOp3 = bd.operation3(); 86 | Assert.assertEquals("The actual " + actualOp3 + " and expected " 87 | + expectedOp3 + " are not the same", expectedOp3, actualOp3); 88 | 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/jee/DataAccessObjectTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.jee; 2 | 3 | import junit.framework.Assert; 4 | import org.junit.Test; 5 | 6 | public class DataAccessObjectTest { 7 | 8 | private static final String LAST_NAME = "lastName"; 9 | private static final String FIRST_NAME = "firstName"; 10 | private static final String MODIFIED_FIRST_NAME = "firstNameModified"; 11 | private static final String MODIFIED_LAST_NAME = "modifiedLastName"; 12 | 13 | @DataAccessObjectPattern.BusinessObject 14 | class BusinessObject { 15 | 16 | @DataAccessObjectPattern.Dao(comment = "Mock dao to simulate connection to the database") 17 | private final DataAccessObject dao = new DataAccessObject(); 18 | 19 | public ValueObject findThatValueObject() { 20 | return dao.getData(); 21 | } 22 | 23 | /** 24 | * Updates the {@link ValueObject} and returns the updated version 25 | * 26 | * @return The updated value object 27 | */ 28 | public ValueObject updateThatValueObject() { 29 | @DataAccessObjectPattern.ValueObject 30 | ValueObject valueObject = dao.getData(); 31 | 32 | valueObject.setFirstName(MODIFIED_FIRST_NAME); 33 | valueObject.setLastName(MODIFIED_LAST_NAME); 34 | dao.setData(valueObject); 35 | return valueObject; 36 | } 37 | 38 | } 39 | 40 | @DataAccessObjectPattern.Dao 41 | class DataAccessObject { 42 | 43 | @DataAccessObjectPattern.DataSource(comment = "This is the DataSource which will connect to the database") 44 | private DataSource ds = new DataSource(); 45 | 46 | public ValueObject getData() { 47 | FullName fullName = ds.getData(); 48 | return new ValueObject(fullName.getFirstName(), fullName.getLastName()); 49 | } 50 | 51 | public void setData(@DataAccessObjectPattern.ValueObject ValueObject valueObject) { 52 | ds.setData(valueObject); 53 | 54 | } 55 | 56 | } 57 | 58 | @DataAccessObjectPattern.DataSource 59 | class DataSource { 60 | 61 | public FullName getData() { 62 | return new FullName(FIRST_NAME, LAST_NAME); 63 | } 64 | 65 | public void setData(@DataAccessObjectPattern.ValueObject ValueObject valueObject) { 66 | // It would normally persist to the database 67 | } 68 | 69 | } 70 | 71 | @DataAccessObjectPattern.ValueObject 72 | class ValueObject { 73 | 74 | private String firstName; 75 | 76 | private String lastName; 77 | 78 | public ValueObject(String firstName, String lastName) { 79 | this.firstName = firstName; 80 | this.lastName = lastName; 81 | } 82 | 83 | public String getFirstName() { 84 | return firstName; 85 | } 86 | 87 | public String getLastName() { 88 | return lastName; 89 | } 90 | 91 | public void setLastName(String modifiedLastName) { 92 | lastName = modifiedLastName; 93 | 94 | } 95 | 96 | public void setFirstName(String modifiedFirstName) { 97 | firstName = modifiedFirstName; 98 | 99 | } 100 | 101 | @Override 102 | public int hashCode() { 103 | final int prime = 31; 104 | int result = 1; 105 | result = prime * result 106 | + ((firstName == null) ? 0 : firstName.hashCode()); 107 | result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); 108 | return result; 109 | } 110 | 111 | @Override 112 | public boolean equals(Object obj) { 113 | if (this == obj) { 114 | return true; 115 | } 116 | if (obj == null) { 117 | return false; 118 | } 119 | if (getClass() != obj.getClass()) { 120 | return false; 121 | } 122 | ValueObject other = (ValueObject) obj; 123 | 124 | if (firstName == null) { 125 | if (other.firstName != null) { 126 | return false; 127 | } 128 | } else if (!firstName.equals(other.firstName)) { 129 | return false; 130 | } 131 | if (lastName == null) { 132 | if (other.lastName != null) { 133 | return false; 134 | } 135 | } else if (!lastName.equals(other.lastName)) { 136 | return false; 137 | } 138 | return true; 139 | } 140 | 141 | } 142 | 143 | class FullName { 144 | private final String firstName; 145 | 146 | private final String lastName; 147 | 148 | public FullName(String firstName, String lastName) { 149 | this.firstName = firstName; 150 | this.lastName = lastName; 151 | } 152 | 153 | public String getFirstName() { 154 | return firstName; 155 | } 156 | 157 | public String getLastName() { 158 | return lastName; 159 | } 160 | } 161 | 162 | @Test 163 | public void testCreateValueObject() { 164 | 165 | @DataAccessObjectPattern.ValueObject 166 | ValueObject expected = new ValueObject(FIRST_NAME, LAST_NAME); 167 | 168 | @DataAccessObjectPattern.BusinessObject(comment = "This represents the client") 169 | BusinessObject businessObject = new BusinessObject(); 170 | 171 | @DataAccessObjectPattern.ValueObject 172 | ValueObject valueObject = businessObject.findThatValueObject(); 173 | 174 | Assert.assertNotNull(valueObject); 175 | Assert.assertEquals(expected, valueObject); 176 | } 177 | 178 | @Test 179 | public void testUpdateValueObject() { 180 | 181 | @DataAccessObjectPattern.ValueObject(comment = "This represents our expectation") 182 | ValueObject expected = new ValueObject(MODIFIED_FIRST_NAME, 183 | MODIFIED_LAST_NAME); 184 | 185 | @DataAccessObjectPattern.BusinessObject(comment = "This represents the client") 186 | BusinessObject businessObject = new BusinessObject(); 187 | ValueObject valueObject = businessObject.updateThatValueObject(); 188 | Assert.assertNotNull(valueObject); 189 | Assert.assertEquals(expected, valueObject); 190 | 191 | } 192 | 193 | } 194 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/jee/ModelViewControllerTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.jee; 2 | 3 | import junit.framework.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.*; 7 | import java.util.*; 8 | 9 | public class ModelViewControllerTest { 10 | 11 | private static final int HTTP_REQUEST_OK = 200; 12 | 13 | @ModelViewController.View 14 | class View { 15 | 16 | private final Controller controller = new Controller(); 17 | 18 | // This method is usually hidden from the user and part of the framework 19 | // machinery 20 | public int processUserRequest(String firstName, String lastName) 21 | throws IOException { 22 | 23 | HttpServletRequest request = new HttpServletRequest(); 24 | request.setRequestParameter("firstName", firstName); 25 | request.setRequestParameter("lastName", lastName); 26 | 27 | HttpServletResponse response = new HttpServletResponse(); 28 | 29 | controller.processRequest(request, response); 30 | 31 | return HTTP_REQUEST_OK; 32 | 33 | } 34 | 35 | } 36 | 37 | @ModelViewController.Controller 38 | class Controller { 39 | 40 | private final Model model = new Model(); 41 | 42 | public void processRequest(HttpServletRequest request, 43 | HttpServletResponse response) throws IOException { 44 | 45 | PersonVO person = new PersonVO(); 46 | person.setFirstName((String) request.getParameter("firstName")); 47 | person.setLastName((String) request.getParameter("lastName")); 48 | 49 | model.storePerson(person); 50 | 51 | } 52 | 53 | } 54 | 55 | @ModelViewController.Model 56 | class Model { 57 | 58 | public void storePerson(PersonVO personVo) { 59 | // Store person to database... 60 | } 61 | 62 | } 63 | 64 | class PersonVO implements Serializable { 65 | 66 | /** 67 | * 68 | */ 69 | private static final long serialVersionUID = 1L; 70 | 71 | private String firstName; 72 | 73 | private String lastName; 74 | 75 | public String getFirstName() { 76 | return firstName; 77 | } 78 | 79 | public String getLastName() { 80 | return lastName; 81 | } 82 | 83 | public void setFirstName(String firstName) { 84 | this.firstName = firstName; 85 | 86 | } 87 | 88 | public void setLastName(String lastName) { 89 | this.lastName = lastName; 90 | 91 | } 92 | 93 | @Override 94 | public int hashCode() { 95 | final int prime = 31; 96 | int result = 1; 97 | result = prime * result 98 | + ((firstName == null) ? 0 : firstName.hashCode()); 99 | result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); 100 | return result; 101 | } 102 | 103 | @Override 104 | public boolean equals(Object obj) { 105 | if (this == obj) { 106 | return true; 107 | } 108 | if (obj == null) { 109 | return false; 110 | } 111 | if (getClass() != obj.getClass()) { 112 | return false; 113 | } 114 | PersonVO other = (PersonVO) obj; 115 | if (firstName == null) { 116 | if (other.firstName != null) { 117 | return false; 118 | } 119 | } else if (!firstName.equals(other.firstName)) { 120 | return false; 121 | } 122 | if (lastName == null) { 123 | if (other.lastName != null) { 124 | return false; 125 | } 126 | } else if (!lastName.equals(other.lastName)) { 127 | return false; 128 | } 129 | return true; 130 | } 131 | 132 | } 133 | 134 | class HttpServletRequest { 135 | 136 | private final Map requestParameters = new HashMap(); 137 | 138 | public void setRequestParameter(String key, Object value) { 139 | 140 | requestParameters.put(key, value); 141 | 142 | } 143 | 144 | public Object getParameter(String key) { 145 | return requestParameters.get(key); 146 | } 147 | 148 | // Whatever... 149 | 150 | } 151 | 152 | class HttpServletResponse { 153 | // Whatever... 154 | } 155 | 156 | @Test 157 | public void testMvc() throws Exception { 158 | 159 | View view = new View(); 160 | String firstName = "firstName"; 161 | String lastName = "lastName"; 162 | int responseCode = view.processUserRequest(firstName, lastName); 163 | Assert.assertTrue(HTTP_REQUEST_OK == responseCode); 164 | 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /src/test/java/org/jpatterns/plopd/NullObjectTest.java: -------------------------------------------------------------------------------- 1 | package org.jpatterns.plopd; 2 | 3 | import static junit.framework.Assert.assertEquals; 4 | import org.junit.Test; 5 | 6 | public class NullObjectTest { 7 | @NullObjectPattern.AbstractObject 8 | private static interface Policy { 9 | float calculateInterest(); 10 | } 11 | 12 | @NullObjectPattern.NullObject 13 | private static class NullPolicy implements Policy { 14 | public float calculateInterest() { 15 | return 0.0f; 16 | } 17 | } 18 | 19 | @NullObjectPattern.RealObject 20 | private static class RealPolicy implements Policy { 21 | public float calculateInterest() { 22 | return 12.4f; 23 | } 24 | } 25 | 26 | @Test 27 | public void calculatingInterestWithNullObject() { 28 | Policy policy = new NullPolicy(); 29 | assertEquals(0.0f, policy.calculateInterest()); 30 | } 31 | 32 | @Test 33 | public void calculatingInterestWithRealObject() { 34 | Policy policy = new RealPolicy(); 35 | assertEquals(12.4f, policy.calculateInterest(), 0.01f); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /uml/ee/BusinessDelegateStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/ee/BusinessDelegateStructure.gif -------------------------------------------------------------------------------- /uml/ee/DaoStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/ee/DaoStructure.gif -------------------------------------------------------------------------------- /uml/ee/MVCStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/ee/MVCStructure.gif -------------------------------------------------------------------------------- /uml/gof/AbstractFactoryStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/AbstractFactoryStructure.gif -------------------------------------------------------------------------------- /uml/gof/AbstractFactoryUserViewStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/AbstractFactoryUserViewStructure.gif -------------------------------------------------------------------------------- /uml/gof/BridgeStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/BridgeStructure.gif -------------------------------------------------------------------------------- /uml/gof/ChainOfResponsibilityStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/ChainOfResponsibilityStructure.gif -------------------------------------------------------------------------------- /uml/gof/ClassAdapterStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/ClassAdapterStructure.gif -------------------------------------------------------------------------------- /uml/gof/CommandStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/CommandStructure.gif -------------------------------------------------------------------------------- /uml/gof/CompositeStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/CompositeStructure.gif -------------------------------------------------------------------------------- /uml/gof/DecoratorStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/DecoratorStructure.gif -------------------------------------------------------------------------------- /uml/gof/FacadeStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/FacadeStructure.gif -------------------------------------------------------------------------------- /uml/gof/FactoryMethodStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/FactoryMethodStructure.gif -------------------------------------------------------------------------------- /uml/gof/FlyweightStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/FlyweightStructure.gif -------------------------------------------------------------------------------- /uml/gof/IteratorStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/IteratorStructure.gif -------------------------------------------------------------------------------- /uml/gof/MementoStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/MementoStructure.gif -------------------------------------------------------------------------------- /uml/gof/ObjectAdapterStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/ObjectAdapterStructure.gif -------------------------------------------------------------------------------- /uml/gof/ObserverStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/ObserverStructure.gif -------------------------------------------------------------------------------- /uml/gof/ProxyStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/ProxyStructure.gif -------------------------------------------------------------------------------- /uml/gof/SingletonStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/SingletonStructure.gif -------------------------------------------------------------------------------- /uml/gof/StateStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/StateStructure.gif -------------------------------------------------------------------------------- /uml/gof/StrategyStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/StrategyStructure.gif -------------------------------------------------------------------------------- /uml/gof/TemplateMethodStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/TemplateMethodStructure.gif -------------------------------------------------------------------------------- /uml/gof/VisitorStructure.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jexp/jpatterns/f6537c1ae3bce4b401e256e27d7f569a00a8f993/uml/gof/VisitorStructure.gif --------------------------------------------------------------------------------