diff --git a/pom.xml b/pom.xml index 3c86ed57e..4419fb98a 100644 --- a/pom.xml +++ b/pom.xml @@ -68,6 +68,7 @@ multiton resource-acquisition-is-initialization thread-pool + twin private-class-data object-pool dependency-injection diff --git a/twin/.gitignore b/twin/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/twin/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/twin/etc/twin.png b/twin/etc/twin.png new file mode 100644 index 000000000..724092525 Binary files /dev/null and b/twin/etc/twin.png differ diff --git a/twin/etc/twin.ucls b/twin/etc/twin.ucls new file mode 100644 index 000000000..6948dbf6a --- /dev/null +++ b/twin/etc/twin.ucls @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/twin/index.md b/twin/index.md new file mode 100644 index 000000000..241c31f58 --- /dev/null +++ b/twin/index.md @@ -0,0 +1,20 @@ +--- +layout: pattern +title: Twin +folder: twin +permalink: /patterns/twin/ +categories: Creational +tags: Java +--- + +**Intent:** Twin pattern is a design pattern which provides a standard solution to simulate multiple +inheritance in java + + + +![alt text](./etc/twin.png "Twin") + +**Applicability:** Use the Twin idiom when + +* to simulate multiple inheritance in a language that does not support this feature. +* to avoid certain problems of multiple inheritance such as name clashes. \ No newline at end of file diff --git a/twin/pom.xml b/twin/pom.xml new file mode 100644 index 000000000..c2a4b131b --- /dev/null +++ b/twin/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.8.0-SNAPSHOT + + twin + + + junit + junit + test + + + diff --git a/twin/src/main/java/com/iluwatar/twin/App.java b/twin/src/main/java/com/iluwatar/twin/App.java new file mode 100644 index 000000000..4ecba711f --- /dev/null +++ b/twin/src/main/java/com/iluwatar/twin/App.java @@ -0,0 +1,53 @@ +package com.iluwatar.twin; + +/** + * Twin pattern is a design pattern which provides a standard solution to simulate multiple + * inheritance in java. + * + *

+ * In this example, there is a ball game, a ball needs to subclass {@link GameItem} which provide + * some common method like draw and click. Moreover, it needs to subclass {@link Thread} as ball is + * a moving item (we use {@link Thread} instead of implements {@link Runnable} for example only) + *

+ * Threre is scenario, when user click the ball, the ball will stop, when user click it gain, it + * will resume to move. We create two class, ons is {@link BallItem} which subclass {@link GameItem} + * , another is {@link BallThread} which subclass {@link Thread}. These two object both hold a field + * named "Twin" reference to another object. In {@link BallItem#click()}, it will invoke + * {@link BallThread} to suspend or resume moving; in {@link BallThread#run()}, it will invoke + * {@link BallItem} for drawing. + * + */ +public class App { + + /** + * Program entry point + * + * @param args command line args + */ + public static void main(String[] args) throws Exception { + + BallItem ballItem = new BallItem(); + BallThread ballThread = new BallThread(); + + ballItem.setTwin(ballThread); + ballThread.setTwin(ballItem); + + ballThread.start(); + + waiting(); + + ballItem.click(); + + waiting(); + + ballItem.click(); + + waiting(); + + ballThread.stopMe(); + } + + private static void waiting() throws Exception { + Thread.sleep(2500); + } +} diff --git a/twin/src/main/java/com/iluwatar/twin/BallItem.java b/twin/src/main/java/com/iluwatar/twin/BallItem.java new file mode 100644 index 000000000..b95dc06ee --- /dev/null +++ b/twin/src/main/java/com/iluwatar/twin/BallItem.java @@ -0,0 +1,41 @@ + +package com.iluwatar.twin; + +/** + * This class represents a Ball which extends {@link GameItem} and implements the logic for ball + * item, like move and draw. It hold a reference of {@link BallThread} to delegate the suspend and + * resume task. + */ +public class BallItem extends GameItem { + + private boolean isSuspended = false; + + private BallThread twin; + + public void setTwin(BallThread twin) { + this.twin = twin; + } + + @Override + public void doDraw() { + + System.out.println("doDraw"); + } + + public void move() { + System.out.println("move"); + } + + @Override + public void click() { + + isSuspended = !isSuspended; + + if (isSuspended) { + twin.suspendMe(); + } else { + twin.resumeMe(); + } + } +} + diff --git a/twin/src/main/java/com/iluwatar/twin/BallThread.java b/twin/src/main/java/com/iluwatar/twin/BallThread.java new file mode 100644 index 000000000..dae537e64 --- /dev/null +++ b/twin/src/main/java/com/iluwatar/twin/BallThread.java @@ -0,0 +1,53 @@ + +package com.iluwatar.twin; + +/** + * This class is a UI thread for drawing the {@link BallItem}, and provide the method for suspend + * and resume. It hold the reference of {@link BallItem} to delegate the draw task. + * + */ + +public class BallThread extends Thread { + + private BallItem twin; + + private volatile boolean isSuspended; + + private volatile boolean isRunning = true; + + public void setTwin(BallItem twin) { + this.twin = twin; + } + + public void run() { + + while (isRunning) { + while (!isSuspended) { + twin.draw(); + twin.move(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + } + } + } + + public void suspendMe() { + isSuspended = true; + System.out.println("Begin to suspend BallThread"); + } + + public void resumeMe() { + isSuspended = false; + System.out.println("Begin to resume BallThread"); + } + + public void stopMe() { + this.isRunning = false; + this.isSuspended = true; + } +} + diff --git a/twin/src/main/java/com/iluwatar/twin/GameItem.java b/twin/src/main/java/com/iluwatar/twin/GameItem.java new file mode 100644 index 000000000..d797eda95 --- /dev/null +++ b/twin/src/main/java/com/iluwatar/twin/GameItem.java @@ -0,0 +1,25 @@ + + +package com.iluwatar.twin; + +/** + * GameItem is a common class which provides some common methods for game object. + */ +public abstract class GameItem { + + /** + * Template method, do some common logic before draw + * + * @param other + * @return + */ + public void draw() { + System.out.println("draw"); + doDraw(); + } + + public abstract void doDraw(); + + + public abstract void click(); +} diff --git a/twin/src/test/java/com/iluwatar/twin/AppTest.java b/twin/src/test/java/com/iluwatar/twin/AppTest.java new file mode 100644 index 000000000..94e178254 --- /dev/null +++ b/twin/src/test/java/com/iluwatar/twin/AppTest.java @@ -0,0 +1,17 @@ +package com.iluwatar.twin; + +import org.junit.Test; + +/** + * + * Application test + * + */ +public class AppTest { + + @Test + public void test() throws Exception { + String[] args = {}; + App.main(args); + } +}