Skip to content

Commit ba3f583

Browse files
committed
Merge pull request iluwatar#290 from hoswey/master
implements Twin design pattern iluwatar#63
2 parents 5b06c52 + 142274f commit ba3f583

File tree

11 files changed

+305
-0
lines changed

11 files changed

+305
-0
lines changed

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<module>multiton</module>
6969
<module>resource-acquisition-is-initialization</module>
7070
<module>thread-pool</module>
71+
<module>twin</module>
7172
<module>private-class-data</module>
7273
<module>object-pool</module>
7374
<module>dependency-injection</module>

twin/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target/

twin/etc/twin.png

29 KB
Loading

twin/etc/twin.ucls

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
3+
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
4+
<class id="1" language="java" name="com.iluwatar.twin.BallThread" project="twin"
5+
file="/twin/src/main/java/com/iluwatar/twin/BallThread.java" binary="false" corner="BOTTOM_RIGHT">
6+
<position height="-1" width="-1" x="550" y="316"/>
7+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
8+
sort-features="false" accessors="true" visibility="true">
9+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
10+
<operations public="true" package="true" protected="true" private="true" static="true"/>
11+
</display>
12+
</class>
13+
<class id="2" language="java" name="com.iluwatar.twin.BallItem" project="twin"
14+
file="/twin/src/main/java/com/iluwatar/twin/BallItem.java" binary="false" corner="BOTTOM_RIGHT">
15+
<position height="-1" width="-1" x="285" y="315"/>
16+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
17+
sort-features="false" accessors="true" visibility="true">
18+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
19+
<operations public="true" package="true" protected="true" private="true" static="true"/>
20+
</display>
21+
</class>
22+
<class id="3" language="java" name="com.iluwatar.twin.GameItem" project="twin"
23+
file="/twin/src/main/java/com/iluwatar/twin/GameItem.java" binary="false" corner="BOTTOM_RIGHT">
24+
<position height="-1" width="-1" x="285" y="84"/>
25+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
26+
sort-features="false" accessors="true" visibility="true">
27+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
28+
<operations public="true" package="true" protected="true" private="true" static="true"/>
29+
</display>
30+
</class>
31+
<class id="4" language="java" name="java.lang.Thread" project="twin"
32+
file="/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/rt.jar" binary="true"
33+
corner="BOTTOM_RIGHT">
34+
<position height="-1" width="-1" x="550" y="96"/>
35+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
36+
sort-features="false" accessors="true" visibility="true">
37+
<attributes public="false" package="false" protected="false" private="false" static="true"/>
38+
<operations public="false" package="false" protected="false" private="false" static="true"/>
39+
</display>
40+
</class>
41+
<generalization id="5">
42+
<end type="SOURCE" refId="2"/>
43+
<end type="TARGET" refId="3"/>
44+
</generalization>
45+
<association id="6">
46+
<end type="SOURCE" refId="2" navigable="false">
47+
<attribute id="7" name="twin"/>
48+
<multiplicity id="8" minimum="0" maximum="1"/>
49+
</end>
50+
<end type="TARGET" refId="1" navigable="true"/>
51+
<display labels="true" multiplicity="true"/>
52+
</association>
53+
<association id="9">
54+
<end type="SOURCE" refId="4" navigable="false">
55+
<attribute id="10" name="threadQ"/>
56+
<multiplicity id="11" minimum="0" maximum="1"/>
57+
</end>
58+
<end type="TARGET" refId="4" navigable="true"/>
59+
<display labels="true" multiplicity="true"/>
60+
</association>
61+
<association id="12">
62+
<end type="SOURCE" refId="1" navigable="false">
63+
<attribute id="13" name="twin"/>
64+
<multiplicity id="14" minimum="0" maximum="1"/>
65+
</end>
66+
<end type="TARGET" refId="2" navigable="true"/>
67+
<display labels="true" multiplicity="true"/>
68+
</association>
69+
<generalization id="15">
70+
<end type="SOURCE" refId="1"/>
71+
<end type="TARGET" refId="4"/>
72+
</generalization>
73+
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
74+
sort-features="false" accessors="true" visibility="true">
75+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
76+
<operations public="true" package="true" protected="true" private="true" static="true"/>
77+
</classifier-display>
78+
<association-display labels="true" multiplicity="true"/>
79+
</class-diagram>

twin/index.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
layout: pattern
3+
title: Twin
4+
folder: twin
5+
permalink: /patterns/twin/
6+
categories: Creational
7+
tags: Java
8+
---
9+
10+
**Intent:** Twin pattern is a design pattern which provides a standard solution to simulate multiple
11+
inheritance in java
12+
13+
14+
15+
![alt text](./etc/twin.png "Twin")
16+
17+
**Applicability:** Use the Twin idiom when
18+
19+
* to simulate multiple inheritance in a language that does not support this feature.
20+
* to avoid certain problems of multiple inheritance such as name clashes.
21+
22+
**Credits:**
23+
24+
* [Twin – A Design Pattern for Modeling Multiple Inheritance](http://www.ssw.uni-linz.ac.at/Research/Papers/Moe99/Paper.pdf)

twin/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0"?>
2+
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>com.iluwatar</groupId>
7+
<artifactId>java-design-patterns</artifactId>
8+
<version>1.8.0-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>twin</artifactId>
11+
<dependencies>
12+
<dependency>
13+
<groupId>junit</groupId>
14+
<artifactId>junit</artifactId>
15+
<scope>test</scope>
16+
</dependency>
17+
</dependencies>
18+
</project>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.iluwatar.twin;
2+
3+
/**
4+
* Twin pattern is a design pattern which provides a standard solution to simulate multiple
5+
* inheritance in java.
6+
* <p>
7+
* In this example, the essence of the Twin pattern is the {@link BallItem} class and
8+
* {@link BallThread} class represent the twin objects to coordinate with each other(via the twin
9+
* reference) like a single class inheriting from {@link GameItem} and {@link Thread}.
10+
*/
11+
12+
public class App {
13+
14+
/**
15+
* Program entry point
16+
*
17+
* @param args command line args
18+
*/
19+
public static void main(String[] args) throws Exception {
20+
21+
BallItem ballItem = new BallItem();
22+
BallThread ballThread = new BallThread();
23+
24+
ballItem.setTwin(ballThread);
25+
ballThread.setTwin(ballItem);
26+
27+
ballThread.start();
28+
29+
waiting();
30+
31+
ballItem.click();
32+
33+
waiting();
34+
35+
ballItem.click();
36+
37+
waiting();
38+
39+
// exit
40+
ballThread.stopMe();
41+
}
42+
43+
private static void waiting() throws Exception {
44+
Thread.sleep(2500);
45+
}
46+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
package com.iluwatar.twin;
3+
4+
/**
5+
* This class represents a Ball which extends {@link GameItem} and implements the logic for ball
6+
* item, like move and draw. It hold a reference of {@link BallThread} to delegate the suspend and
7+
* resume task.
8+
*/
9+
public class BallItem extends GameItem {
10+
11+
private boolean isSuspended = false;
12+
13+
private BallThread twin;
14+
15+
public void setTwin(BallThread twin) {
16+
this.twin = twin;
17+
}
18+
19+
@Override
20+
public void doDraw() {
21+
22+
System.out.println("doDraw");
23+
}
24+
25+
public void move() {
26+
System.out.println("move");
27+
}
28+
29+
@Override
30+
public void click() {
31+
32+
isSuspended = !isSuspended;
33+
34+
if (isSuspended) {
35+
twin.suspendMe();
36+
} else {
37+
twin.resumeMe();
38+
}
39+
}
40+
}
41+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
2+
package com.iluwatar.twin;
3+
4+
/**
5+
* This class is a UI thread for drawing the {@link BallItem}, and provide the method for suspend
6+
* and resume. It hold the reference of {@link BallItem} to delegate the draw task.
7+
*
8+
*/
9+
10+
public class BallThread extends Thread {
11+
12+
private BallItem twin;
13+
14+
private volatile boolean isSuspended;
15+
16+
private volatile boolean isRunning = true;
17+
18+
public void setTwin(BallItem twin) {
19+
this.twin = twin;
20+
}
21+
22+
public void run() {
23+
24+
while (isRunning) {
25+
while (!isSuspended) {
26+
twin.draw();
27+
twin.move();
28+
try {
29+
Thread.sleep(1000);
30+
} catch (InterruptedException e) {
31+
throw new RuntimeException(e);
32+
}
33+
34+
}
35+
}
36+
}
37+
38+
public void suspendMe() {
39+
isSuspended = true;
40+
System.out.println("Begin to suspend BallThread");
41+
}
42+
43+
public void resumeMe() {
44+
isSuspended = false;
45+
System.out.println("Begin to resume BallThread");
46+
}
47+
48+
public void stopMe() {
49+
this.isRunning = false;
50+
this.isSuspended = true;
51+
}
52+
}
53+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
3+
package com.iluwatar.twin;
4+
5+
/**
6+
* GameItem is a common class which provides some common methods for game object.
7+
*/
8+
public abstract class GameItem {
9+
10+
/**
11+
* Template method, do some common logic before draw
12+
*
13+
* @param other
14+
* @return
15+
*/
16+
public void draw() {
17+
System.out.println("draw");
18+
doDraw();
19+
}
20+
21+
public abstract void doDraw();
22+
23+
24+
public abstract void click();
25+
}

0 commit comments

Comments
 (0)