├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── abstract-factory ├── .gitignore ├── etc │ └── abstract-factory.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Army.java │ ├── Castle.java │ ├── ElfArmy.java │ ├── ElfCastle.java │ ├── ElfKing.java │ ├── ElfKingdomFactory.java │ ├── King.java │ ├── KingdomFactory.java │ ├── OrcArmy.java │ ├── OrcCastle.java │ ├── OrcKing.java │ └── OrcKingdomFactory.java ├── adapter ├── etc │ └── adapter.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Engineer.java │ ├── GnomeEngineer.java │ ├── GnomeEngineeringManager.java │ └── GoblinGlider.java ├── bridge ├── etc │ └── bridge.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── BlindingMagicWeapon.java │ ├── BlindingMagicWeaponImp.java │ ├── Excalibur.java │ ├── FlyingMagicWeapon.java │ ├── FlyingMagicWeaponImp.java │ ├── MagicWeapon.java │ ├── MagicWeaponImp.java │ ├── Mjollnir.java │ ├── SoulEatingMagicWeapon.java │ ├── SoulEatingMagicWeaponImp.java │ └── Stormbringer.java ├── builder ├── .gitignore ├── etc │ └── builder.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Armor.java │ ├── HairColor.java │ ├── HairType.java │ ├── Hero.java │ ├── Profession.java │ └── Weapon.java ├── chain ├── etc │ └── chain.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── OrcCommander.java │ ├── OrcKing.java │ ├── OrcOfficer.java │ ├── OrcSoldier.java │ ├── Request.java │ ├── RequestHandler.java │ └── RequestType.java ├── command ├── etc │ └── command.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Command.java │ ├── Goblin.java │ ├── InvisibilitySpell.java │ ├── ShrinkSpell.java │ ├── Size.java │ ├── Target.java │ ├── Visibility.java │ └── Wizard.java ├── composite ├── etc │ └── composite.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Letter.java │ ├── LetterComposite.java │ ├── Messenger.java │ ├── Sentence.java │ └── Word.java ├── decorator ├── etc │ └── decorator.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Hostile.java │ ├── SmartTroll.java │ └── Troll.java ├── facade ├── etc │ └── facade.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── DwarvenCartOperator.java │ ├── DwarvenGoldDigger.java │ ├── DwarvenGoldmineFacade.java │ ├── DwarvenMineWorker.java │ └── DwarvenTunnelDigger.java ├── factory-method ├── .gitignore ├── etc │ └── factory-method.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Blacksmith.java │ ├── ElfBlacksmith.java │ ├── ElfWeapon.java │ ├── OrcBlacksmith.java │ ├── OrcWeapon.java │ ├── Weapon.java │ └── WeaponType.java ├── flyweight ├── etc │ └── flyweight.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── AlchemistShop.java │ ├── App.java │ ├── HealingPotion.java │ ├── HolyWaterPotion.java │ ├── InvisibilityPotion.java │ ├── PoisonPotion.java │ ├── Potion.java │ ├── PotionFactory.java │ ├── PotionType.java │ └── StrengthPotion.java ├── interpreter ├── etc │ └── interpreter.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Expression.java │ ├── MinusExpression.java │ ├── MultiplyExpression.java │ ├── NumberExpression.java │ └── PlusExpression.java ├── iterator ├── etc │ └── iterator.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Item.java │ ├── ItemIterator.java │ ├── ItemType.java │ ├── TreasureChest.java │ └── TreasureChestItemIterator.java ├── mediator ├── etc │ └── mediator.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── Action.java │ ├── App.java │ ├── Hobbit.java │ ├── Hunter.java │ ├── Party.java │ ├── PartyImpl.java │ ├── PartyMember.java │ ├── PartyMemberBase.java │ ├── Rogue.java │ └── Wizard.java ├── memento ├── etc │ └── memento.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Star.java │ ├── StarMemento.java │ ├── StarMementoInternal.java │ └── StarType.java ├── observer ├── etc │ └── observer.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Hobbits.java │ ├── Orcs.java │ ├── Weather.java │ ├── WeatherObserver.java │ └── WeatherType.java ├── pom.xml ├── prototype ├── etc │ └── prototype.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Beast.java │ ├── ElfBeast.java │ ├── ElfMage.java │ ├── ElfWarlord.java │ ├── HeroFactory.java │ ├── HeroFactoryImpl.java │ ├── Mage.java │ ├── OrcBeast.java │ ├── OrcMage.java │ ├── OrcWarlord.java │ ├── Prototype.java │ └── Warlord.java ├── proxy ├── etc │ └── proxy.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── Wizard.java │ ├── WizardTower.java │ └── WizardTowerProxy.java ├── singleton ├── etc │ └── singleton.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ └── IvoryTower.java ├── state ├── etc │ └── state.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── AngryState.java │ ├── App.java │ ├── Mammoth.java │ ├── PeacefulState.java │ └── State.java ├── strategy ├── etc │ └── strategy.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── DragonSlayer.java │ ├── DragonSlayingStrategy.java │ ├── MeleeStrategy.java │ ├── ProjectileStrategy.java │ └── SpellStrategy.java ├── template-method ├── etc │ └── template-method.jpg ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── iluwatar │ ├── App.java │ ├── HalflingThief.java │ ├── HitAndRunMethod.java │ ├── StealingMethod.java │ └── SubtleMethod.java └── visitor ├── etc └── visitor.jpg ├── pom.xml └── src └── main └── java └── com └── iluwatar ├── App.java ├── Commander.java ├── CommanderVisitor.java ├── Sergeant.java ├── SergeantVisitor.java ├── Soldier.java ├── SoldierVisitor.java ├── Unit.java └── UnitVisitor.java /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .metadata 3 | .settings 4 | .classpath 5 | .project 6 | *.class 7 | # Package Files # 8 | *.jar 9 | *.war 10 | *.ear 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) {{{year}}} {{{fullname}}} 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | #Design pattern samples in Java. 3 | 4 | ## Build status: 5 | 6 | ![Build status](https://travis-ci.org/iluwatar/java-design-patterns.svg?branch=master) 7 | 8 | 9 | ##Abstract Factory 10 | **Intent:** Provide an interface for creating families of related or dependent objects without specifying their concrete classes. 11 | 12 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/abstract-factory/etc/abstract-factory.jpg "Abstract Factory") 13 | 14 | **Applicability:** Use the Abstract Factory pattern when 15 | * a system should be independent of how its products are created, composed and represented 16 | * a system should be configured with one of multiple families of products 17 | * a family of related product objects is designed to be used together, and you need to enforce this constraint 18 | * you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations 19 | 20 | ##Builder 21 | **Intent:** Separate the construction of a complex object from its representation so that the same construction process can create different representations. 22 | 23 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/builder/etc/builder.jpg "Builder") 24 | 25 | **Applicability:** Use the Builder pattern when 26 | * the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled 27 | * the construction process must allow different representations for the object that's constructed 28 | 29 | ##Factory Method 30 | **Intent:** Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. 31 | 32 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/factory-method/etc/factory-method.jpg "Factory Method") 33 | 34 | **Applicability:** Use the Factory Method pattern when 35 | * a class can't anticipate the class of objects it must create 36 | * a class wants its subclasses to specify the objects it creates 37 | * classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate 38 | 39 | ##Prototype 40 | **Intent:** Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. 41 | 42 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/prototype/etc/prototype.jpg "Prototype") 43 | 44 | **Applicability:** Use the Prototype pattern when a system should be independent of how its products are created, composed and represented; and 45 | * when the classes to instantiate are specified at run-time, for example, by dynamic loading; or 46 | * to avoid building a class hierarchy of factories that parallels the class hierarchy of products; or 47 | * when instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state 48 | 49 | ##Singleton 50 | **Intent:** Ensure a class only has one instance, and provide a global point of access to it. 51 | 52 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/singleton/etc/singleton.jpg "Singleton") 53 | 54 | **Applicability:** Use the Singleton pattern when 55 | * the must be exactly one instance of a class, and it must be accessible to clients from a well-known access point 56 | * when the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code 57 | 58 | ##Adapter 59 | **Intent:** Convert the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. 60 | 61 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/adapter/etc/adapter.jpg "Adapter") 62 | 63 | **Applicability:** Use the Adapter pattern when 64 | * you want to use an existing class, and its interface does not match the one you need 65 | * you want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don't necessarily have compatible interfaces 66 | * you need to use several existing subclasses, but it's impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class. 67 | 68 | ##Bridge 69 | **Intent:** Decouple an abstraction from its implementation so that the two can vary independently. 70 | 71 | 72 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/bridge/etc/bridge.jpg "Bridge") 73 | 74 | **Applicability:** Use the Bridge pattern when 75 | * you want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at run-time. 76 | * both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently 77 | * changes in the implementation of an abstraction should have no impact on clients; that is, their code should not have to be recompiled. 78 | * you have a proliferation of classes. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations" to refer to such class hierarchies 79 | * you want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class, in which multiple objects can share the same string representation. 80 | 81 | ##Composite 82 | **Intent:** Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. 83 | 84 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/composite/etc/composite.jpg "Composite") 85 | 86 | **Applicability:** Use the Composite pattern when 87 | * you want to represent part-whole hierarchies of objects 88 | * you want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will treat all objects in the composite structure uniformly 89 | 90 | ##Decorator 91 | **Intent:** Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. 92 | 93 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/decorator/etc/decorator.jpg "Decorator") 94 | 95 | **Applicability:** Use Decorator 96 | * to add responsibilities to individual objects dynamically and transparently, that is, without affecting other objects 97 | * for responsibilities that can be withdrawn 98 | * when extension by subclassing is impractical. Sometimes a large number of independent extensions are possible and would produce an explosion of sublasses to support every combination. Or a class definition may be hidden or otherwise unavailable for subclassing 99 | 100 | ##Facade 101 | **Intent:** Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. 102 | 103 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/facade/etc/facade.jpg "Facade") 104 | 105 | **Applicability:** Use the Facade pattern when 106 | * you want to provide a simple interface to a complex subsystem. Subsystems often get more complex as they evolve. Most patterns, when applied, result in more and smaller classes. This makes the subsystem more reusable and easier to customize, but is also becomes harder to use for clients that don't need to customize it. A facade can provide a simple default view of the subsystem that is good enough for most clients. Only clients needing more customizability will need to look beyond the facade. 107 | * there are many dependencies between clients and the implementation classes of an abstraction. Introduce a facade to decouple the subsystem from clients and other subsystems, thereby promoting subsystem independence and portability. 108 | * you want to layer your subsystems. Use a facade to define an entry point to each subsystem level. If subsystems are dependent, the you can simplify the dependencies between them by making them communicate with each other solely through their facades 109 | 110 | ##Flyweight 111 | **Intent:** Use sharing to support large numbers of fine-grained objects efficiently. 112 | 113 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/flyweight/etc/flyweight.jpg "Flyweight") 114 | 115 | **Applicability:** The Flyweight pattern's effectiveness depends heavily on how and where it's used. Apply the Flyweight pattern when all of the following are true 116 | * an application uses a large number of objects 117 | * storage costs are high because of the sheer quantity of objects 118 | * most object state can be made extrinsic 119 | * many groups of objects may be replaced by relatively few shared objects once extrinsic state is removed 120 | * the application doesn't depend on object identity. Since flyweight objects may be shared, identity tests will return true for conceptually distinct objects. 121 | 122 | ##Proxy 123 | **Intent:** Provide a surrogate or placeholder for another object to control access to it. 124 | 125 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/proxy/etc/proxy.jpg "Proxy") 126 | 127 | **Applicability:** Proxy is applicable whenever there is a need for a more versatile or sophisticated reference to an object than a simple pointer. here are several common situations in which the Proxy pattern is applicable 128 | * a remote proxy provides a local representative for an object in a different address space. 129 | * a virtual proxy creates expensive objects on demand. 130 | * a protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights. 131 | 132 | ##Chain of responsibility 133 | **Intent:** Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. 134 | 135 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/chain/etc/chain.jpg "Chain of Responsibility") 136 | 137 | **Applicability:** Use Chain of Responsibility when 138 | * more than one object may handle a request, and the handler isn't known a priori. The handler should be ascertained automatically 139 | * you want to issue a request to one of several objects without specifying the receiver explicitly 140 | * the set of objects that can handle a request should be specified dynamically 141 | 142 | ##Command 143 | **Intent:** Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations. 144 | 145 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/command/etc/command.jpg "Command") 146 | 147 | **Applicability:** Use the Command pattern when you want to 148 | * parameterize objects by an action to perform. You can express such parameterization in a procedural language with a callback function, that is, a function that's registered somewhere to be called at a later point. Commands are an object-oriented replacement for callbacks. 149 | * specify, queue, and execute requests at different times. A Command object can have a lifetime independent of the original request. If the receiver of a request can be represented in an address space-independent way, then you can transfer a command object for the request to a different process and fulfill the request there 150 | * support undo. The Command's execute operation can store state for reversing its effects in the command itself. The Command interface must have an added Unexecute operation that reverses the effects of a previous call to execute. Executed commands are stored in a history list. Unlimited-level undo and redo is achieved by traversing this list backwards and forwards calling unexecute and execute, respectively 151 | * support logging changes so that they can be reapplied in case of a system crash. By augmenting the Command interface with load and store operations, you can keep a persistent log of changes. Recovering from a crash involves reloading logged commands from disk and re-executing them with the execute operation 152 | * structure a system around high-level operations build on primitive operations. Such a structure is common in information systems that support transactions. A transaction encapsulates a set of changes to data. The Command pattern offers a way to model transactions. Commands have a common interface, letting you invoke all transactions the same way. The pattern also makes it easy to extend the system with new transactions 153 | 154 | ##Interpreter 155 | **Intent:** Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. 156 | 157 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/interpreter/etc/interpreter.jpg "Interpreter") 158 | 159 | **Applicability:** Use the Interpreter pattern when there is a language to interpret, and you can represent statements in the language as abstract syntax trees. The Interpreter pattern works best when 160 | * the grammar is simple. For complex grammars, the class hierarchy for the grammar becomes large and unmanageable. Tools such as parser generators are a better alternative in such cases. They can interpret expressions without building abstract syntax trees, which can save space and possibly time 161 | * efficiency is not a critical concern. The most efficient interpreters are usually not implemented by interpreting parse trees directly but by first translating them into another form. For example, regular expressions are often transformed into state machines. But even then, the translator can be implemented by the Interpreter pattern, so the pattern is still applicable 162 | 163 | ##Iterator 164 | **Intent:** Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. 165 | 166 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/iterator/etc/iterator.jpg "Iterator") 167 | 168 | **Applicability:** Use the Iterator pattern 169 | * to access an aggregate object's contents without exposing its internal representation 170 | * to support multiple traversals of aggregate objects 171 | * to provide a uniform interface for traversing different aggregate structures 172 | 173 | ##Mediator 174 | **Intent:** Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. 175 | 176 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/mediator/etc/mediator.jpg "Mediator") 177 | 178 | **Applicability:** Use the Mediator pattern when 179 | * a set of objects communicate in well-defined but complex ways. The resulting interdependencies are unstructured and difficult to understand 180 | * reusing an object is difficult because it refers to and communicates with many other objects 181 | * a behavior that's distributed between several classes should be customizable without a lot of subclassing 182 | 183 | ##Memento 184 | **Intent:** Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later. 185 | 186 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/memento/etc/memento.jpg "Memento") 187 | 188 | **Applicability:** Use the Memento pattern when 189 | * a snapshot of an object's state must be saved so that it can be restored to that state later, and 190 | * a direct interface to obtaining the state would expose implementation details and break the object's encapsulation 191 | 192 | ##Observer 193 | **Intent:** Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. 194 | 195 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/observer/etc/observer.jpg "Observer") 196 | 197 | **Applicability:** Use the Observer pattern in any of the following situations 198 | * when an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects lets you vary and reuse them independently 199 | * when a change to one object requires changing others, and you don't know how many objects need to be changed 200 | * when an object should be able to notify other objects without making assumptions about who these objects are. In other words, you don't want these objects tightly coupled 201 | 202 | ##State 203 | **Intent:** Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. 204 | 205 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/state/etc/state.jpg "State") 206 | 207 | **Applicability:** Use the State pattern in either of the following cases 208 | * an object's behavior depends on its state, and it must change its behavior at run-time depending on that state 209 | * operations have large, multipart conditional statements that depend on the object's state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects. 210 | 211 | ##Strategy 212 | **Intent:** Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. 213 | 214 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/strategy/etc/strategy.jpg "Strategy") 215 | 216 | **Applicability:** Use the Strategy pattern when 217 | * many related classes differ only in their behavior. Stratefies provide a way to configure a class eith one of many behaviors 218 | * you need different variants of an algorithm. for example, you migh define algorithms reflecting different space/time trade-offs. Strategies can be used when these variants are implemented as a class hierarchy of algorithms 219 | * an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures 220 | * a class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class 221 | 222 | ##Template method 223 | **Intent:** Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. 224 | 225 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/template-method/etc/template-method.jpg "Template Method") 226 | 227 | **Applicability:** The Template Method pattern should be used 228 | * to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary 229 | * when common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is good example of "refactoring to generalize" as described by Opdyke and Johnson. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations 230 | * to control subclasses extensions. You can define a template method that calls "hook" operations at specific points, thereby permitting extensions only at those points 231 | 232 | ##Visitor 233 | **Intent:** Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. 234 | 235 | ![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/visitor/etc/visitor.jpg "Visitor") 236 | 237 | **Applicability:** Use the Visitor pattern when 238 | * an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes 239 | * many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them 240 | * the classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes 241 | 242 | 243 | 244 | # Frequently asked questions 245 | 246 | **Q: What is the difference between State and Strategy patterns?** 247 | 248 | While the implementation is similar they solve different problems. The State pattern deals with what state an object is in - it encapsulates state-dependent behavior. The Strategy pattern deals with how an object performs a certain task - it encapsulates an algorithm. 249 | 250 | **Q: What is the difference between Strategy and Template Method patterns?** 251 | 252 | In Template Method the algorithm is chosen at compile time via inheritance. With Strategy pattern the algorithm is chosen at runtime via composition. 253 | 254 | **Q: What is the difference between Proxy and Decorator patterns?** 255 | 256 | The difference is the intent of the patterns. While Proxy controls access to the object Decorator is used to add responsibilities to the object. 257 | 258 | 259 | 260 | # How to contribute 261 | 262 | For a new pattern to be added you need to do the following steps: 263 | 264 | 1. Fork the repository. 265 | 2. Implement the code changes in your fork. Remember to add sufficient comments documenting the implementation. 266 | 3. Create a simple class diagram from your example code. I've used [GenMyModel](https://www.genmymodel.com/) and its "Export as JPEG" feature. 267 | 4. Add description of the pattern in README.md and link to the class diagram. 268 | 5. Create a pull request. 269 | 270 | 271 | 272 | # Credits 273 | 274 | * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) 275 | * [Effective Java (2nd Edition)](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683) 276 | 277 | 278 | 279 | # License 280 | 281 | This project is licensed under the terms of the MIT license. 282 | -------------------------------------------------------------------------------- /abstract-factory/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /abstract-factory/etc/abstract-factory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/abstract-factory/etc/abstract-factory.jpg -------------------------------------------------------------------------------- /abstract-factory/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | abstract-factory 12 | 1.0-SNAPSHOT 13 | abstract-factory 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * The essence of the Abstract Factory pattern is a factory interface (KingdomFactory) 6 | * and its implementations (ElfKingdomFactory, OrcKingdomFactory). 7 | * 8 | * The example uses both concrete implementations to create a king, a castle and an 9 | * army. 10 | * 11 | */ 12 | public class App 13 | { 14 | public static void main( String[] args ) 15 | { 16 | createKingdom(new ElfKingdomFactory()); 17 | createKingdom(new OrcKingdomFactory()); 18 | } 19 | 20 | public static void createKingdom(KingdomFactory factory) { 21 | King king = factory.createKing(); 22 | Castle castle = factory.createCastle(); 23 | Army army = factory.createArmy(); 24 | System.out.println("The kingdom was created."); 25 | System.out.println(king); 26 | System.out.println(castle); 27 | System.out.println(army); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/Army.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public interface Army { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/Castle.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public interface Castle { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/ElfArmy.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class ElfArmy implements Army { 4 | 5 | @Override 6 | public String toString() { 7 | return "This is the Elven Army!"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/ElfCastle.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class ElfCastle implements Castle { 4 | 5 | @Override 6 | public String toString() { 7 | return "This is the Elven castle!"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/ElfKing.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class ElfKing implements King { 4 | 5 | @Override 6 | public String toString() { 7 | return "This is the Elven king!"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/ElfKingdomFactory.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Concrete factory. 6 | * 7 | */ 8 | public class ElfKingdomFactory implements KingdomFactory { 9 | 10 | public Castle createCastle() { 11 | return new ElfCastle(); 12 | } 13 | 14 | public King createKing() { 15 | return new ElfKing(); 16 | } 17 | 18 | public Army createArmy() { 19 | return new ElfArmy(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/King.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public interface King { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/KingdomFactory.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * The factory interface. 6 | * 7 | */ 8 | public interface KingdomFactory { 9 | 10 | Castle createCastle(); 11 | King createKing(); 12 | Army createArmy(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/OrcArmy.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcArmy implements Army { 4 | 5 | @Override 6 | public String toString() { 7 | return "This is the Orcish Army!"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/OrcCastle.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcCastle implements Castle { 4 | 5 | @Override 6 | public String toString() { 7 | return "This is the Orcish castle!"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/OrcKing.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcKing implements King { 4 | 5 | @Override 6 | public String toString() { 7 | return "This is the Orc king!"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /abstract-factory/src/main/java/com/iluwatar/OrcKingdomFactory.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Concrete factory. 6 | * 7 | */ 8 | public class OrcKingdomFactory implements KingdomFactory { 9 | 10 | public Castle createCastle() { 11 | return new OrcCastle(); 12 | } 13 | 14 | public King createKing() { 15 | return new OrcKing(); 16 | } 17 | 18 | public Army createArmy() { 19 | return new OrcArmy(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /adapter/etc/adapter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/adapter/etc/adapter.jpg -------------------------------------------------------------------------------- /adapter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | adapter 12 | 1.0-SNAPSHOT 13 | adapter 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /adapter/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * There are two variations of the Adapter pattern: The 6 | * class adapter implements the adaptee's interface whereas 7 | * the object adapter uses composition to contain the adaptee 8 | * in the adapter object. This example uses the object adapter 9 | * approach. 10 | * 11 | * The Adapter (GnomeEngineer) converts the interface of the 12 | * target class (GoblinGlider) into a suitable one expected 13 | * by the client (GnomeEngineeringManager). 14 | * 15 | */ 16 | public class App 17 | { 18 | public static void main( String[] args ) 19 | { 20 | GnomeEngineeringManager manager = new GnomeEngineeringManager(); 21 | manager.operateDevice(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /adapter/src/main/java/com/iluwatar/Engineer.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Engineers can operate devices. 6 | * 7 | */ 8 | public interface Engineer { 9 | 10 | void operateDevice(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /adapter/src/main/java/com/iluwatar/GnomeEngineer.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Adapter class. Adapts the interface of the device 6 | * (GoblinGlider) into Engineer interface expected 7 | * by the client (GnomeEngineeringManager). 8 | * 9 | */ 10 | public class GnomeEngineer implements Engineer { 11 | 12 | private GoblinGlider glider; 13 | 14 | public GnomeEngineer() { 15 | glider = new GoblinGlider(); 16 | } 17 | 18 | @Override 19 | public void operateDevice() { 20 | glider.attachGlider(); 21 | glider.gainSpeed(); 22 | glider.takeOff(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /adapter/src/main/java/com/iluwatar/GnomeEngineeringManager.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * GnomeEngineering manager uses Engineer to 6 | * operate devices. 7 | * 8 | */ 9 | public class GnomeEngineeringManager implements Engineer { 10 | 11 | private Engineer engineer; 12 | 13 | public GnomeEngineeringManager() { 14 | engineer = new GnomeEngineer(); 15 | } 16 | 17 | @Override 18 | public void operateDevice() { 19 | engineer.operateDevice(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /adapter/src/main/java/com/iluwatar/GoblinGlider.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Device class (adaptee in the pattern). 6 | * 7 | */ 8 | public class GoblinGlider { 9 | 10 | public void attachGlider() { 11 | System.out.println("Glider attached."); 12 | } 13 | 14 | public void gainSpeed() { 15 | System.out.println("Gaining speed."); 16 | } 17 | 18 | public void takeOff() { 19 | System.out.println("Lift-off!"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /bridge/etc/bridge.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/bridge/etc/bridge.jpg -------------------------------------------------------------------------------- /bridge/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | bridge 12 | 1.0-SNAPSHOT 13 | bridge 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * In Bridge pattern both abstraction (MagicWeapon) 6 | * and implementation (MagicWeaponImp) have their 7 | * own class hierarchies. The interface of the 8 | * implementations can be changed without affecting 9 | * the clients. 10 | * 11 | */ 12 | public class App 13 | { 14 | public static void main( String[] args ) 15 | { 16 | BlindingMagicWeapon blindingMagicWeapon = new BlindingMagicWeapon(new Excalibur()); 17 | blindingMagicWeapon.wield(); 18 | blindingMagicWeapon.blind(); 19 | blindingMagicWeapon.swing(); 20 | blindingMagicWeapon.unwield(); 21 | 22 | FlyingMagicWeapon flyingMagicWeapon = new FlyingMagicWeapon(new Mjollnir()); 23 | flyingMagicWeapon.wield(); 24 | flyingMagicWeapon.fly(); 25 | flyingMagicWeapon.swing(); 26 | flyingMagicWeapon.unwield(); 27 | 28 | SoulEatingMagicWeapon soulEatingMagicWeapon = new SoulEatingMagicWeapon(new Stormbringer()); 29 | soulEatingMagicWeapon.wield(); 30 | soulEatingMagicWeapon.swing(); 31 | soulEatingMagicWeapon.eatSoul(); 32 | soulEatingMagicWeapon.unwield(); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/BlindingMagicWeapon.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class BlindingMagicWeapon extends MagicWeapon { 4 | 5 | public BlindingMagicWeapon(BlindingMagicWeaponImp imp) { 6 | super(imp); 7 | } 8 | 9 | @Override 10 | public BlindingMagicWeaponImp getImp() { 11 | return (BlindingMagicWeaponImp) imp; 12 | } 13 | 14 | @Override 15 | public void wield() { 16 | getImp().wieldImp(); 17 | } 18 | 19 | @Override 20 | public void swing() { 21 | getImp().swingImp(); 22 | } 23 | 24 | @Override 25 | public void unwield() { 26 | getImp().unwieldImp(); 27 | } 28 | 29 | public void blind() { 30 | getImp().blindImp(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/BlindingMagicWeaponImp.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class BlindingMagicWeaponImp extends MagicWeaponImp { 4 | 5 | public abstract void blindImp(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/Excalibur.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Excalibur extends BlindingMagicWeaponImp { 4 | 5 | @Override 6 | public void wieldImp() { 7 | System.out.println("wielding Excalibur"); 8 | } 9 | 10 | @Override 11 | public void swingImp() { 12 | System.out.println("swinging Excalibur"); 13 | } 14 | 15 | @Override 16 | public void unwieldImp() { 17 | System.out.println("unwielding Excalibur"); 18 | } 19 | 20 | @Override 21 | public void blindImp() { 22 | System.out.println("bright light streams from Excalibur blinding the enemy"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/FlyingMagicWeapon.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class FlyingMagicWeapon extends MagicWeapon { 4 | 5 | public FlyingMagicWeapon(FlyingMagicWeaponImp imp) { 6 | super(imp); 7 | } 8 | 9 | public FlyingMagicWeaponImp getImp() { 10 | return (FlyingMagicWeaponImp) imp; 11 | } 12 | 13 | @Override 14 | public void wield() { 15 | getImp().wieldImp(); 16 | } 17 | 18 | @Override 19 | public void swing() { 20 | getImp().swingImp(); 21 | } 22 | 23 | @Override 24 | public void unwield() { 25 | getImp().unwieldImp(); 26 | } 27 | 28 | public void fly() { 29 | getImp().flyImp(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/FlyingMagicWeaponImp.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class FlyingMagicWeaponImp extends MagicWeaponImp { 4 | 5 | public abstract void flyImp(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/MagicWeapon.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Abstraction interface. 6 | * 7 | */ 8 | public abstract class MagicWeapon { 9 | 10 | protected MagicWeaponImp imp; 11 | 12 | public MagicWeapon(MagicWeaponImp imp) { 13 | this.imp = imp; 14 | } 15 | 16 | public abstract void wield(); 17 | 18 | public abstract void swing(); 19 | 20 | public abstract void unwield(); 21 | 22 | public MagicWeaponImp getImp() { 23 | return imp; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/MagicWeaponImp.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Implementation interface. 6 | * 7 | */ 8 | public abstract class MagicWeaponImp { 9 | 10 | public abstract void wieldImp(); 11 | 12 | public abstract void swingImp(); 13 | 14 | public abstract void unwieldImp(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/Mjollnir.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Mjollnir extends FlyingMagicWeaponImp { 4 | 5 | @Override 6 | public void wieldImp() { 7 | System.out.println("wielding Mjollnir"); 8 | } 9 | 10 | @Override 11 | public void swingImp() { 12 | System.out.println("swinging Mjollnir"); 13 | } 14 | 15 | @Override 16 | public void unwieldImp() { 17 | System.out.println("unwielding Mjollnir"); 18 | } 19 | 20 | @Override 21 | public void flyImp() { 22 | System.out.println("Mjollnir hits the enemy in the air and returns back to the owner's hand"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/SoulEatingMagicWeapon.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class SoulEatingMagicWeapon extends MagicWeapon { 4 | 5 | public SoulEatingMagicWeapon(SoulEatingMagicWeaponImp imp) { 6 | super(imp); 7 | } 8 | 9 | @Override 10 | public SoulEatingMagicWeaponImp getImp() { 11 | return (SoulEatingMagicWeaponImp) imp; 12 | } 13 | 14 | @Override 15 | public void wield() { 16 | getImp().wieldImp(); 17 | } 18 | 19 | @Override 20 | public void swing() { 21 | getImp().swingImp(); 22 | } 23 | 24 | @Override 25 | public void unwield() { 26 | getImp().unwieldImp(); 27 | } 28 | 29 | public void eatSoul() { 30 | getImp().eatSoulImp(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/SoulEatingMagicWeaponImp.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class SoulEatingMagicWeaponImp extends MagicWeaponImp { 4 | 5 | public abstract void eatSoulImp(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /bridge/src/main/java/com/iluwatar/Stormbringer.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Stormbringer extends SoulEatingMagicWeaponImp { 4 | 5 | @Override 6 | public void wieldImp() { 7 | System.out.println("wielding Stormbringer"); 8 | } 9 | 10 | @Override 11 | public void swingImp() { 12 | System.out.println("swinging Stormbringer"); 13 | } 14 | 15 | @Override 16 | public void unwieldImp() { 17 | System.out.println("unwielding Stormbringer"); 18 | } 19 | 20 | @Override 21 | public void eatSoulImp() { 22 | System.out.println("Stormbringer devours the enemy's soul"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /builder/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /builder/etc/builder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/builder/etc/builder.jpg -------------------------------------------------------------------------------- /builder/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | builder 12 | 1.0-SNAPSHOT 13 | builder 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /builder/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import com.iluwatar.Hero.HeroBuilder; 4 | 5 | /** 6 | * 7 | * This is the Builder pattern variation as described by 8 | * Joshua Bloch in Effective Java 2nd Edition. 9 | * 10 | * We want to build Hero objects, but its construction 11 | * is complex because of the many parameters needed. To 12 | * aid the user we introduce HeroBuilder class. HeroBuilder 13 | * takes the minimum parameters to build Hero object in 14 | * its constructor. After that additional configuration 15 | * for the Hero object can be done using the fluent 16 | * HeroBuilder interface. When configuration is ready 17 | * the build method is called to receive the final Hero 18 | * object. 19 | * 20 | */ 21 | public class App 22 | { 23 | public static void main( String[] args ) 24 | { 25 | 26 | Hero mage = new HeroBuilder(Profession.MAGE, "Riobard") 27 | .withHairColor(HairColor.BLACK) 28 | .withWeapon(Weapon.DAGGER) 29 | .build(); 30 | System.out.println(mage); 31 | 32 | Hero warrior = new HeroBuilder(Profession.WARRIOR, "Amberjill") 33 | .withHairColor(HairColor.BLOND) 34 | .withHairType(HairType.LONG_CURLY) 35 | .withArmor(Armor.CHAIN_MAIL) 36 | .withWeapon(Weapon.SWORD) 37 | .build(); 38 | System.out.println(warrior); 39 | 40 | Hero thief = new HeroBuilder(Profession.THIEF, "Desmond") 41 | .withHairType(HairType.BOLD) 42 | .withWeapon(Weapon.BOW) 43 | .build(); 44 | System.out.println(thief); 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /builder/src/main/java/com/iluwatar/Armor.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum Armor { 4 | 5 | CLOTHES, LEATHER, CHAIN_MAIL, PLATE_MAIL; 6 | 7 | @Override 8 | public String toString() { 9 | String s = ""; 10 | switch(this) { 11 | case CLOTHES: s = "clothes"; break; 12 | case LEATHER: s = "leather armor"; break; 13 | case CHAIN_MAIL: s = "chain mail"; break; 14 | case PLATE_MAIL: s = "plate mail"; break; 15 | } 16 | return s; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /builder/src/main/java/com/iluwatar/HairColor.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum HairColor { 4 | 5 | WHITE, BLOND, RED, BROWN, BLACK; 6 | 7 | @Override 8 | public String toString() { 9 | String s = ""; 10 | switch(this) { 11 | case WHITE: s = "white"; break; 12 | case BLOND: s = "blond"; break; 13 | case RED: s = "red"; break; 14 | case BROWN: s = "brown"; break; 15 | case BLACK: s = "black"; break; 16 | } 17 | return s; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /builder/src/main/java/com/iluwatar/HairType.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum HairType { 4 | 5 | BOLD, SHORT, CURLY, LONG_STRAIGHT, LONG_CURLY; 6 | 7 | @Override 8 | public String toString() { 9 | String s = ""; 10 | switch(this) { 11 | case BOLD: s = "bold"; break; 12 | case SHORT: s = "short"; break; 13 | case CURLY: s = "curly"; break; 14 | case LONG_STRAIGHT: s = "long straight"; break; 15 | case LONG_CURLY: s = "long curly"; break; 16 | } 17 | return s; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /builder/src/main/java/com/iluwatar/Hero.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * The class with many parameters. 6 | * 7 | */ 8 | public class Hero { 9 | 10 | private final Profession profession; 11 | private final String name; 12 | private final HairType hairType; 13 | private final HairColor hairColor; 14 | private final Armor armor; 15 | private final Weapon weapon; 16 | 17 | public Profession getProfession() { 18 | return profession; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public HairType getHairType() { 26 | return hairType; 27 | } 28 | 29 | public HairColor getHairColor() { 30 | return hairColor; 31 | } 32 | 33 | public Armor getArmor() { 34 | return armor; 35 | } 36 | 37 | public Weapon getWeapon() { 38 | return weapon; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | 44 | StringBuilder sb = new StringBuilder(); 45 | sb.append(profession); 46 | sb.append(" named "); 47 | sb.append(name); 48 | if (hairColor != null || hairType != null) { 49 | sb.append(" with "); 50 | if (hairColor != null) { 51 | sb.append(hairColor); 52 | sb.append(" "); 53 | } 54 | if (hairType != null) { 55 | sb.append(hairType); 56 | sb.append(" "); 57 | } 58 | sb.append(hairType != HairType.BOLD ? "hair" : "head"); 59 | } 60 | if (armor != null) { 61 | sb.append(" wearing "); 62 | sb.append(armor); 63 | } 64 | if (weapon != null) { 65 | sb.append(" and wielding "); 66 | sb.append(weapon); 67 | } 68 | sb.append("."); 69 | return sb.toString(); 70 | } 71 | 72 | private Hero(HeroBuilder builder) { 73 | this.profession = builder.profession; 74 | this.name = builder.name; 75 | this.hairColor = builder.hairColor; 76 | this.hairType = builder.hairType; 77 | this.weapon = builder.weapon; 78 | this.armor = builder.armor; 79 | } 80 | 81 | /** 82 | * 83 | * The builder class. 84 | * 85 | */ 86 | public static class HeroBuilder { 87 | 88 | private final Profession profession; 89 | private final String name; 90 | private HairType hairType; 91 | private HairColor hairColor; 92 | private Armor armor; 93 | private Weapon weapon; 94 | 95 | public HeroBuilder(Profession profession, String name) { 96 | if (profession == null || name == null) { 97 | throw new NullPointerException("profession and name can not be null"); 98 | } 99 | this.profession = profession; 100 | this.name = name; 101 | } 102 | 103 | public HeroBuilder withHairType(HairType hairType) { 104 | this.hairType = hairType; 105 | return this; 106 | } 107 | 108 | public HeroBuilder withHairColor(HairColor hairColor) { 109 | this.hairColor = hairColor; 110 | return this; 111 | } 112 | 113 | public HeroBuilder withArmor(Armor armor) { 114 | this.armor = armor; 115 | return this; 116 | } 117 | 118 | public HeroBuilder withWeapon(Weapon weapon) { 119 | this.weapon = weapon; 120 | return this; 121 | } 122 | 123 | public Hero build() { 124 | return new Hero(this); 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /builder/src/main/java/com/iluwatar/Profession.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum Profession { 4 | 5 | WARRIOR, THIEF, MAGE, PRIEST; 6 | 7 | @Override 8 | public String toString() { 9 | String s = ""; 10 | switch(this) { 11 | case WARRIOR: s = "Warrior"; break; 12 | case THIEF: s = "Thief"; break; 13 | case MAGE: s = "Mage"; break; 14 | case PRIEST: s = "Priest"; break; 15 | } 16 | return s; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /builder/src/main/java/com/iluwatar/Weapon.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum Weapon { 4 | 5 | DAGGER, SWORD, AXE, WARHAMMER, BOW; 6 | 7 | @Override 8 | public String toString() { 9 | String s = ""; 10 | switch(this) { 11 | case DAGGER: s = "dagger"; break; 12 | case SWORD: s = "sword"; break; 13 | case AXE: s = "axe"; break; 14 | case WARHAMMER: s = "warhammer"; break; 15 | case BOW: s = "bow"; break; 16 | } 17 | return s; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /chain/etc/chain.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/chain/etc/chain.jpg -------------------------------------------------------------------------------- /chain/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | chain 12 | 1.0-SNAPSHOT 13 | chain 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /chain/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Chain of Responsibility organizes request handlers (RequestHandler) into 6 | * a chain where each handler has a chance to act on the request on its 7 | * turn. In this example the king (OrcKing) makes requests and the military 8 | * orcs (OrcCommander, OrcOfficer, OrcSoldier) form the handler chain. 9 | * 10 | */ 11 | public class App 12 | { 13 | public static void main( String[] args ) 14 | { 15 | 16 | OrcKing king = new OrcKing(); 17 | king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle")); 18 | king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner")); 19 | king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax")); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /chain/src/main/java/com/iluwatar/OrcCommander.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcCommander extends RequestHandler { 4 | 5 | public OrcCommander(RequestHandler handler) { 6 | super(handler); 7 | } 8 | 9 | @Override 10 | public void handleRequest(Request req) { 11 | if (req.getRequestType().equals(RequestType.DEFEND_CASTLE)) { 12 | printHandling(req); 13 | } else { 14 | super.handleRequest(req); 15 | } 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "Orc commander"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /chain/src/main/java/com/iluwatar/OrcKing.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Makes requests that are handled by the chain. 6 | * 7 | */ 8 | public class OrcKing { 9 | 10 | RequestHandler chain; 11 | 12 | public OrcKing() { 13 | buildChain(); 14 | } 15 | 16 | private void buildChain() { 17 | chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null))); 18 | } 19 | 20 | public void makeRequest(Request req) { 21 | chain.handleRequest(req); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /chain/src/main/java/com/iluwatar/OrcOfficer.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcOfficer extends RequestHandler { 4 | 5 | public OrcOfficer(RequestHandler handler) { 6 | super(handler); 7 | } 8 | 9 | @Override 10 | public void handleRequest(Request req) { 11 | if (req.getRequestType().equals(RequestType.TORTURE_PRISONER)) { 12 | printHandling(req); 13 | } else { 14 | super.handleRequest(req); 15 | } 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "Orc officer"; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /chain/src/main/java/com/iluwatar/OrcSoldier.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcSoldier extends RequestHandler { 4 | 5 | public OrcSoldier(RequestHandler handler) { 6 | super(handler); 7 | } 8 | 9 | @Override 10 | public void handleRequest(Request req) { 11 | if (req.getRequestType().equals(RequestType.COLLECT_TAX)) { 12 | printHandling(req); 13 | } else { 14 | super.handleRequest(req); 15 | } 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "Orc soldier"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /chain/src/main/java/com/iluwatar/Request.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Request { 4 | 5 | private String requestDescription; 6 | private RequestType requestType; 7 | 8 | public Request(RequestType requestType, String requestDescription) { 9 | this.setRequestType(requestType); 10 | this.setRequestDescription(requestDescription); 11 | } 12 | 13 | public String getRequestDescription() { 14 | return requestDescription; 15 | } 16 | 17 | public void setRequestDescription(String requestDescription) { 18 | this.requestDescription = requestDescription; 19 | } 20 | 21 | public RequestType getRequestType() { 22 | return requestType; 23 | } 24 | 25 | public void setRequestType(RequestType requestType) { 26 | this.requestType = requestType; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return getRequestDescription(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /chain/src/main/java/com/iluwatar/RequestHandler.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class RequestHandler { 4 | 5 | private RequestHandler next; 6 | 7 | public RequestHandler(RequestHandler next) { 8 | this.next = next; 9 | } 10 | 11 | public void handleRequest(Request req) { 12 | if (next != null) { 13 | next.handleRequest(req); 14 | } 15 | } 16 | 17 | protected void printHandling(Request req) { 18 | System.out.println(this + " handling request \"" + req + "\""); 19 | } 20 | 21 | @Override 22 | public abstract String toString(); 23 | } 24 | -------------------------------------------------------------------------------- /chain/src/main/java/com/iluwatar/RequestType.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum RequestType { 4 | 5 | DEFEND_CASTLE, 6 | TORTURE_PRISONER, 7 | COLLECT_TAX 8 | 9 | } 10 | -------------------------------------------------------------------------------- /command/etc/command.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/command/etc/command.jpg -------------------------------------------------------------------------------- /command/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | command 12 | 1.0-SNAPSHOT 13 | command 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /command/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * In Command pattern actions are objects that can 6 | * be executed and undone. The commands in this example 7 | * are spells cast by the wizard on the goblin. 8 | * 9 | */ 10 | public class App 11 | { 12 | public static void main( String[] args ) 13 | { 14 | Wizard wizard = new Wizard(); 15 | Goblin goblin = new Goblin(); 16 | 17 | goblin.printStatus(); 18 | 19 | wizard.castSpell(new ShrinkSpell(), goblin); 20 | goblin.printStatus(); 21 | 22 | wizard.castSpell(new InvisibilitySpell(), goblin); 23 | goblin.printStatus(); 24 | wizard.undoLastSpell(); 25 | goblin.printStatus(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /command/src/main/java/com/iluwatar/Command.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Interface for spells. 6 | * 7 | */ 8 | public abstract class Command { 9 | 10 | public abstract void execute(Target target); 11 | 12 | public abstract void undo(); 13 | 14 | @Override 15 | public abstract String toString(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /command/src/main/java/com/iluwatar/Goblin.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Goblin extends Target { 4 | 5 | public Goblin() { 6 | this.setSize(Size.NORMAL); 7 | this.setVisibility(Visibility.VISIBLE); 8 | } 9 | 10 | @Override 11 | public String toString() { 12 | return "Goblin"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /command/src/main/java/com/iluwatar/InvisibilitySpell.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class InvisibilitySpell extends Command { 4 | 5 | private Target target; 6 | 7 | public InvisibilitySpell() { 8 | target = null; 9 | } 10 | 11 | @Override 12 | public void execute(Target target) { 13 | target.setVisibility(Visibility.INVISIBLE); 14 | this.target = target; 15 | } 16 | 17 | @Override 18 | public void undo() { 19 | if (target != null) { 20 | target.setVisibility(Visibility.VISIBLE); 21 | } 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Invisibility spell"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /command/src/main/java/com/iluwatar/ShrinkSpell.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class ShrinkSpell extends Command { 4 | 5 | private Size oldSize; 6 | 7 | private Target target; 8 | 9 | public ShrinkSpell() { 10 | oldSize = null; 11 | target = null; 12 | } 13 | 14 | @Override 15 | public void execute(Target target) { 16 | oldSize = target.getSize(); 17 | target.setSize(Size.SMALL); 18 | this.target = target; 19 | } 20 | 21 | @Override 22 | public void undo() { 23 | if (oldSize != null && target != null) { 24 | target.setSize(oldSize); 25 | } 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "Shrink spell"; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /command/src/main/java/com/iluwatar/Size.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum Size { 4 | 5 | SMALL, 6 | NORMAL, 7 | LARGE; 8 | 9 | @Override 10 | public String toString() { 11 | 12 | String s = ""; 13 | 14 | switch (this) { 15 | case LARGE: 16 | s = "large"; 17 | break; 18 | case NORMAL: 19 | s = "normal"; 20 | break; 21 | case SMALL: 22 | s = "small"; 23 | break; 24 | default: 25 | break; 26 | } 27 | return s; 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /command/src/main/java/com/iluwatar/Target.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class Target { 4 | 5 | private Size size; 6 | 7 | private Visibility visibility; 8 | 9 | public Size getSize() { 10 | return size; 11 | } 12 | 13 | public void setSize(Size size) { 14 | this.size = size; 15 | } 16 | 17 | public Visibility getVisibility() { 18 | return visibility; 19 | } 20 | 21 | public void setVisibility(Visibility visibility) { 22 | this.visibility = visibility; 23 | } 24 | 25 | @Override 26 | public abstract String toString(); 27 | 28 | public void printStatus() { 29 | System.out.println(String.format("%s, size=%s visibility=%s", this, getSize(), getVisibility())); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /command/src/main/java/com/iluwatar/Visibility.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum Visibility { 4 | 5 | VISIBLE, 6 | INVISIBLE; 7 | 8 | @Override 9 | public String toString() { 10 | 11 | String s = ""; 12 | 13 | switch (this) { 14 | case INVISIBLE: 15 | s = "invisible"; 16 | break; 17 | case VISIBLE: 18 | s = "visible"; 19 | break; 20 | default: 21 | break; 22 | 23 | } 24 | return s; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /command/src/main/java/com/iluwatar/Wizard.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Wizard extends Target { 4 | 5 | private Command previousSpell; 6 | 7 | public Wizard() { 8 | this.setSize(Size.NORMAL); 9 | this.setVisibility(Visibility.VISIBLE); 10 | previousSpell = null; 11 | } 12 | 13 | public void castSpell(Command command, Target target) { 14 | System.out.println(this + " casts " + command + " at " + target); 15 | command.execute(target); 16 | previousSpell = command; 17 | } 18 | 19 | public void undoLastSpell() { 20 | if (previousSpell != null) { 21 | System.out.println(this + " undoes " + previousSpell); 22 | previousSpell.undo(); 23 | } 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return "Wizard"; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /composite/etc/composite.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/composite/etc/composite.jpg -------------------------------------------------------------------------------- /composite/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | composite 12 | 1.0-SNAPSHOT 13 | composite 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /composite/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * With Composite we can treat tree hierarchies of objects 6 | * with uniform interface (LetterComposite). In this example 7 | * we have sentences composed of words composed of letters. 8 | * 9 | */ 10 | public class App 11 | { 12 | public static void main( String[] args ) 13 | { 14 | System.out.println("Message from the orcs: "); 15 | 16 | LetterComposite orcMessage = new Messenger().messageFromOrcs(); 17 | orcMessage.print(); 18 | 19 | System.out.println("\n"); 20 | 21 | System.out.println("Message from the elves: "); 22 | 23 | LetterComposite elfMessage = new Messenger().messageFromElves(); 24 | elfMessage.print(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /composite/src/main/java/com/iluwatar/Letter.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Letter extends LetterComposite { 4 | 5 | private char c; 6 | 7 | public Letter(char c) { 8 | this.c = c; 9 | } 10 | 11 | @Override 12 | protected void printThisBefore() { 13 | System.out.print(c); 14 | } 15 | 16 | @Override 17 | protected void printThisAfter() { 18 | // nop 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /composite/src/main/java/com/iluwatar/LetterComposite.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 8 | * Composite interface. 9 | * 10 | */ 11 | public abstract class LetterComposite { 12 | 13 | private List children = new ArrayList(); 14 | 15 | public void add(LetterComposite letter) { 16 | children.add(letter); 17 | } 18 | 19 | public int count() { 20 | return children.size(); 21 | } 22 | 23 | protected abstract void printThisBefore(); 24 | 25 | protected abstract void printThisAfter(); 26 | 27 | public void print() { 28 | printThisBefore(); 29 | for (LetterComposite letter: children) { 30 | letter.print(); 31 | } 32 | printThisAfter(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /composite/src/main/java/com/iluwatar/Messenger.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | public class Messenger { 8 | 9 | LetterComposite messageFromOrcs() { 10 | 11 | List words = new ArrayList(); 12 | 13 | words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e')))); 14 | words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e')))); 15 | words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s')))); 16 | words.add(new Word(Arrays.asList(new Letter('a')))); 17 | words.add(new Word(Arrays.asList(new Letter('w'), new Letter('h'), new Letter('i'), new Letter('p')))); 18 | words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e')))); 19 | words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s')))); 20 | words.add(new Word(Arrays.asList(new Letter('a')))); 21 | words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'), new Letter('y')))); 22 | 23 | return new Sentence(words); 24 | 25 | } 26 | 27 | LetterComposite messageFromElves() { 28 | 29 | List words = new ArrayList(); 30 | 31 | words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'), new Letter('c'), new Letter('h')))); 32 | words.add(new Word(Arrays.asList(new Letter('w'), new Letter('i'), new Letter('n'), new Letter('d')))); 33 | words.add(new Word(Arrays.asList(new Letter('p'), new Letter('o'), new Letter('u'), new Letter('r'), new Letter('s')))); 34 | words.add(new Word(Arrays.asList(new Letter('f'), new Letter('r'), new Letter('o'), new Letter('m')))); 35 | words.add(new Word(Arrays.asList(new Letter('y'), new Letter('o'), new Letter('u'), new Letter('r')))); 36 | words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'), new Letter('u'), new Letter('t'), new Letter('h')))); 37 | 38 | return new Sentence(words); 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /composite/src/main/java/com/iluwatar/Sentence.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.List; 4 | 5 | public class Sentence extends LetterComposite { 6 | 7 | public Sentence(List words) { 8 | for (Word w: words) { 9 | this.add(w); 10 | } 11 | } 12 | 13 | @Override 14 | protected void printThisBefore() { 15 | // nop 16 | } 17 | 18 | @Override 19 | protected void printThisAfter() { 20 | System.out.print("."); 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /composite/src/main/java/com/iluwatar/Word.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.List; 4 | 5 | public class Word extends LetterComposite { 6 | 7 | public Word(List letters) { 8 | for (Letter l: letters) { 9 | this.add(l); 10 | } 11 | } 12 | 13 | @Override 14 | protected void printThisBefore() { 15 | System.out.print(" "); 16 | } 17 | 18 | @Override 19 | protected void printThisAfter() { 20 | // nop 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /decorator/etc/decorator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/decorator/etc/decorator.jpg -------------------------------------------------------------------------------- /decorator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | decorator 12 | 1.0-SNAPSHOT 13 | decorator 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /decorator/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Decorator pattern is more flexible alternative to 6 | * subclassing. The decorator class implements the same 7 | * interface as the target and uses composition to 8 | * "decorate" calls to the target. 9 | * 10 | */ 11 | public class App 12 | { 13 | public static void main( String[] args ) 14 | { 15 | 16 | System.out.println("A simple looking troll approaches."); 17 | Hostile troll = new Troll(); 18 | troll.attack(); 19 | troll.fleeBattle(); 20 | 21 | System.out.println("\nA smart looking troll surprises you."); 22 | Hostile smart = new SmartTroll(new Troll()); 23 | smart.attack(); 24 | smart.fleeBattle(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /decorator/src/main/java/com/iluwatar/Hostile.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public interface Hostile { 4 | 5 | void attack(); 6 | void fleeBattle(); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /decorator/src/main/java/com/iluwatar/SmartTroll.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class SmartTroll implements Hostile { 4 | 5 | private Hostile decorated; 6 | 7 | public SmartTroll(Hostile decorated) { 8 | this.decorated = decorated; 9 | } 10 | 11 | @Override 12 | public void attack() { 13 | System.out.println("The troll throws a rock at you!"); 14 | decorated.attack(); 15 | } 16 | 17 | @Override 18 | public void fleeBattle() { 19 | System.out.println("The troll calls for help!"); 20 | decorated.fleeBattle(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /decorator/src/main/java/com/iluwatar/Troll.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Troll implements Hostile { 4 | 5 | public void attack() { 6 | System.out.println("The troll swings at you with a club!"); 7 | } 8 | 9 | public void fleeBattle() { 10 | System.out.println("The troll shrieks in horror and runs away!"); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /facade/etc/facade.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/facade/etc/facade.jpg -------------------------------------------------------------------------------- /facade/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | facade 12 | 1.0-SNAPSHOT 13 | facade 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /facade/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Facade (DwarvenGoldmineFacade) provides simpler interface to 6 | * subsystem. 7 | * 8 | */ 9 | public class App 10 | { 11 | public static void main( String[] args ) 12 | { 13 | DwarvenGoldmineFacade facade = new DwarvenGoldmineFacade(); 14 | facade.startNewDay(); 15 | facade.digOutGold(); 16 | facade.endDay(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /facade/src/main/java/com/iluwatar/DwarvenCartOperator.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class DwarvenCartOperator extends DwarvenMineWorker { 4 | 5 | @Override 6 | public void work() { 7 | System.out.println(name() + " moves gold chunks out of the mine."); 8 | } 9 | 10 | @Override 11 | public String name() { 12 | return "Dwarf cart operator"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /facade/src/main/java/com/iluwatar/DwarvenGoldDigger.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class DwarvenGoldDigger extends DwarvenMineWorker { 4 | 5 | @Override 6 | public void work() { 7 | System.out.println(name() + " digs for gold."); 8 | } 9 | 10 | @Override 11 | public String name() { 12 | return "Dwarf gold digger"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /facade/src/main/java/com/iluwatar/DwarvenGoldmineFacade.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class DwarvenGoldmineFacade { 7 | 8 | List workers; 9 | 10 | public DwarvenGoldmineFacade() { 11 | workers = new ArrayList<>(); 12 | workers.add(new DwarvenGoldDigger()); 13 | workers.add(new DwarvenCartOperator()); 14 | workers.add(new DwarvenTunnelDigger()); 15 | } 16 | 17 | public void startNewDay() { 18 | for (DwarvenMineWorker worker: workers) { 19 | worker.wakeUp(); 20 | worker.goToMine(); 21 | } 22 | } 23 | 24 | public void digOutGold() { 25 | for (DwarvenMineWorker worker: workers) { 26 | worker.work(); 27 | } 28 | } 29 | 30 | public void endDay() { 31 | for (DwarvenMineWorker worker: workers) { 32 | worker.goHome(); 33 | worker.goToSleep(); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /facade/src/main/java/com/iluwatar/DwarvenMineWorker.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class DwarvenMineWorker { 4 | 5 | public void goToSleep() { 6 | System.out.println(name() + " goes to sleep."); 7 | } 8 | 9 | public void wakeUp() { 10 | System.out.println(name() + " wakes up."); 11 | } 12 | 13 | public void goHome() { 14 | System.out.println(name() + " goes home."); 15 | } 16 | 17 | public void goToMine() { 18 | System.out.println(name() + " goes to the mine."); 19 | } 20 | 21 | public abstract void work(); 22 | 23 | public abstract String name(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /facade/src/main/java/com/iluwatar/DwarvenTunnelDigger.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class DwarvenTunnelDigger extends DwarvenMineWorker { 4 | 5 | @Override 6 | public void work() { 7 | System.out.println(name() + " creates another promising tunnel."); 8 | } 9 | 10 | @Override 11 | public String name() { 12 | return "Dwarven tunnel digger"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /factory-method/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /factory-method/etc/factory-method.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/factory-method/etc/factory-method.jpg -------------------------------------------------------------------------------- /factory-method/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | factory-method 12 | 1.0-SNAPSHOT 13 | factory-method 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /factory-method/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * In Factory Method we have an interface (Blacksmith) with a 6 | * method for creating objects (manufactureWeapon). The concrete 7 | * subclasses (OrcBlacksmith, ElfBlacksmith) then override the 8 | * method to produce objects of their liking. 9 | * 10 | */ 11 | public class App 12 | { 13 | public static void main( String[] args ) 14 | { 15 | Blacksmith blacksmith; 16 | Weapon weapon; 17 | 18 | blacksmith = new OrcBlacksmith(); 19 | weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR); 20 | System.out.println(weapon); 21 | weapon = blacksmith.manufactureWeapon(WeaponType.AXE); 22 | System.out.println(weapon); 23 | 24 | blacksmith = new ElfBlacksmith(); 25 | weapon = blacksmith.manufactureWeapon(WeaponType.SHORT_SWORD); 26 | System.out.println(weapon); 27 | weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR); 28 | System.out.println(weapon); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /factory-method/src/main/java/com/iluwatar/Blacksmith.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * The interface containing method for producing objects. 6 | * 7 | */ 8 | public interface Blacksmith { 9 | 10 | Weapon manufactureWeapon(WeaponType weaponType); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /factory-method/src/main/java/com/iluwatar/ElfBlacksmith.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Concrete subclass for creating new objects. 6 | * 7 | */ 8 | public class ElfBlacksmith implements Blacksmith { 9 | 10 | public Weapon manufactureWeapon(WeaponType weaponType) { 11 | return new ElfWeapon(weaponType); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /factory-method/src/main/java/com/iluwatar/ElfWeapon.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class ElfWeapon implements Weapon { 4 | 5 | private WeaponType weaponType; 6 | 7 | public ElfWeapon(WeaponType weaponType) { 8 | this.weaponType = weaponType; 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | return "Elven " + weaponType; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /factory-method/src/main/java/com/iluwatar/OrcBlacksmith.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Concrete subclass for creating new objects. 6 | * 7 | */ 8 | public class OrcBlacksmith implements Blacksmith { 9 | 10 | public Weapon manufactureWeapon(WeaponType weaponType) { 11 | return new OrcWeapon(weaponType); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /factory-method/src/main/java/com/iluwatar/OrcWeapon.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcWeapon implements Weapon { 4 | 5 | private WeaponType weaponType; 6 | 7 | public OrcWeapon(WeaponType weaponType) { 8 | this.weaponType = weaponType; 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | return "Orcish " + weaponType; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /factory-method/src/main/java/com/iluwatar/Weapon.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public interface Weapon { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /factory-method/src/main/java/com/iluwatar/WeaponType.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum WeaponType { 4 | 5 | SHORT_SWORD, SPEAR, AXE; 6 | 7 | @Override 8 | public String toString() { 9 | String s = ""; 10 | switch(this) { 11 | case SHORT_SWORD: s = "short sword"; break; 12 | case SPEAR: s = "spear"; break; 13 | case AXE: s = "axe"; break; 14 | } 15 | return s; 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /flyweight/etc/flyweight.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/flyweight/etc/flyweight.jpg -------------------------------------------------------------------------------- /flyweight/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | flyweight 12 | 1.0-SNAPSHOT 13 | flyweight 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/AlchemistShop.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 8 | * The class that needs many objects. 9 | * 10 | */ 11 | public class AlchemistShop { 12 | 13 | List topShelf; 14 | List bottomShelf; 15 | 16 | public AlchemistShop() { 17 | topShelf = new ArrayList<>(); 18 | bottomShelf = new ArrayList<>(); 19 | fillShelves(); 20 | } 21 | 22 | private void fillShelves() { 23 | 24 | PotionFactory factory = new PotionFactory(); 25 | 26 | topShelf.add(factory.createPotion(PotionType.INVISIBILITY)); 27 | topShelf.add(factory.createPotion(PotionType.INVISIBILITY)); 28 | topShelf.add(factory.createPotion(PotionType.STRENGTH)); 29 | topShelf.add(factory.createPotion(PotionType.HEALING)); 30 | topShelf.add(factory.createPotion(PotionType.INVISIBILITY)); 31 | topShelf.add(factory.createPotion(PotionType.STRENGTH)); 32 | topShelf.add(factory.createPotion(PotionType.HEALING)); 33 | topShelf.add(factory.createPotion(PotionType.HEALING)); 34 | 35 | bottomShelf.add(factory.createPotion(PotionType.POISON)); 36 | bottomShelf.add(factory.createPotion(PotionType.POISON)); 37 | bottomShelf.add(factory.createPotion(PotionType.POISON)); 38 | bottomShelf.add(factory.createPotion(PotionType.HOLY_WATER)); 39 | bottomShelf.add(factory.createPotion(PotionType.HOLY_WATER)); 40 | } 41 | 42 | public void enumerate() { 43 | 44 | System.out.println("Enumerating top shelf potions\n"); 45 | 46 | for (Potion p: topShelf) { 47 | p.drink(); 48 | } 49 | 50 | System.out.println("\nEnumerating bottom shelf potions\n"); 51 | 52 | for (Potion p: bottomShelf) { 53 | p.drink(); 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Flyweight (PotionFactory) is useful when there is plethora of 6 | * objects (Potion). It provides means to decrease resource usage 7 | * by sharing object instances. 8 | * 9 | */ 10 | public class App 11 | { 12 | public static void main( String[] args ) 13 | { 14 | AlchemistShop alchemistShop = new AlchemistShop(); 15 | alchemistShop.enumerate(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/HealingPotion.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class HealingPotion implements Potion { 4 | 5 | @Override 6 | public void drink() { 7 | System.out.println("You feel healed. (Potion=" + System.identityHashCode(this) + ")"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/HolyWaterPotion.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class HolyWaterPotion implements Potion { 4 | 5 | @Override 6 | public void drink() { 7 | System.out.println("You feel blessed. (Potion=" + System.identityHashCode(this) + ")"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/InvisibilityPotion.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class InvisibilityPotion implements Potion { 4 | 5 | @Override 6 | public void drink() { 7 | System.out.println("You become invisible. (Potion=" + System.identityHashCode(this) + ")"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/PoisonPotion.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class PoisonPotion implements Potion { 4 | 5 | @Override 6 | public void drink() { 7 | System.out.println("Urgh! This is poisonous. (Potion=" + System.identityHashCode(this) + ")"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/Potion.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Interface for objects. 6 | * 7 | */ 8 | public interface Potion { 9 | 10 | public void drink(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/PotionFactory.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.EnumMap; 4 | 5 | /** 6 | * 7 | * Flyweight. 8 | * 9 | */ 10 | public class PotionFactory { 11 | 12 | private EnumMap potions; 13 | 14 | public PotionFactory() { 15 | potions = new EnumMap<>(PotionType.class); 16 | } 17 | 18 | Potion createPotion(PotionType type) { 19 | Potion potion = potions.get(type); 20 | if (potion == null) { 21 | switch (type) { 22 | case HEALING: 23 | potion = new HealingPotion(); 24 | potions.put(type, potion); 25 | break; 26 | case HOLY_WATER: 27 | potion = new HolyWaterPotion(); 28 | potions.put(type, potion); 29 | break; 30 | case INVISIBILITY: 31 | potion = new InvisibilityPotion(); 32 | potions.put(type, potion); 33 | break; 34 | case POISON: 35 | potion = new PoisonPotion(); 36 | potions.put(type, potion); 37 | break; 38 | case STRENGTH: 39 | potion = new StrengthPotion(); 40 | potions.put(type, potion); 41 | break; 42 | default: 43 | break; 44 | } 45 | } 46 | return potion; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/PotionType.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum PotionType { 4 | 5 | HEALING, 6 | INVISIBILITY, 7 | STRENGTH, 8 | HOLY_WATER, 9 | POISON; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /flyweight/src/main/java/com/iluwatar/StrengthPotion.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class StrengthPotion implements Potion { 4 | 5 | @Override 6 | public void drink() { 7 | System.out.println("You feel strong. (Potion=" + System.identityHashCode(this) + ")"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /interpreter/etc/interpreter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/interpreter/etc/interpreter.jpg -------------------------------------------------------------------------------- /interpreter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | interpreter 12 | 1.0-SNAPSHOT 13 | interpreter 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /interpreter/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * 7 | * Interpreter pattern breaks sentences into expressions (Expression) 8 | * that can be evaluated and as a whole form the result. 9 | * 10 | */ 11 | public class App 12 | { 13 | 14 | /** 15 | * 16 | * Expressions can be evaluated using prefix, infix or postfix notations 17 | * This sample uses postfix, where operator comes after the operands 18 | * 19 | */ 20 | public static void main( String[] args ) 21 | { 22 | String tokenString = "4 3 2 - 1 + *"; 23 | Stack stack = new Stack<>(); 24 | 25 | String[] tokenList = tokenString.split(" "); 26 | for (String s : tokenList) { 27 | if (isOperator(s)) { 28 | Expression rightExpression = stack.pop(); 29 | Expression leftExpression = stack.pop(); 30 | System.out.println(String.format("popped from stack left: %d right: %d", 31 | leftExpression.interpret(), rightExpression.interpret())); 32 | Expression operator = getOperatorInstance(s, leftExpression, 33 | rightExpression); 34 | System.out.println(String.format("operator: %s", operator)); 35 | int result = operator.interpret(); 36 | NumberExpression resultExpression = new NumberExpression(result); 37 | stack.push(resultExpression); 38 | System.out.println(String.format("push result to stack: %d", resultExpression.interpret())); 39 | } else { 40 | Expression i = new NumberExpression(s); 41 | stack.push(i); 42 | System.out.println(String.format("push to stack: %d", i.interpret())); 43 | } 44 | } 45 | System.out.println(String.format("result: %d", stack.pop().interpret())); 46 | } 47 | 48 | public static boolean isOperator(String s) { 49 | if (s.equals("+") || s.equals("-") || s.equals("*")) 50 | return true; 51 | else 52 | return false; 53 | } 54 | 55 | public static Expression getOperatorInstance(String s, Expression left, 56 | Expression right) { 57 | switch (s) { 58 | case "+": 59 | return new PlusExpression(left, right); 60 | case "-": 61 | return new MinusExpression(left, right); 62 | case "*": 63 | return new MultiplyExpression(left, right); 64 | } 65 | return null; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /interpreter/src/main/java/com/iluwatar/Expression.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class Expression { 4 | 5 | public abstract int interpret(); 6 | 7 | @Override 8 | public abstract String toString(); 9 | } 10 | -------------------------------------------------------------------------------- /interpreter/src/main/java/com/iluwatar/MinusExpression.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class MinusExpression extends Expression { 4 | 5 | private Expression leftExpression; 6 | private Expression rightExpression; 7 | 8 | public MinusExpression(Expression leftExpression, Expression rightExpression) { 9 | this.leftExpression = leftExpression; 10 | this.rightExpression = rightExpression; 11 | } 12 | 13 | @Override 14 | public int interpret() { 15 | return leftExpression.interpret() - rightExpression.interpret(); 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "-"; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /interpreter/src/main/java/com/iluwatar/MultiplyExpression.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class MultiplyExpression extends Expression { 4 | 5 | private Expression leftExpression; 6 | private Expression rightExpression; 7 | 8 | public MultiplyExpression(Expression leftExpression, Expression rightExpression) { 9 | this.leftExpression = leftExpression; 10 | this.rightExpression = rightExpression; 11 | } 12 | 13 | @Override 14 | public int interpret() { 15 | return leftExpression.interpret() * rightExpression.interpret(); 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "*"; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /interpreter/src/main/java/com/iluwatar/NumberExpression.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class NumberExpression extends Expression { 4 | 5 | private int number; 6 | 7 | public NumberExpression(int number) { 8 | this.number = number; 9 | } 10 | 11 | public NumberExpression(String s) { 12 | this.number = Integer.parseInt(s); 13 | } 14 | 15 | @Override 16 | public int interpret() { 17 | return number; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "number"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /interpreter/src/main/java/com/iluwatar/PlusExpression.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class PlusExpression extends Expression { 4 | 5 | private Expression leftExpression; 6 | private Expression rightExpression; 7 | 8 | public PlusExpression(Expression leftExpression, Expression rightExpression) { 9 | this.leftExpression = leftExpression; 10 | this.rightExpression = rightExpression; 11 | } 12 | 13 | @Override 14 | public int interpret() { 15 | return leftExpression.interpret() + rightExpression.interpret(); 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return "+"; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /iterator/etc/iterator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/iterator/etc/iterator.jpg -------------------------------------------------------------------------------- /iterator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | iterator 12 | 1.0-SNAPSHOT 13 | iterator 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /iterator/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Iterator (ItemIterator) adds abstraction layer on top of a 6 | * collection (TreasureChest). This way the collection can change 7 | * its internal implementation without affecting its clients. 8 | * 9 | */ 10 | public class App 11 | { 12 | public static void main( String[] args ) 13 | { 14 | TreasureChest chest = new TreasureChest(); 15 | 16 | ItemIterator ringIterator = chest.Iterator(ItemType.RING); 17 | while (ringIterator.hasNext()) { 18 | System.out.println(ringIterator.next()); 19 | } 20 | 21 | System.out.println("----------"); 22 | 23 | ItemIterator potionIterator = chest.Iterator(ItemType.POTION); 24 | while (potionIterator.hasNext()) { 25 | System.out.println(potionIterator.next()); 26 | } 27 | 28 | System.out.println("----------"); 29 | 30 | ItemIterator weaponIterator = chest.Iterator(ItemType.WEAPON); 31 | while (weaponIterator.hasNext()) { 32 | System.out.println(weaponIterator.next()); 33 | } 34 | 35 | System.out.println("----------"); 36 | 37 | ItemIterator it = chest.Iterator(ItemType.ANY); 38 | while (it.hasNext()) { 39 | System.out.println(it.next()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /iterator/src/main/java/com/iluwatar/Item.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Item { 4 | 5 | private ItemType type; 6 | private String name; 7 | 8 | public Item(ItemType type, String name) { 9 | this.setType(type); 10 | this.name = name; 11 | } 12 | 13 | @Override 14 | public String toString() { 15 | return name; 16 | } 17 | 18 | public ItemType getType() { 19 | return type; 20 | } 21 | 22 | public void setType(ItemType type) { 23 | this.type = type; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /iterator/src/main/java/com/iluwatar/ItemIterator.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Iterator interface. 6 | * 7 | */ 8 | public interface ItemIterator { 9 | 10 | boolean hasNext(); 11 | 12 | Item next(); 13 | } 14 | -------------------------------------------------------------------------------- /iterator/src/main/java/com/iluwatar/ItemType.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum ItemType { 4 | 5 | ANY, 6 | WEAPON, 7 | RING, 8 | POTION 9 | 10 | } 11 | -------------------------------------------------------------------------------- /iterator/src/main/java/com/iluwatar/TreasureChest.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 8 | * Collection class. 9 | * 10 | */ 11 | public class TreasureChest { 12 | 13 | private List items; 14 | 15 | public TreasureChest() { 16 | items = new ArrayList<>(); 17 | items.add(new Item(ItemType.POTION, "Potion of courage")); 18 | items.add(new Item(ItemType.RING, "Ring of shadows")); 19 | items.add(new Item(ItemType.POTION, "Potion of wisdom")); 20 | items.add(new Item(ItemType.POTION, "Potion of blood")); 21 | items.add(new Item(ItemType.WEAPON, "Sword of silver +1")); 22 | items.add(new Item(ItemType.POTION, "Potion of rust")); 23 | items.add(new Item(ItemType.POTION, "Potion of healing")); 24 | items.add(new Item(ItemType.RING, "Ring of armor")); 25 | items.add(new Item(ItemType.WEAPON, "Steel halberd")); 26 | items.add(new Item(ItemType.WEAPON, "Dagger of poison")); 27 | } 28 | 29 | ItemIterator Iterator(ItemType type) { 30 | return new TreasureChestItemIterator(this, type); 31 | } 32 | 33 | public List getItems() { 34 | ArrayList list = new ArrayList<>(); 35 | list.addAll(items); 36 | return list; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /iterator/src/main/java/com/iluwatar/TreasureChestItemIterator.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.List; 4 | 5 | public class TreasureChestItemIterator implements ItemIterator { 6 | 7 | private TreasureChest chest; 8 | private int idx; 9 | private ItemType type; 10 | 11 | public TreasureChestItemIterator(TreasureChest chest, ItemType type) { 12 | this.chest = chest; 13 | this.type = type; 14 | this.idx = -1; 15 | } 16 | 17 | @Override 18 | public boolean hasNext() { 19 | return findNextIdx() != -1; 20 | } 21 | 22 | @Override 23 | public Item next() { 24 | idx = findNextIdx(); 25 | if (idx != -1) { 26 | return chest.getItems().get(idx); 27 | } 28 | return null; 29 | } 30 | 31 | private int findNextIdx() { 32 | 33 | List items = chest.getItems(); 34 | boolean found = false; 35 | int tempIdx = idx; 36 | while (!found) { 37 | tempIdx++; 38 | if (tempIdx >= items.size()) { 39 | tempIdx = -1; 40 | break; 41 | } 42 | if (type.equals(ItemType.ANY) || items.get(tempIdx).getType().equals(type)) { 43 | break; 44 | } 45 | } 46 | return tempIdx; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /mediator/etc/mediator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/mediator/etc/mediator.jpg -------------------------------------------------------------------------------- /mediator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | mediator 12 | 1.0-SNAPSHOT 13 | mediator 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/Action.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum Action { 4 | 5 | HUNT, TALE, GOLD, ENEMY; 6 | 7 | public String toString() { 8 | 9 | String s = ""; 10 | switch (this) { 11 | case ENEMY: 12 | s = "spotted enemies"; 13 | break; 14 | case GOLD: 15 | s = "found gold"; 16 | break; 17 | case HUNT: 18 | s = "hunted a rabbit"; 19 | break; 20 | case TALE: 21 | s = "tells a tale"; 22 | break; 23 | default: 24 | break; 25 | } 26 | return s; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Mediator encapsulates how set of objects (PartyMember) interact. 6 | * Instead of referring to each other directly they 7 | * use the mediator (Party) interface. 8 | * 9 | */ 10 | public class App 11 | { 12 | public static void main( String[] args ) 13 | { 14 | Party party = new PartyImpl(); 15 | Hobbit hobbit = new Hobbit(); 16 | Wizard wizard = new Wizard(); 17 | Rogue rogue = new Rogue(); 18 | Hunter hunter = new Hunter(); 19 | 20 | party.addMember(hobbit); 21 | party.addMember(wizard); 22 | party.addMember(rogue); 23 | party.addMember(hunter); 24 | 25 | hobbit.act(Action.ENEMY); 26 | wizard.act(Action.TALE); 27 | rogue.act(Action.GOLD); 28 | hunter.act(Action.HUNT); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/Hobbit.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Hobbit extends PartyMemberBase { 4 | 5 | @Override 6 | public String toString() { 7 | return "Hobbit"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/Hunter.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Hunter extends PartyMemberBase { 4 | 5 | @Override 6 | public String toString() { 7 | return "Hunter"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/Party.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Mediator interface. 6 | * 7 | */ 8 | public interface Party { 9 | 10 | void addMember(PartyMember member); 11 | 12 | void act(PartyMember actor, Action action); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/PartyImpl.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class PartyImpl implements Party { 7 | 8 | private List members; 9 | 10 | public PartyImpl() { 11 | members = new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void act(PartyMember actor, Action action) { 16 | for (PartyMember member: members) { 17 | if (member != actor) { 18 | member.partyAction(action); 19 | } 20 | } 21 | } 22 | 23 | @Override 24 | public void addMember(PartyMember member) { 25 | members.add(member); 26 | member.joinedParty(this); 27 | } 28 | 29 | // somebody hunts for food, call for dinner 30 | 31 | // somebody spots enemy, alert everybody 32 | 33 | // somebody finds gold, deal the gold with everybody 34 | 35 | // somebody tells a tale, call everybody to listen 36 | 37 | } 38 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/PartyMember.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Interface for party members interacting with Party. 6 | * 7 | */ 8 | public interface PartyMember { 9 | 10 | void joinedParty(Party party); 11 | 12 | void partyAction(Action action); 13 | 14 | void act(Action action); 15 | } 16 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/PartyMemberBase.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class PartyMemberBase implements PartyMember { 4 | 5 | protected Party party; 6 | 7 | @Override 8 | public void joinedParty(Party party) { 9 | System.out.println(this + " joins the party"); 10 | this.party = party; 11 | } 12 | 13 | @Override 14 | public void partyAction(Action action) { 15 | String s = this + " "; 16 | switch (action) { 17 | case ENEMY: 18 | s = s + "runs for cover"; 19 | break; 20 | case GOLD: 21 | s = s + "takes his share of the gold"; 22 | break; 23 | case HUNT: 24 | s = s + "arrives for dinner"; 25 | break; 26 | case TALE: 27 | s = s + "comes to listen"; 28 | break; 29 | default: 30 | break; 31 | } 32 | System.out.println(s); 33 | } 34 | 35 | @Override 36 | public void act(Action action) { 37 | if (party != null) { 38 | System.out.println(this + " " + action.toString()); 39 | party.act(this, action); 40 | } 41 | } 42 | 43 | @Override 44 | public abstract String toString(); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/Rogue.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Rogue extends PartyMemberBase { 4 | 5 | @Override 6 | public String toString() { 7 | return "Rogue"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /mediator/src/main/java/com/iluwatar/Wizard.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Wizard extends PartyMemberBase { 4 | 5 | @Override 6 | public String toString() { 7 | return "Wizard"; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /memento/etc/memento.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/memento/etc/memento.jpg -------------------------------------------------------------------------------- /memento/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | memento 12 | 1.0-SNAPSHOT 13 | memento 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /memento/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * 7 | * Memento pattern is for storing and restoring object 8 | * state. The object (Star) gives out a "memento" 9 | * (StarMemento) that contains the state of the object. 10 | * Later on the memento can be set back to the object 11 | * restoring the state. 12 | * 13 | */ 14 | public class App 15 | { 16 | public static void main( String[] args ) 17 | { 18 | Stack states = new Stack<>(); 19 | 20 | Star star = new Star(StarType.SUN, 10000000, 500000); 21 | System.out.println(star); 22 | states.add(star.getMemento()); 23 | star.timePasses(); 24 | System.out.println(star); 25 | states.add(star.getMemento()); 26 | star.timePasses(); 27 | System.out.println(star); 28 | states.add(star.getMemento()); 29 | star.timePasses(); 30 | System.out.println(star); 31 | states.add(star.getMemento()); 32 | star.timePasses(); 33 | System.out.println(star); 34 | while (states.size() > 0) { 35 | star.setMemento(states.pop()); 36 | System.out.println(star); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /memento/src/main/java/com/iluwatar/Star.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Star uses "mementos" to store and restore state. 6 | * 7 | */ 8 | public class Star { 9 | 10 | private StarType type; 11 | private int ageYears; 12 | private int massTons; 13 | 14 | public Star(StarType startType, int startAge, int startMass) { 15 | this.type = startType; 16 | this.ageYears = startAge; 17 | this.massTons = startMass; 18 | } 19 | 20 | public void timePasses() { 21 | ageYears *= 2; 22 | massTons *= 8; 23 | switch (type) { 24 | case RED_GIANT: 25 | type = StarType.WHITE_DWARF; 26 | break; 27 | case SUN: 28 | type = StarType.RED_GIANT; 29 | break; 30 | case SUPERNOVA: 31 | type = StarType.DEAD; 32 | break; 33 | case WHITE_DWARF: 34 | type = StarType.SUPERNOVA; 35 | break; 36 | case DEAD: 37 | ageYears *= 2; 38 | massTons = 0; 39 | break; 40 | default: 41 | break; 42 | } 43 | } 44 | 45 | StarMemento getMemento() { 46 | 47 | StarMementoInternal state = new StarMementoInternal(); 48 | state.setAgeYears(ageYears); 49 | state.setMassTons(massTons); 50 | state.setType(type); 51 | return state; 52 | 53 | } 54 | 55 | void setMemento(StarMemento memento) { 56 | 57 | StarMementoInternal state = (StarMementoInternal) memento; 58 | this.type = state.getType(); 59 | this.ageYears = state.getAgeYears(); 60 | this.massTons = state.getMassTons(); 61 | 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return String.format("%s age: %d years mass: %d tons", type.toString(), ageYears, massTons); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /memento/src/main/java/com/iluwatar/StarMemento.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * External interface to memento. 6 | * 7 | */ 8 | public interface StarMemento { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /memento/src/main/java/com/iluwatar/StarMementoInternal.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Internal interface to memento. 6 | * 7 | */ 8 | public class StarMementoInternal implements StarMemento { 9 | 10 | private StarType type; 11 | private int ageYears; 12 | private int massTons; 13 | 14 | public StarType getType() { 15 | return type; 16 | } 17 | public void setType(StarType type) { 18 | this.type = type; 19 | } 20 | public int getAgeYears() { 21 | return ageYears; 22 | } 23 | public void setAgeYears(int ageYears) { 24 | this.ageYears = ageYears; 25 | } 26 | public int getMassTons() { 27 | return massTons; 28 | } 29 | public void setMassTons(int massTons) { 30 | this.massTons = massTons; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /memento/src/main/java/com/iluwatar/StarType.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum StarType { 4 | 5 | SUN, 6 | RED_GIANT, 7 | WHITE_DWARF, 8 | SUPERNOVA, 9 | DEAD; 10 | 11 | @Override 12 | public String toString() { 13 | String s = ""; 14 | switch (this) { 15 | case RED_GIANT: 16 | s = "red giant"; 17 | break; 18 | case SUN: 19 | s = "sun"; 20 | break; 21 | case SUPERNOVA: 22 | s = "supernova"; 23 | break; 24 | case WHITE_DWARF: 25 | s = "white dwarf"; 26 | break; 27 | case DEAD: 28 | s = "dead star"; 29 | break; 30 | default: 31 | break; 32 | } 33 | return s; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /observer/etc/observer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/observer/etc/observer.jpg -------------------------------------------------------------------------------- /observer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | observer 12 | 1.0-SNAPSHOT 13 | observer 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /observer/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Observer pattern defines one-to-many relationship 6 | * between objects. The target object sends change 7 | * notifications to its registered observers. 8 | * 9 | */ 10 | public class App 11 | { 12 | public static void main( String[] args ) 13 | { 14 | 15 | Weather weather = new Weather(); 16 | weather.addObserver(new Orcs()); 17 | weather.addObserver(new Hobbits()); 18 | 19 | weather.timePasses(); 20 | weather.timePasses(); 21 | weather.timePasses(); 22 | weather.timePasses(); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /observer/src/main/java/com/iluwatar/Hobbits.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Hobbits implements WeatherObserver { 4 | 5 | @Override 6 | public void update(WeatherType currentWeather) { 7 | switch (currentWeather) { 8 | case COLD: 9 | System.out.println("The hobbits are shivering in the cold weather."); 10 | break; 11 | case RAINY: 12 | System.out.println("The hobbits look for cover from the rain."); 13 | break; 14 | case SUNNY: 15 | System.out.println("The happy hobbits bade in the warm sun."); 16 | break; 17 | case WINDY: 18 | System.out.println("The hobbits hold their hats tightly in the windy weather."); 19 | break; 20 | default: 21 | break; 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /observer/src/main/java/com/iluwatar/Orcs.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Orcs implements WeatherObserver { 4 | 5 | @Override 6 | public void update(WeatherType currentWeather) { 7 | switch (currentWeather) { 8 | case COLD: 9 | System.out.println("The orcs are freezing cold."); 10 | break; 11 | case RAINY: 12 | System.out.println("The orcs are dripping wet."); 13 | break; 14 | case SUNNY: 15 | System.out.println("The sun hurts the orcs' eyes."); 16 | break; 17 | case WINDY: 18 | System.out.println("The orc smell almost vanishes in the wind."); 19 | break; 20 | default: 21 | break; 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /observer/src/main/java/com/iluwatar/Weather.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 8 | * Weather can be observed by implementing WeatherObserver 9 | * interface and registering as listener. 10 | * 11 | */ 12 | public class Weather { 13 | 14 | private WeatherType currentWeather; 15 | private List observers; 16 | 17 | public Weather() { 18 | observers = new ArrayList<>(); 19 | currentWeather = WeatherType.SUNNY; 20 | } 21 | 22 | public void addObserver(WeatherObserver obs) { 23 | observers.add(obs); 24 | } 25 | 26 | public void removeObserver(WeatherObserver obs) { 27 | observers.remove(obs); 28 | } 29 | 30 | public void timePasses() { 31 | switch (currentWeather) { 32 | case COLD: 33 | currentWeather = WeatherType.SUNNY; 34 | break; 35 | case RAINY: 36 | currentWeather = WeatherType.WINDY; 37 | break; 38 | case SUNNY: 39 | currentWeather = WeatherType.RAINY; 40 | break; 41 | case WINDY: 42 | currentWeather = WeatherType.COLD; 43 | break; 44 | default: 45 | break; 46 | } 47 | System.out.println("The weather now changes to " + currentWeather); 48 | notifyObservers(); 49 | } 50 | 51 | private void notifyObservers() { 52 | for (WeatherObserver obs: observers) { 53 | obs.update(currentWeather); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /observer/src/main/java/com/iluwatar/WeatherObserver.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Observer interface. 6 | * 7 | */ 8 | public interface WeatherObserver { 9 | 10 | void update(WeatherType currentWeather); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /observer/src/main/java/com/iluwatar/WeatherType.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public enum WeatherType { 4 | 5 | SUNNY, 6 | RAINY, 7 | WINDY, 8 | COLD; 9 | 10 | public String toString() { 11 | return this.name().toLowerCase(); 12 | }; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.iluwatar 6 | java-design-patterns 7 | 1.0-SNAPSHOT 8 | pom 9 | 10 | 11 | 12 | website 13 | scp://webhost.company.com/www/website 14 | 15 | 16 | 17 | 18 | UTF-8 19 | 20 | 21 | abstract-factory 22 | builder 23 | factory-method 24 | prototype 25 | singleton 26 | adapter 27 | bridge 28 | composite 29 | decorator 30 | facade 31 | flyweight 32 | proxy 33 | chain 34 | command 35 | interpreter 36 | iterator 37 | mediator 38 | memento 39 | observer 40 | state 41 | strategy 42 | template-method 43 | visitor 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-compiler-plugin 52 | 3.0 53 | 54 | 1.7 55 | 1.7 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /prototype/etc/prototype.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/prototype/etc/prototype.jpg -------------------------------------------------------------------------------- /prototype/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | prototype 12 | 1.0-SNAPSHOT 13 | prototype 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * In Prototype we have a factory class (HeroFactoryImpl) producing 6 | * objects by cloning existing ones. In this example the factory's 7 | * prototype objects are given as constructor parameters. 8 | * 9 | */ 10 | public class App 11 | { 12 | public static void main( String[] args ) 13 | { 14 | HeroFactory factory; 15 | Mage mage; 16 | Warlord warlord; 17 | Beast beast; 18 | 19 | factory = new HeroFactoryImpl(new ElfMage(), new ElfWarlord(), new ElfBeast()); 20 | mage = factory.createMage(); 21 | warlord = factory.createWarlord(); 22 | beast = factory.createBeast(); 23 | System.out.println(mage); 24 | System.out.println(warlord); 25 | System.out.println(beast); 26 | 27 | factory = new HeroFactoryImpl(new OrcMage(), new OrcWarlord(), new OrcBeast()); 28 | mage = factory.createMage(); 29 | warlord = factory.createWarlord(); 30 | beast = factory.createBeast(); 31 | System.out.println(mage); 32 | System.out.println(warlord); 33 | System.out.println(beast); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/Beast.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class Beast extends Prototype { 4 | 5 | @Override 6 | public abstract Beast clone() throws CloneNotSupportedException; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/ElfBeast.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class ElfBeast extends Beast { 4 | 5 | public ElfBeast() { 6 | } 7 | 8 | public ElfBeast(ElfBeast beast) { 9 | } 10 | 11 | @Override 12 | public Beast clone() throws CloneNotSupportedException { 13 | return new ElfBeast(this); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "Elven eagle"; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/ElfMage.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class ElfMage extends Mage { 4 | 5 | public ElfMage() { 6 | } 7 | 8 | public ElfMage(ElfMage mage) { 9 | } 10 | 11 | @Override 12 | public Mage clone() throws CloneNotSupportedException { 13 | return new ElfMage(this); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "Elven mage"; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/ElfWarlord.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class ElfWarlord extends Warlord { 4 | 5 | public ElfWarlord() { 6 | } 7 | 8 | public ElfWarlord(ElfWarlord warlord) { 9 | } 10 | 11 | @Override 12 | public Warlord clone() throws CloneNotSupportedException { 13 | return new ElfWarlord(this); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "Elven warlord"; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/HeroFactory.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Interface for the factory class. 6 | * 7 | */ 8 | public interface HeroFactory { 9 | 10 | Mage createMage(); 11 | 12 | Warlord createWarlord(); 13 | 14 | Beast createBeast(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/HeroFactoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Concrete factory class. 6 | * 7 | */ 8 | public class HeroFactoryImpl implements HeroFactory { 9 | 10 | private Mage mage; 11 | private Warlord warlord; 12 | private Beast beast; 13 | 14 | public HeroFactoryImpl(Mage mage, Warlord warlord, Beast beast) { 15 | this.mage = mage; 16 | this.warlord = warlord; 17 | this.beast = beast; 18 | } 19 | 20 | public Mage createMage() { 21 | try { 22 | return mage.clone(); 23 | } catch (CloneNotSupportedException e) { 24 | return null; 25 | } 26 | } 27 | 28 | public Warlord createWarlord() { 29 | try { 30 | return warlord.clone(); 31 | } catch (CloneNotSupportedException e) { 32 | return null; 33 | } 34 | } 35 | 36 | public Beast createBeast() { 37 | try { 38 | return beast.clone(); 39 | } catch (CloneNotSupportedException e) { 40 | return null; 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/Mage.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class Mage extends Prototype { 4 | 5 | @Override 6 | public abstract Mage clone() throws CloneNotSupportedException; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/OrcBeast.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcBeast extends Beast { 4 | 5 | public OrcBeast() { 6 | } 7 | 8 | public OrcBeast(OrcBeast beast) { 9 | } 10 | 11 | @Override 12 | public Beast clone() throws CloneNotSupportedException { 13 | return new OrcBeast(this); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "Orcish wolf"; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/OrcMage.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcMage extends Mage { 4 | 5 | public OrcMage() { 6 | } 7 | 8 | public OrcMage(OrcMage mage) { 9 | } 10 | 11 | @Override 12 | public Mage clone() throws CloneNotSupportedException { 13 | return new OrcMage(this); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "Orcish mage"; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/OrcWarlord.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class OrcWarlord extends Warlord { 4 | 5 | public OrcWarlord() { 6 | } 7 | 8 | public OrcWarlord(OrcWarlord warlord) { 9 | } 10 | 11 | @Override 12 | public Warlord clone() throws CloneNotSupportedException { 13 | return new OrcWarlord(this); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "Orcish warlord"; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/Prototype.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class Prototype implements Cloneable { 4 | 5 | @Override 6 | public abstract Object clone() throws CloneNotSupportedException; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /prototype/src/main/java/com/iluwatar/Warlord.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public abstract class Warlord extends Prototype { 4 | 5 | @Override 6 | public abstract Warlord clone() throws CloneNotSupportedException; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /proxy/etc/proxy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/proxy/etc/proxy.jpg -------------------------------------------------------------------------------- /proxy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | proxy 12 | 1.0-SNAPSHOT 13 | proxy 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /proxy/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Proxy (WizardTowerProxy) controls access to the 6 | * actual object (WizardTower). 7 | * 8 | */ 9 | public class App 10 | { 11 | public static void main( String[] args ) 12 | { 13 | 14 | WizardTowerProxy tower = new WizardTowerProxy(); 15 | tower.enter(new Wizard("Red wizard")); 16 | tower.enter(new Wizard("White wizard")); 17 | tower.enter(new Wizard("Black wizard")); 18 | tower.enter(new Wizard("Green wizard")); 19 | tower.enter(new Wizard("Brown wizard")); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /proxy/src/main/java/com/iluwatar/Wizard.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Wizard { 4 | 5 | private String name; 6 | 7 | public Wizard(String name) { 8 | this.name = name; 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | return name; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /proxy/src/main/java/com/iluwatar/WizardTower.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * The object to be proxyed. 6 | * 7 | */ 8 | public class WizardTower { 9 | 10 | public void enter(Wizard wizard) { 11 | System.out.println(wizard + " enters the tower."); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /proxy/src/main/java/com/iluwatar/WizardTowerProxy.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * The proxy controlling access to WizardTower. 6 | * 7 | */ 8 | public class WizardTowerProxy extends WizardTower { 9 | 10 | private static final int NUM_WIZARDS_ALLOWED = 3; 11 | 12 | private int numWizards; 13 | 14 | @Override 15 | public void enter(Wizard wizard) { 16 | if (numWizards < NUM_WIZARDS_ALLOWED) { 17 | super.enter(wizard); 18 | numWizards++; 19 | } else { 20 | System.out.println(wizard + " is not allowed to enter!"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /singleton/etc/singleton.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/singleton/etc/singleton.jpg -------------------------------------------------------------------------------- /singleton/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | singleton 12 | 1.0-SNAPSHOT 13 | singleton 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /singleton/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Singleton pattern ensures that the class (IvoryTower) can have only 6 | * one existing instance and provides global access to that instance. 7 | * 8 | */ 9 | public class App 10 | { 11 | public static void main( String[] args ) 12 | { 13 | 14 | IvoryTower ivoryTower1 = IvoryTower.getInstance(); 15 | IvoryTower ivoryTower2 = IvoryTower.getInstance(); 16 | System.out.println("ivoryTower1=" + ivoryTower1); 17 | System.out.println("ivoryTower2=" + ivoryTower2); 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /singleton/src/main/java/com/iluwatar/IvoryTower.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Singleton class. 6 | * 7 | */ 8 | public class IvoryTower { 9 | 10 | private static IvoryTower instance = new IvoryTower(); 11 | 12 | private IvoryTower() { 13 | } 14 | 15 | public static IvoryTower getInstance() { 16 | return instance; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /state/etc/state.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/state/etc/state.jpg -------------------------------------------------------------------------------- /state/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | state 12 | 1.0-SNAPSHOT 13 | state 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /state/src/main/java/com/iluwatar/AngryState.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class AngryState implements State { 4 | 5 | private Mammoth mammoth; 6 | 7 | public AngryState(Mammoth mammoth) { 8 | this.mammoth = mammoth; 9 | } 10 | 11 | @Override 12 | public void observe() { 13 | System.out.println(String.format("%s is furious!", mammoth)); 14 | } 15 | 16 | @Override 17 | public void onEnterState() { 18 | System.out.println(String.format("%s gets angry!", mammoth)); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /state/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * In State pattern the object (Mammoth) has internal 6 | * state object (State) that defines the current 7 | * behavior. The state object can be changed 8 | * to alter the behavior. 9 | * 10 | */ 11 | public class App 12 | { 13 | public static void main( String[] args ) 14 | { 15 | 16 | Mammoth mammoth = new Mammoth(); 17 | mammoth.observe(); 18 | mammoth.timePasses(); 19 | mammoth.observe(); 20 | mammoth.timePasses(); 21 | mammoth.observe(); 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /state/src/main/java/com/iluwatar/Mammoth.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Mammoth has internal state that defines its behavior. 6 | * 7 | */ 8 | public class Mammoth { 9 | 10 | private State state; 11 | 12 | public Mammoth() { 13 | state = new PeacefulState(this); 14 | } 15 | 16 | public void timePasses() { 17 | if (state.getClass().equals(PeacefulState.class)) { 18 | changeStateTo(new AngryState(this)); 19 | } else { 20 | changeStateTo(new PeacefulState(this)); 21 | } 22 | } 23 | 24 | private void changeStateTo(State newState) { 25 | this.state = newState; 26 | this.state.onEnterState(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "The mammoth"; 32 | } 33 | 34 | public void observe() { 35 | this.state.observe(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /state/src/main/java/com/iluwatar/PeacefulState.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class PeacefulState implements State { 4 | 5 | private Mammoth mammoth; 6 | 7 | public PeacefulState(Mammoth mammoth) { 8 | this.mammoth = mammoth; 9 | } 10 | 11 | @Override 12 | public void observe() { 13 | System.out.println(String.format("%s is calm and peaceful.", mammoth)); 14 | } 15 | 16 | @Override 17 | public void onEnterState() { 18 | System.out.println(String.format("%s calms down.", mammoth)); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /state/src/main/java/com/iluwatar/State.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * State interface. 6 | * 7 | */ 8 | public interface State { 9 | 10 | void onEnterState(); 11 | 12 | void observe(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /strategy/etc/strategy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/strategy/etc/strategy.jpg -------------------------------------------------------------------------------- /strategy/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | strategy 12 | 1.0-SNAPSHOT 13 | strategy 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /strategy/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Strategy (DragonSlayingStrategy) encapsulates the algorithm to use. 6 | * The object (DragonSlayer) can alter its behavior by changing its strategy. 7 | * 8 | */ 9 | public class App 10 | { 11 | public static void main( String[] args ) 12 | { 13 | System.out.println("Green dragon spotted ahead!"); 14 | DragonSlayer dragonSlayer = new DragonSlayer(new MeleeStrategy()); 15 | dragonSlayer.goToBattle(); 16 | System.out.println("Red dragon emerges."); 17 | dragonSlayer.changeStrategy(new ProjectileStrategy()); 18 | dragonSlayer.goToBattle(); 19 | System.out.println("Black dragon lands before you."); 20 | dragonSlayer.changeStrategy(new SpellStrategy()); 21 | dragonSlayer.goToBattle(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /strategy/src/main/java/com/iluwatar/DragonSlayer.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * DragonSlayer uses different strategies to slay the dragon. 6 | * 7 | */ 8 | public class DragonSlayer { 9 | 10 | private DragonSlayingStrategy strategy; 11 | 12 | public DragonSlayer(DragonSlayingStrategy strategy) { 13 | this.strategy = strategy; 14 | } 15 | 16 | public void changeStrategy(DragonSlayingStrategy strategy) { 17 | this.strategy = strategy; 18 | } 19 | 20 | public void goToBattle() { 21 | strategy.execute(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /strategy/src/main/java/com/iluwatar/DragonSlayingStrategy.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Strategy interface. 6 | * 7 | */ 8 | public interface DragonSlayingStrategy { 9 | 10 | void execute(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /strategy/src/main/java/com/iluwatar/MeleeStrategy.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class MeleeStrategy implements DragonSlayingStrategy { 4 | 5 | @Override 6 | public void execute() { 7 | System.out.println("With your Excalibur you severe the dragon's head!"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /strategy/src/main/java/com/iluwatar/ProjectileStrategy.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class ProjectileStrategy implements DragonSlayingStrategy { 4 | 5 | @Override 6 | public void execute() { 7 | System.out.println("You shoot the dragon with the magical crossbow and it falls dead on the ground!"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /strategy/src/main/java/com/iluwatar/SpellStrategy.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class SpellStrategy implements DragonSlayingStrategy { 4 | 5 | @Override 6 | public void execute() { 7 | System.out.println("You cast the spell of disintegration and the dragon vaporizes in a pile of dust!"); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /template-method/etc/template-method.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/template-method/etc/template-method.jpg -------------------------------------------------------------------------------- /template-method/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | template-method 12 | 1.0-SNAPSHOT 13 | template-method 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /template-method/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Template Method (StealingMethod) defines skeleton for the 6 | * algorithm and subclasses (HitAndRunMethod, SubtleMethod) 7 | * fill in the blanks. 8 | * 9 | */ 10 | public class App 11 | { 12 | public static void main( String[] args ) 13 | { 14 | HalflingThief thief = new HalflingThief(new HitAndRunMethod()); 15 | thief.steal(); 16 | thief.changeMethod(new SubtleMethod()); 17 | thief.steal(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /template-method/src/main/java/com/iluwatar/HalflingThief.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Halfling thief uses StealingMethod to steal. 6 | * 7 | */ 8 | public class HalflingThief { 9 | 10 | private StealingMethod method; 11 | 12 | public HalflingThief(StealingMethod method) { 13 | this.method = method; 14 | } 15 | 16 | public void steal() { 17 | method.steal(); 18 | } 19 | 20 | public void changeMethod(StealingMethod method) { 21 | this.method = method; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /template-method/src/main/java/com/iluwatar/HitAndRunMethod.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class HitAndRunMethod extends StealingMethod { 4 | 5 | @Override 6 | protected String pickTarget() { 7 | return "old goblin woman"; 8 | } 9 | 10 | @Override 11 | protected void confuseTarget(String target) { 12 | System.out.println("Approach the " + target + " from behind."); 13 | } 14 | 15 | @Override 16 | protected void stealTheItem(String target) { 17 | System.out.println("Grab the handbag and run away fast!"); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /template-method/src/main/java/com/iluwatar/StealingMethod.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Template Method base class. 6 | * 7 | */ 8 | public abstract class StealingMethod { 9 | 10 | protected abstract String pickTarget(); 11 | 12 | protected abstract void confuseTarget(String target); 13 | 14 | protected abstract void stealTheItem(String target); 15 | 16 | public void steal() { 17 | String target = pickTarget(); 18 | System.out.println("The target has been chosen as " + target + "."); 19 | confuseTarget(target); 20 | stealTheItem(target); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /template-method/src/main/java/com/iluwatar/SubtleMethod.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class SubtleMethod extends StealingMethod { 4 | 5 | @Override 6 | protected String pickTarget() { 7 | return "shop keeper"; 8 | } 9 | 10 | @Override 11 | protected void confuseTarget(String target) { 12 | System.out.println("Approach the " + target + " with tears running and hug him!"); 13 | } 14 | 15 | @Override 16 | protected void stealTheItem(String target) { 17 | System.out.println("While in close contact grab the " + target + "'s wallet."); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /visitor/etc/visitor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android10/java-design-patterns/1eddfa844de82f731c46599b0b4d06296d3ab3cf/visitor/etc/visitor.jpg -------------------------------------------------------------------------------- /visitor/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.iluwatar 7 | java-design-patterns 8 | 1.0-SNAPSHOT 9 | 10 | com.iluwatar 11 | visitor 12 | 1.0-SNAPSHOT 13 | visitor 14 | http://maven.apache.org 15 | 16 | 17 | junit 18 | junit 19 | 3.8.1 20 | test 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /visitor/src/main/java/com/iluwatar/App.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Visitor pattern defines mechanism to apply operations 6 | * (UnitVisitor) on nodes (Unit) in hierarchy. New operations 7 | * can be added without altering the node interface. 8 | * 9 | */ 10 | public class App 11 | { 12 | public static void main( String[] args ) 13 | { 14 | 15 | Commander commander = new Commander( 16 | new Sergeant(new Soldier(), new Soldier(), new Soldier()), 17 | new Sergeant(new Soldier(), new Soldier(), new Soldier())); 18 | commander.accept(new SoldierVisitor()); 19 | commander.accept(new SergeantVisitor()); 20 | commander.accept(new CommanderVisitor()); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /visitor/src/main/java/com/iluwatar/Commander.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Commander extends Unit { 4 | 5 | public Commander(Unit ... children) { 6 | super(children); 7 | } 8 | 9 | @Override 10 | public void accept(UnitVisitor visitor) { 11 | visitor.visitCommander(this); 12 | super.accept(visitor); 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "commander"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /visitor/src/main/java/com/iluwatar/CommanderVisitor.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class CommanderVisitor implements UnitVisitor { 4 | 5 | @Override 6 | public void visitSoldier(Soldier soldier) { 7 | // TODO Auto-generated method stub 8 | 9 | } 10 | 11 | @Override 12 | public void visitSergeant(Sergeant sergeant) { 13 | // TODO Auto-generated method stub 14 | 15 | } 16 | 17 | @Override 18 | public void visitCommander(Commander commander) { 19 | System.out.println("Good to see you " + commander); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /visitor/src/main/java/com/iluwatar/Sergeant.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Sergeant extends Unit { 4 | 5 | public Sergeant(Unit ... children) { 6 | super(children); 7 | } 8 | 9 | @Override 10 | public void accept(UnitVisitor visitor) { 11 | visitor.visitSergeant(this); 12 | super.accept(visitor); 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "sergeant"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /visitor/src/main/java/com/iluwatar/SergeantVisitor.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class SergeantVisitor implements UnitVisitor { 4 | 5 | @Override 6 | public void visitSoldier(Soldier soldier) { 7 | // TODO Auto-generated method stub 8 | 9 | } 10 | 11 | @Override 12 | public void visitSergeant(Sergeant sergeant) { 13 | System.out.println("Hello " + sergeant); 14 | } 15 | 16 | @Override 17 | public void visitCommander(Commander commander) { 18 | // TODO Auto-generated method stub 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /visitor/src/main/java/com/iluwatar/Soldier.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class Soldier extends Unit { 4 | 5 | public Soldier(Unit ... children) { 6 | super(children); 7 | } 8 | 9 | @Override 10 | public void accept(UnitVisitor visitor) { 11 | visitor.visitSoldier(this); 12 | super.accept(visitor); 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "soldier"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /visitor/src/main/java/com/iluwatar/SoldierVisitor.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | public class SoldierVisitor implements UnitVisitor { 4 | 5 | @Override 6 | public void visitSoldier(Soldier soldier) { 7 | System.out.println("Greetings " + soldier); 8 | } 9 | 10 | @Override 11 | public void visitSergeant(Sergeant sergeant) { 12 | // TODO Auto-generated method stub 13 | 14 | } 15 | 16 | @Override 17 | public void visitCommander(Commander commander) { 18 | // TODO Auto-generated method stub 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /visitor/src/main/java/com/iluwatar/Unit.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Interface for the nodes in hierarchy. 6 | * 7 | */ 8 | public abstract class Unit { 9 | 10 | private Unit[] children; 11 | 12 | public Unit(Unit ... children) { 13 | this.children = children; 14 | } 15 | 16 | public void accept(UnitVisitor visitor) { 17 | for (Unit child: children) { 18 | child.accept(visitor); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /visitor/src/main/java/com/iluwatar/UnitVisitor.java: -------------------------------------------------------------------------------- 1 | package com.iluwatar; 2 | 3 | /** 4 | * 5 | * Visitor interface. 6 | * 7 | */ 8 | public interface UnitVisitor { 9 | 10 | void visitSoldier(Soldier soldier); 11 | void visitSergeant(Sergeant sergeant); 12 | void visitCommander(Commander commander); 13 | 14 | } 15 | --------------------------------------------------------------------------------