Twin pattern is a design pattern which provides a standard solution to simulate multiple
inheritance in java
## Explanation
Real-world example
> Consider a game with a ball that needs features of two types, Game Item, and threads to function
> smoothly in the game. We can use two objects, with one object compatible with the first type and
> the other compatible with the second type.
> The pair of objects together can function as one ball in the game.
In plain words
> It provides a way to form two closely coupled sub-classes that can act as a twin class having two ends.
Wikipedia says
> In software engineering, the Twin pattern is a software design pattern that allows developers
> to model multiple inheritance in programming languages that do not support multiple inheritance.
> This pattern avoids many of the problems with multiple inheritance.
**Programmatic Example**
Take our game ball example from above. Consider we have a game in which the ball needs to be both a `GameItem` and `Thread`.
First of all, we have the `GameItem` class given below and the `Thread` class.
```java
@Slf4j
publicabstractclassGameItem{
publicvoiddraw(){
LOGGER.info("draw");
doDraw();
}
publicabstractvoiddoDraw();
publicabstractvoidclick();
}
```
Then, we have subclasses `BallItem` and `BallThread` inheriting them, respectively.
```java
@Slf4j
publicclassBallItemextendsGameItem{
privatebooleanisSuspended;
@Setter
privateBallThreadtwin;
@Override
publicvoiddoDraw(){
LOGGER.info("doDraw");
}
publicvoidmove(){
LOGGER.info("move");
}
@Override
publicvoidclick(){
isSuspended=!isSuspended;
if(isSuspended){
twin.suspendMe();
}else{
twin.resumeMe();
}
}
}
@Slf4j
publicclassBallThreadextendsThread{
@Setter
privateBallItemtwin;
privatevolatilebooleanisSuspended;
privatevolatilebooleanisRunning=true;
/**
* Run the thread.
*/
publicvoidrun(){
while(isRunning){
if(!isSuspended){
twin.draw();
twin.move();
}
try{
Thread.sleep(250);
}catch(InterruptedExceptione){
thrownewRuntimeException(e);
}
}
}
publicvoidsuspendMe(){
isSuspended=true;
LOGGER.info("Begin to suspend BallThread");
}
publicvoidresumeMe(){
isSuspended=false;
LOGGER.info("Begin to resume BallThread");
}
publicvoidstopMe(){
this.isRunning=false;
this.isSuspended=true;
}
}
```
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.