programmierkonzepte modul - fortgeschrittene · mypackage.klass k = mypackage.klass.create(); as...
TRANSCRIPT
![Page 1: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/1.jpg)
Modul - FortgeschritteneProgrammierkonzepte
Bachelor Informatik
08 - Design Patterns, pt. 2
Prof. Dr. Marcel Tilly
Fakultät für Informatik, Cloud Computing
© Technische Hochschule Rosenheim
![Page 2: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/2.jpg)
Agenda for todayWhat is on the menu for today?
Singleton PatternStrategy PatternFactory PatternCommand Pattern
2 / 45© Technische Hochschule Rosenheim
![Page 3: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/3.jpg)
Singleton - PatternThe task is pretty simple:
How can you ensure that a certain object is unique among your application?
3 / 45© Technische Hochschule Rosenheim
![Page 4: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/4.jpg)
Singleton in JavaIn Java, there are a number of ways to realize that.
1. Restrict access to the constructor! Avoid that someone can create instances.2. The safest thing to do is to make the constructor private.3. If we can only create instances from within the class, we can allocate a static
attribute at startup.
class Singleton { public static final Singleton instance = new Singleton();
private Singleton() {
}}
Singleton.instance.doSomething();
4 / 45© Technische Hochschule Rosenheim
![Page 5: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/5.jpg)
Singleton in JavaThis works if the constructor is trivial, and no further setup of instance isrequired.But what if you need to do some extra work for instance to be ready-to-use? ->The answer is: use a static initializer block.
And one more thing: the public visibility does not allow to guard the instance, e.g. fromsimultaneous access from multiple threads. To �x this, use a getter method.
5 / 45© Technische Hochschule Rosenheim
![Page 6: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/6.jpg)
Singleton in Javaclass Singleton { private final static Singleton instance;
static { instance = new Singleton();
// do more work... }
private Singleton() {
}
public static Singleton getInstance() { // guard if necessary... return instance; }}
Singleton.getInstance().doSomething();
6 / 45© Technische Hochschule Rosenheim
![Page 7: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/7.jpg)
Singleton in JavaThe drawback of this solution is that the singleton is now instantiated at startup, andregardless if it is actually used. To �x this, use a lazy initializer:
class Singleton { private static Singleton instance; // note: no final!
public static Singleton getInstance() { if (instance == null) { instance = new Singleton();
// do more stuff... }
return instance; }
private Singleton() {
}}
Singleton.getInstance().doSomething();
7 / 45© Technische Hochschule Rosenheim
![Page 8: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/8.jpg)
Singleton
Structure and ParticipantsSingleton
static instance: Singleton
Singleton()getInstance(): Singleton
return instance
Singletontypically responsible for managing its unique instanceprovides operation to obtain unique instance (in Java: static method)
8 / 45© Technische Hochschule Rosenheim
![Page 9: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/9.jpg)
Singleton
DiscussionSingletons are standard practice to avoid resource con�icts or overallocation.However, they are at the same time (strongly) disencouraged if working in a multi-threaded (parallel) environment:
while the actual resource con�ict can be (usually) solved with locking,the process itself may dramatically reduce the bene�t of parallel processing.
For advanced developers: Favor dependency injection over singletons.
9 / 45© Technische Hochschule Rosenheim
![Page 10: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/10.jpg)
Singleton
ExamplesLogging facilitiesEvent busses and dispatch queuesDevice handles (there is only 1 physical device, e.g. System.out)Service objects (eg. API wrappers, ...)
10 / 45© Technische Hochschule Rosenheim
![Page 11: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/11.jpg)
Strategy - Pattern
The strategy pattern helps to abstract a certain method from its actualimplementation. It is so fundamental to Java that it has the syntax keywordinterface to separate declarations from implementations.
Do you have an example where you have used a strategy pattern already?
11 / 45© Technische Hochschule Rosenheim
![Page 12: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/12.jpg)
Strategy
Simple Example (Sorting)Sort a list in ascending or descending order, using different Comparator<T>s.
List<Integer> list = new LinkedList<>();list.add(4); list.add(7); list.add(1); list.add(1);
Collections.sort(list, new Comparator<Integer>() { @Override public compare(Integer a, Integer b) { return a.compareTo(b); }});
Collections.sort(list, new Comparator<Integer>() { @Override public compare(Integer a, Integer b) { return b.compareTo(a); // note the flipped order! }});
12 / 45© Technische Hochschule Rosenheim
![Page 13: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/13.jpg)
Strategy
Other Example (Game)Check out JavaKara, a little robot bug that can be moved through a tiny world.
13 / 45© Technische Hochschule Rosenheim
![Page 14: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/14.jpg)
Strategy with KaraHere is a small code snippet to get Kara working:
public class Kara extends JavaKaraProgram { public static void main(String[] args) throws Exception { Kara k = new Kara(); k.run("src/main/resources/world2.world"); }
@Override public void myMainProgram() { kara.move(); // one step forward kara.turnLeft(); // you guessed it... kara.turnRight(); kara.treeFront(); // tree ahead? kara.putLeaf(); // take a clover leaf kara.removeLeav(); // remove a clover leaf }}
What is the strategy to place leafs on every �eld?
14 / 45© Technische Hochschule Rosenheim
![Page 15: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/15.jpg)
StrategyMy Strategy thinking:
To have kara explore the whole room (starting from the center), I could think of twostrategies:
walk concentric growing circles until the room is fully exploredwalk to the top-right corner; then sweep left-to-right, top-to-bottom.
The sample code can be found in https://github.com/hsro-inf-prg3/hsro-inf-prg3.github.io/tree/master/examples/src/main/java/designpattern/strategy.
Check out the StrategyExampleBad, which has two explicit plans,
1. planA() and2. planB().
Contrast it with the implementation in StrategyExample: here, the logic of thestrategy is moved to a separate class which is instantiated as needed.
15 / 45© Technische Hochschule Rosenheim
![Page 16: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/16.jpg)
Strategy
Structure and ParticipantsMechanism to provide different implementations to achieve the same outcome.
Context
Strategy
algorithm()
ConcreteStrategyA
algorithm()
ConcreteStrategyC
algorithm()
ConcreteStrategyB
algorithm()
16 / 45© Technische Hochschule Rosenheim
![Page 17: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/17.jpg)
Strategy
DiscussionThe strategy pattern is used to represent a similar functionality with differentimplementations: For example, the Stream.filter(Predicate<T> p),Iterable.iterator() or Collection.sort(Comparator<T> c).
You can easily spot potential refactoring areas if you have code such as
if (isWav()) return decodeWav(data);else if (isMP3()) return decodeMP3(data);else return data.raw;
with the decode{Wav,MP3}() methods being members of the class. Refactor to thestrategy pattern by extracting them from the class and use them via a commoninterface.
17 / 45© Technische Hochschule Rosenheim
![Page 18: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/18.jpg)
Strategy
ExamplesComparator interface, to customize sortingEncryption and authentication protocolsMedia encoders (mp3, mp4, aac, etc.)Serializers ("save as..." feature)
Do you have other examples?
18 / 45© Technische Hochschule Rosenheim
![Page 19: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/19.jpg)
FactoryA factory provides instances that ful�ll a certain interface.
19 / 45© Technische Hochschule Rosenheim
![Page 20: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/20.jpg)
Factory
Simple ExampleA package with public interfaces but package-private classes.
package mypackage;
public interface Klass { void method();}
package mypackage;
class KlassImpl implements Klass { public void method() { System.out.println("Hello World!"); }}
20 / 45© Technische Hochschule Rosenheim
![Page 21: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/21.jpg)
Factory
Simple ExampleSo from outside the package, you can't instanciate KlassImpl:
package someApp;class MyApp { public static void main(String... args) { mypackage.Klass k = new mypackage.KlassImpl(); // not visible! }}
This is where you need a factory method, often attached to an abstract class or as adefault method to an interface.
21 / 45© Technische Hochschule Rosenheim
![Page 22: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/22.jpg)
Factory
Simple Examplepackage mypackage;
public interface Klass { void method(); default Klass create() { return new KlassImpl(); // inside package: visible! }}
mypackage.Klass k = mypackage.Klass.create();
As you can see, the user of the package relies on the interface, and has no idea onwhich class was actually instantiated.
22 / 45© Technische Hochschule Rosenheim
![Page 23: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/23.jpg)
Factory
Another ExampleRecall the Composite pattern and the strcuture of JSON document and XML:
{ "key": "value", "nested": { "key": "value" }}
<element> <key>value</key> <element> <key>value</key> </element></element>
23 / 45© Technische Hochschule Rosenheim
![Page 24: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/24.jpg)
Factory
Another ExampleWith Java interfaces this could look like:
interface Component { String toString();}
interface Composite extends Component { void add(Component c);}
interface Leaf extends Component {}
24 / 45© Technische Hochschule Rosenheim
![Page 25: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/25.jpg)
Factory
Another ExampleWithout a factory, you would have to manually construct the composite:
JsonComposite root = new JsonComposite("root");root.add(new JsonLeaf("key", "value"));
Composite nested = new JsonComposite("nested");nested.add(new JsonLeaf("key", "value"));root.add(nested);
System.out.println(root);// "root": {"key": "value", "nested": {"key": "value"}}
And similarly for XmlComposite.
25 / 45© Technische Hochschule Rosenheim
![Page 26: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/26.jpg)
Factory
Another ExampleIf you abstract the instance creation into a factory, you could generalize the codesigni�cantly (for JSON and XML):
interface CompositeFactory { Composite createComposite(String name); Leaf createLeaf(String name, String value);}class JsonFactory implements CompositeFactory { @Override public Composite createComposite(String name) { return new JsonComposite(name); } @Override public Leaf createLeaf(String name, String value) { return new JsonLeaf(name, value); }}
26 / 45© Technische Hochschule Rosenheim
![Page 27: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/27.jpg)
Factory
Another ExampleAnd now, you can use it:
CompositeFactory f = new JsonFactory();// CompositeFactory f = new XmlFactory();
Composite root = f.createComposite("root");root.add(f.createLeaf("key", "value"));
Composite nested = f.createComposite("nested");nested.add(f.createLeaf("key", "value"));
root.add(nested);
System.out.println(root);
In case, you want to get the XML representation, you only need to replace the factorythat produces the concrete clases; the construction logic remains the same.
27 / 45© Technische Hochschule Rosenheim
![Page 28: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/28.jpg)
Factory
Structure and ParticipantsStructure to enforce the use of abstract factories and products, by hiding the actualinstantiation of the concrete factory and products.
AbstractFactory
CreateProductA(): AbstractProductACreateProductB(): AbstractProductB
ConcreteFactory1
CreateProductA(): AbstractProductACreateProductB(): AbstractProductB
ConcreteFactory2
CreateProductA(): AbstractProductACreateProductB(): AbstractProductB
AbstractProductA ProductA1
ProductA2
AbstractProductB
ProductB1
ProductB2
client
28 / 45© Technische Hochschule Rosenheim
![Page 29: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/29.jpg)
Factory
Structure and ParticipantsAbstractFactory
declares interface for operations that create the abstract productsConcreteFactory
implements the operations and procudes concrete productsAbstractProduct
declares interface for operationsConcreteProduct
implements the operationsClient
uses only interfaces declared by AbstractFactory andAbstractProduct
29 / 45© Technische Hochschule Rosenheim
![Page 30: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/30.jpg)
Factory
DiscussionThe factory pattern is omnipresent:
sometimes it is realized as a single factory methodsometimes as a larger factory serving different objects.
The most common use is when developing against interfaces where the implementingclasses are package-private.
The package would then expose a factory that allows to generate instances thatimplement the public interfaces -- with internals hidden from the client.
30 / 45© Technische Hochschule Rosenheim
![Page 31: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/31.jpg)
Factory
ExamplesTypically objects that are either complicated to instantiate or which should not beexposed outside of a package.
IteratorsObjects that have complex intantiation protocolsLogging instancesAPI wrappers
31 / 45© Technische Hochschule Rosenheim
![Page 32: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/32.jpg)
CommandMechanism to organize, execute and undo operations on certain objects.
32 / 45© Technische Hochschule Rosenheim
![Page 33: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/33.jpg)
Command
Example - KaraWe could write a program that takes input from the command line and uses that todirect kara around.
public class InteractiveKara extends JavaKaraProgram { public static void main(String[] args) throws IOException { ... try { switch ((char) c) { case 'm': program.kara.move(); break; case 'l': program.kara.turnLeft(); break; case 'r': program.kara.turnRight(); break; case 't': program.kara.removeLeaf(); break; case 'd': program.kara.putLeaf(); break; } } catch (RuntimeException e) { System.out.println(e); System.exit(0); }...
33 / 45© Technische Hochschule Rosenheim
![Page 34: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/34.jpg)
Command
ExampleNote the try ... catch for RuntimeException: this happens if you have karawalk into a tree, or try to pick up a leaf where there is none.
So here is the problem: The above program works nicely until we hit a tree orotherwise raise an exception, at which point the while application is terminated.
Can you think of a mechanism that instead allows us to back-track where we camefrom?
(if we screw up, can we undo the previous moves?)
34 / 45© Technische Hochschule Rosenheim
![Page 35: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/35.jpg)
Command
ExampleNote the try ... catch for RuntimeException: this happens if you have karawalk into a tree, or try to pick up a leaf where there is none.
So here is the problem: The above program works nicely until we hit a tree orotherwise raise an exception, at which point the while application is terminated.
Can you think of a mechanism that instead allows us to back-track where we camefrom?
(if we screw up, can we undo the previous moves?)
We can, if we take care of the following aspects:
for every action, we need to know the reversewe need to keep track of every successful action(optionally) we can manually "forget" our history, if we're at a good place.
35 / 45© Technische Hochschule Rosenheim
![Page 36: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/36.jpg)
Command
ExampleKeeping track of past commands is covered by the command pattern. Instead ofdirectly calling the actions on kara, we make objects that will do the actual work:
interface Command { void execute(); default void undo() { throw new UnsupportedOperationException(); }}
Now, if we keep a journal (stack) of commands, it is easy to go back: just remove themone-by-one and call .undo().
36 / 45© Technische Hochschule Rosenheim
![Page 37: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/37.jpg)
Command
Exampleclass MoveCommand implements Command { private JavaKaraProgram.JavaKara kara; public MoveCommand(JavaKaraProgram.JavaKara kara) { this.kara = kara; } @Override public void execute() { kara.move(); } @Override public void undo() { // turn back, move new TurnCommand(kara, 2).execute(); kara.move(); // turn to original direction new TurnCommand(kara, 2).execute(); }}
37 / 45© Technische Hochschule Rosenheim
![Page 38: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/38.jpg)
Commandpublic class CommandExample extends JavaKaraProgram { public static void main(String[] args) throws IOException { ... // this will keep track of the successful commands Stack<Command> history = new Stack<>(); while ((c = System.in.read()) != -1) { // ... Command cmd = new IdleCommand(); switch ((char) c) { case 'm': cmd = new MoveCommand(program.kara); break; case 'l': cmd = new TurnCommand(program.kara, -1); break; // ... } try { cmd.execute(); history.push(cmd); } catch (RuntimeException e) { // go back to beginning, restart while (history.size() > 0) history.pop().undo(); } }... }}
38 / 45© Technische Hochschule Rosenheim
![Page 39: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/39.jpg)
Command
ExampleThe complete example code can be found at https://github.com/hsro-inf-fpk/hsro-inf-fpk.github.io/tree/master/examples/src/main/java/designpattern/command.
39 / 45© Technische Hochschule Rosenheim
![Page 40: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/40.jpg)
Command: UML
Structure and ParticipantsClient
Invoker
Command
execute()undo()
Receiver
action()
ConcreteCommand
state
execute()undo()
receiver.action()
instantiates
controls
40 / 45© Technische Hochschule Rosenheim
![Page 41: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/41.jpg)
Command
Structure and ParticipantsCommand
declares an interface for executing an operationConcreteCommand
implements the operationuses the receiver as needed
Client (application)creates ConcreteCommand and hands receiver
Invokeractually calls .execute()
Receiverthe object used by the strategy
41 / 45© Technische Hochschule Rosenheim
![Page 42: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/42.jpg)
Command
DiscussionThe command pattern is more frequent than you might initially think. Think of it thisway: whenever you allow the user to sequentially apply certain commands to yourdata/state, you may want to be able to undo those at some point. Building up a stack ofactions automatically leads to adopting the command pattern.
42 / 45© Technische Hochschule Rosenheim
![Page 43: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/43.jpg)
Command
ExamplesEditors that support undo or macrosDatabases with transaction/rollback supportFilesystems with journallingVersion control (eg. git)
43 / 45© Technische Hochschule Rosenheim
![Page 44: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/44.jpg)
SummaryLessons learned for today ...
... the Singleton pattern
... the Factory pattern
... Strategy pattern
... Command pattern
44 / 45© Technische Hochschule Rosenheim
![Page 45: Programmierkonzepte Modul - Fortgeschrittene · mypackage.Klass k = mypackage.Klass.create(); As you can see, the user of the package relies on the interface, and has no idea on which](https://reader034.vdocuments.net/reader034/viewer/2022052019/60332ac47933ea703430be95/html5/thumbnails/45.jpg)
Final Thought!
45 / 45© Technische Hochschule Rosenheim