mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 10:58:42 +00:00
docs: update twin
This commit is contained in:
+70
-9
@@ -75,7 +75,9 @@ public class BallItem extends GameItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
@Slf4j
|
||||
public class BallThread extends Thread {
|
||||
@Setter
|
||||
@@ -117,25 +119,85 @@ public class BallThread extends Thread {
|
||||
To use these classes together:
|
||||
|
||||
```java
|
||||
var ballItem = new BallItem();
|
||||
var ballThread = new BallThread();
|
||||
public class App {
|
||||
|
||||
ballItem.setTwin(ballThread);
|
||||
ballThread.setTwin(ballItem);
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
var ballItem = new BallItem();
|
||||
var ballThread = new BallThread();
|
||||
|
||||
ballItem.setTwin(ballThread);
|
||||
ballThread.setTwin(ballItem);
|
||||
|
||||
ballThread.start();
|
||||
|
||||
waiting();
|
||||
|
||||
ballItem.click();
|
||||
|
||||
waiting();
|
||||
|
||||
ballItem.click();
|
||||
|
||||
waiting();
|
||||
|
||||
// exit
|
||||
ballThread.stopMe();
|
||||
}
|
||||
|
||||
private static void waiting() throws Exception {
|
||||
Thread.sleep(750);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Let's break down what happens in `App`.
|
||||
|
||||
1. An instance of `BallItem` and `BallThread` are created.
|
||||
2. The `BallItem` and `BallThread` instances are set as twins of each other. This means that each instance has a reference to the other.
|
||||
3. The `BallThread` is started. This begins the execution of the `run` method in the `BallThread` class, which continuously calls the `draw` and `move` methods of the `BallItem` (its twin) as long as the `BallThread` is not suspended.
|
||||
4. The program waits for 750 milliseconds. This is done to allow the `BallThread` to execute its `run` method a few times.
|
||||
5. The `click` method of the `BallItem` is called. This toggles the `isSuspended` state of the `BallItem` and its twin `BallThread`. If the `BallThread` was running, it gets suspended. If it was suspended, it resumes running.
|
||||
6. Steps 4 and 5 are repeated twice. This means the `BallThread` is suspended and resumed once.
|
||||
7. Finally, the `stopMe` method of the `BallThread` is called to stop its execution.
|
||||
|
||||
Console output:
|
||||
|
||||
```
|
||||
14:29:33.778 [Thread-0] INFO com.iluwatar.twin.GameItem -- draw
|
||||
14:29:33.780 [Thread-0] INFO com.iluwatar.twin.BallItem -- doDraw
|
||||
14:29:33.780 [Thread-0] INFO com.iluwatar.twin.BallItem -- move
|
||||
14:29:34.035 [Thread-0] INFO com.iluwatar.twin.GameItem -- draw
|
||||
14:29:34.035 [Thread-0] INFO com.iluwatar.twin.BallItem -- doDraw
|
||||
14:29:34.035 [Thread-0] INFO com.iluwatar.twin.BallItem -- move
|
||||
14:29:34.291 [Thread-0] INFO com.iluwatar.twin.GameItem -- draw
|
||||
14:29:34.291 [Thread-0] INFO com.iluwatar.twin.BallItem -- doDraw
|
||||
14:29:34.291 [Thread-0] INFO com.iluwatar.twin.BallItem -- move
|
||||
14:29:34.533 [main] INFO com.iluwatar.twin.BallThread -- Begin to suspend BallThread
|
||||
14:29:35.285 [main] INFO com.iluwatar.twin.BallThread -- Begin to resume BallThread
|
||||
14:29:35.308 [Thread-0] INFO com.iluwatar.twin.GameItem -- draw
|
||||
14:29:35.308 [Thread-0] INFO com.iluwatar.twin.BallItem -- doDraw
|
||||
14:29:35.308 [Thread-0] INFO com.iluwatar.twin.BallItem -- move
|
||||
14:29:35.564 [Thread-0] INFO com.iluwatar.twin.GameItem -- draw
|
||||
14:29:35.564 [Thread-0] INFO com.iluwatar.twin.BallItem -- doDraw
|
||||
14:29:35.565 [Thread-0] INFO com.iluwatar.twin.BallItem -- move
|
||||
14:29:35.817 [Thread-0] INFO com.iluwatar.twin.GameItem -- draw
|
||||
14:29:35.817 [Thread-0] INFO com.iluwatar.twin.BallItem -- doDraw
|
||||
14:29:35.817 [Thread-0] INFO com.iluwatar.twin.BallItem -- move
|
||||
```
|
||||
|
||||
This setup allows `BallItem` and `BallThread` to act together as a single cohesive unit in the game, leveraging the capabilities of both `GameItem` and `Thread` without multiple inheritance.
|
||||
|
||||
## Class diagram
|
||||
|
||||

|
||||
|
||||
## Applicability
|
||||
|
||||
* Use when you need to decouple classes that share common functionality but cannot inherit from a common base class due to various reasons such as the use of different frameworks or languages.
|
||||
* Useful in performance-critical applications where inheritance might introduce unnecessary overhead.
|
||||
* Applicable in systems requiring resilience through the ability to replace or update one of the twins without affecting the other.
|
||||
|
||||
## Tutorials
|
||||
|
||||
* [Twin – A Design Pattern for Modeling Multiple Inheritance (Hanspeter Mössenböck)](http://www.ssw.uni-linz.ac.at/Research/Papers/Moe99/Paper.pdf)
|
||||
|
||||
## Known Uses
|
||||
|
||||
* User interfaces where different frameworks are used for rendering and logic.
|
||||
@@ -165,4 +227,3 @@ Trade-offs:
|
||||
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)
|
||||
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3yhh525)
|
||||
* [Patterns of Enterprise Application Architecture](https://amzn.to/3WfKBPR)
|
||||
* [Twin – A Design Pattern for Modeling Multiple Inheritance - Hanspeter Mössenböck](http://www.ssw.uni-linz.ac.at/Research/Papers/Moe99/Paper.pdf)
|
||||
|
||||
Reference in New Issue
Block a user