Compare commits
7 Commits
all-contri
...
all-contri
Author | SHA1 | Date | |
---|---|---|---|
|
40f3112072 | ||
|
cb81d4e8eb | ||
|
221daf5d74 | ||
|
90b1b922e1 | ||
|
bd71bc1311 | ||
|
54d19d4c87 | ||
|
464b166fa3 |
@@ -16,6 +16,17 @@
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ohbus",
|
||||
"name": "Subhrodip Mohanta",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/13291222?v=4",
|
||||
"profile": "http://subho.xyz",
|
||||
"contributions": [
|
||||
"code",
|
||||
"review",
|
||||
"maintenance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "amit1307",
|
||||
"name": "amit1307",
|
||||
@@ -1125,17 +1136,6 @@
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ohbus",
|
||||
"name": "Subhrodip Mohanta",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/13291222?v=4",
|
||||
"profile": "http://subho.xyz",
|
||||
"contributions": [
|
||||
"code",
|
||||
"review",
|
||||
"maintenance"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "nahteb",
|
||||
"name": "Bethan Palmer",
|
||||
@@ -1658,6 +1658,42 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "carldea",
|
||||
"name": "Carl Dea",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1594624?v=4",
|
||||
"profile": "http://carlfx.wordpress.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Mozartuss",
|
||||
"name": "Mozartus",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/32893711?v=4",
|
||||
"profile": "https://github.com/Mozartuss",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ManviGoel26",
|
||||
"name": "Manvi Goel",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/55682355?v=4",
|
||||
"profile": "https://github.com/ManviGoel26",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "blueberry404",
|
||||
"name": "Anum Amin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/39243539?v=4",
|
||||
"profile": "https://github.com/blueberry404",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
12
README.md
12
README.md
@@ -10,7 +10,7 @@
|
||||
[](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
|
||||
[](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
[](#contributors-)
|
||||
[](#contributors-)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
|
||||
<br/>
|
||||
@@ -78,8 +78,8 @@ This project is licensed under the terms of the MIT license.
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/iluwatar"><img src="https://avatars1.githubusercontent.com/u/582346?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ilkka Seppälä</b></sub></a><br /><a href="#projectManagement-iluwatar" title="Project Management">📆</a> <a href="#maintenance-iluwatar" title="Maintenance">🚧</a> <a href="#content-iluwatar" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="http://subho.xyz"><img src="https://avatars0.githubusercontent.com/u/13291222?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Subhrodip Mohanta</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=ohbus" title="Code">💻</a> <a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3Aohbus" title="Reviewed Pull Requests">👀</a> <a href="#maintenance-ohbus" title="Maintenance">🚧</a></td>
|
||||
<td align="center"><a href="https://github.com/npathai"><img src="https://avatars2.githubusercontent.com/u/1792515?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Narendra Pathai</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=npathai" title="Code">💻</a> <a href="#ideas-npathai" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3Anpathai" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://github.com/amit1307"><img src="https://avatars0.githubusercontent.com/u/23420222?v=4?s=100" width="100px;" alt=""/><br /><sub><b>amit1307</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=amit1307" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/npathai"><img src="https://avatars2.githubusercontent.com/u/1792515?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Narendra Pathai</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=npathai" title="Code">💻</a> <a href="#ideas-npathai" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/iluwatar/java-design-patterns/pulls?q=is%3Apr+reviewed-by%3Anpathai" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://github.com/fluxw42"><img src="https://avatars1.githubusercontent.com/u/1545460?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jeroen Meulemeester</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=fluxw42" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://www.joemccarthy.co.uk"><img src="https://avatars0.githubusercontent.com/u/4526195?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Joseph McCarthy</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=mikulucky" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/thomasoss"><img src="https://avatars1.githubusercontent.com/u/22516154?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Thomas</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=thomasoss" title="Code">💻</a></td>
|
||||
@@ -193,8 +193,8 @@ This project is licensed under the terms of the MIT license.
|
||||
<td align="center"><a href="https://github.com/hoswey"><img src="https://avatars3.githubusercontent.com/u/3689445?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hoswey</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=hoswey" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/gwildor28"><img src="https://avatars0.githubusercontent.com/u/16000365?v=4?s=100" width="100px;" alt=""/><br /><sub><b>gwildor28</b></sub></a><br /><a href="#content-gwildor28" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://github.com/amit2103"><img src="https://avatars3.githubusercontent.com/u/7566692?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Amit Pandey</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=amit2103" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/gwildor28"><img src="https://avatars0.githubusercontent.com/u/16000365?v=4?s=100" width="100px;" alt=""/><br /><sub><b>gwildor28</b></sub></a><br /><a href="#content-gwildor28" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://t.me/paul_docker"><img src="https://avatars1.githubusercontent.com/u/2404785?v=4?s=100" width="100px;" alt=""/><br /><sub><b>田浩</b></sub></a><br /><a href="#content-llitfkitfk" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://twitter.com/StPitsios"><img src="https://avatars1.githubusercontent.com/u/6773603?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stamatis Pitsios</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=pitsios-s" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/qza"><img src="https://avatars3.githubusercontent.com/u/233149?v=4?s=100" width="100px;" alt=""/><br /><sub><b>qza</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=qza" title="Code">💻</a></td>
|
||||
@@ -309,6 +309,12 @@ This project is licensed under the terms of the MIT license.
|
||||
<td align="center"><a href="https://programacionymas.com"><img src="https://avatars.githubusercontent.com/u/3101238?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JCarlos</b></sub></a><br /><a href="#translation-JCarlosR" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://www.mrmoshkel.ir"><img src="https://avatars.githubusercontent.com/u/60359433?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ali Ghasemi</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=Dev-AliGhasemi" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="http://carlfx.wordpress.com"><img src="https://avatars.githubusercontent.com/u/1594624?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Carl Dea</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=carldea" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/Mozartuss"><img src="https://avatars.githubusercontent.com/u/32893711?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mozartus</b></sub></a><br /><a href="#translation-Mozartuss" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/ManviGoel26"><img src="https://avatars.githubusercontent.com/u/55682355?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Manvi Goel</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=ManviGoel26" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/blueberry404"><img src="https://avatars.githubusercontent.com/u/39243539?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Anum Amin</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=blueberry404" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
|
138
twin/README.md
138
twin/README.md
@@ -13,6 +13,144 @@ tags:
|
||||
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
|
||||
public abstract class GameItem {
|
||||
|
||||
public void draw() {
|
||||
LOGGER.info("draw");
|
||||
doDraw();
|
||||
}
|
||||
|
||||
public abstract void doDraw();
|
||||
|
||||
|
||||
public abstract void click();
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Then, we have subclasses `BallItem` and `BallThread` inheriting them, respectively.
|
||||
|
||||
```java
|
||||
|
||||
@Slf4j
|
||||
public class BallItem extends GameItem {
|
||||
|
||||
private boolean isSuspended;
|
||||
|
||||
@Setter
|
||||
private BallThread twin;
|
||||
|
||||
@Override
|
||||
public void doDraw() {
|
||||
|
||||
LOGGER.info("doDraw");
|
||||
}
|
||||
|
||||
public void move() {
|
||||
LOGGER.info("move");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click() {
|
||||
|
||||
isSuspended = !isSuspended;
|
||||
|
||||
if (isSuspended) {
|
||||
twin.suspendMe();
|
||||
} else {
|
||||
twin.resumeMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class BallThread extends Thread {
|
||||
|
||||
@Setter
|
||||
private BallItem twin;
|
||||
|
||||
private volatile boolean isSuspended;
|
||||
|
||||
private volatile boolean isRunning = true;
|
||||
|
||||
/**
|
||||
* Run the thread.
|
||||
*/
|
||||
public void run() {
|
||||
|
||||
while (isRunning) {
|
||||
if (!isSuspended) {
|
||||
twin.draw();
|
||||
twin.move();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(250);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void suspendMe() {
|
||||
isSuspended = true;
|
||||
LOGGER.info("Begin to suspend BallThread");
|
||||
}
|
||||
|
||||
public void resumeMe() {
|
||||
isSuspended = false;
|
||||
LOGGER.info("Begin to resume BallThread");
|
||||
}
|
||||
|
||||
public void stopMe() {
|
||||
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.
|
||||
|
||||
```java
|
||||
|
||||
var ballItem = new BallItem();
|
||||
var ballThread = new BallThread();
|
||||
|
||||
ballItem.setTwin(ballThread);
|
||||
ballThread.setTwin(ballItem);
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||
|
@@ -214,6 +214,12 @@ Use the Visitor pattern when
|
||||
* Many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them.
|
||||
* The classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes.
|
||||
|
||||
## Tutorials
|
||||
|
||||
* [Refactoring Guru](https://refactoring.guru/design-patterns/visitor)
|
||||
* [Dzone](https://dzone.com/articles/design-patterns-visitor)
|
||||
* [Sourcemaking](https://sourcemaking.com/design_patterns/visitor)
|
||||
|
||||
## Known uses
|
||||
|
||||
* [Apache Wicket](https://github.com/apache/wicket) component tree, see [MarkupContainer](https://github.com/apache/wicket/blob/b60ec64d0b50a611a9549809c9ab216f0ffa3ae3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java)
|
||||
|
Reference in New Issue
Block a user