You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: twin/README.md
+138Lines changed: 138 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -13,6 +13,144 @@ tags:
13
13
Twin pattern is a design pattern which provides a standard solution to simulate multiple
14
14
inheritance in java
15
15
16
+
## Explanation
17
+
18
+
Real-world example
19
+
20
+
> Consider a game with a ball that needs features of two types, Game Item, and threads to function
21
+
> smoothly in the game. We can use two objects, with one object compatible with the first type and
22
+
> the other compatible with the second type.
23
+
> The pair of objects together can function as one ball in the game.
24
+
25
+
In plain words
26
+
27
+
> It provides a way to form two closely coupled sub-classes that can act as a twin class having two ends.
28
+
29
+
Wikipedia says
30
+
31
+
> In software engineering, the Twin pattern is a software design pattern that allows developers
32
+
> to model multiple inheritance in programming languages that do not support multiple inheritance.
33
+
> This pattern avoids many of the problems with multiple inheritance.
34
+
35
+
**Programmatic Example**
36
+
37
+
Take our game ball example from above. Consider we have a game in which the ball needs to be both a `GameItem` and `Thread`.
38
+
First of all, we have the `GameItem` class given below and the `Thread` class.
39
+
40
+
41
+
```java
42
+
43
+
@Slf4j
44
+
publicabstractclassGameItem {
45
+
46
+
publicvoiddraw() {
47
+
LOGGER.info("draw");
48
+
doDraw();
49
+
}
50
+
51
+
publicabstractvoiddoDraw();
52
+
53
+
54
+
publicabstractvoidclick();
55
+
}
56
+
57
+
```
58
+
59
+
Then, we have subclasses `BallItem` and `BallThread` inheriting them, respectively.
60
+
61
+
```java
62
+
63
+
@Slf4j
64
+
publicclassBallItemextendsGameItem {
65
+
66
+
privateboolean isSuspended;
67
+
68
+
@Setter
69
+
privateBallThread twin;
70
+
71
+
@Override
72
+
publicvoiddoDraw() {
73
+
74
+
LOGGER.info("doDraw");
75
+
}
76
+
77
+
publicvoidmove() {
78
+
LOGGER.info("move");
79
+
}
80
+
81
+
@Override
82
+
publicvoidclick() {
83
+
84
+
isSuspended =!isSuspended;
85
+
86
+
if (isSuspended) {
87
+
twin.suspendMe();
88
+
} else {
89
+
twin.resumeMe();
90
+
}
91
+
}
92
+
}
93
+
94
+
95
+
@Slf4j
96
+
publicclassBallThreadextendsThread {
97
+
98
+
@Setter
99
+
privateBallItem twin;
100
+
101
+
privatevolatileboolean isSuspended;
102
+
103
+
privatevolatileboolean isRunning =true;
104
+
105
+
/**
106
+
* Run the thread.
107
+
*/
108
+
publicvoidrun() {
109
+
110
+
while (isRunning) {
111
+
if (!isSuspended) {
112
+
twin.draw();
113
+
twin.move();
114
+
}
115
+
try {
116
+
Thread.sleep(250);
117
+
} catch (InterruptedException e) {
118
+
thrownewRuntimeException(e);
119
+
}
120
+
}
121
+
}
122
+
123
+
publicvoidsuspendMe() {
124
+
isSuspended =true;
125
+
LOGGER.info("Begin to suspend BallThread");
126
+
}
127
+
128
+
publicvoidresumeMe() {
129
+
isSuspended =false;
130
+
LOGGER.info("Begin to resume BallThread");
131
+
}
132
+
133
+
publicvoidstopMe() {
134
+
this.isRunning =false;
135
+
this.isSuspended =true;
136
+
}
137
+
}
138
+
139
+
```
140
+
141
+
Now, when we need the ball, we can instantiate objects from both the `BallThread` and `BallItem` as a pair and pass them to its pair object so they can act together as appropriate.
0 commit comments