Skip to content

Commit 142fe8b

Browse files
committed
2 parents 8b08728 + 17d019f commit 142fe8b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+98
-66
lines changed

leader-followers/src/main/java/com/iluwatar/leaderfollowers/App.java

+14-57
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,13 @@
1-
/*
2-
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3-
*
4-
* The MIT License
5-
* Copyright © 2014-2022 Ilkka Seppälä
6-
*
7-
* Permission is hereby granted, free of charge, to any person obtaining a copy
8-
* of this software and associated documentation files (the "Software"), to deal
9-
* in the Software without restriction, including without limitation the rights
10-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11-
* copies of the Software, and to permit persons to whom the Software is
12-
* furnished to do so, subject to the following conditions:
13-
*
14-
* The above copyright notice and this permission notice shall be included in
15-
* all copies or substantial portions of the Software.
16-
*
17-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23-
* THE SOFTWARE.
24-
*/
251
package com.iluwatar.leaderfollowers;
262

273
import java.security.SecureRandom;
284
import java.util.concurrent.Executors;
295
import java.util.concurrent.TimeUnit;
6+
import lombok.extern.slf4j.Slf4j;
307

31-
/**
32-
* Leader/Followers pattern is a concurrency pattern. This pattern behaves like a taxi stand where
33-
* one of the threads acts as leader thread which listens for event from event sources,
34-
* de-multiplexes, dispatches and handles the event. It promotes the follower to be the new leader.
35-
* When processing completes the thread joins the followers queue, if there are no followers then it
36-
* becomes the leader and cycle repeats again.
37-
*
38-
* <p>In this example, one of the workers becomes Leader and listens on the {@link TaskSet} for
39-
* work. {@link TaskSet} basically acts as the source of input events for the {@link Worker}, who
40-
* are spawned and controlled by the {@link WorkCenter} . When {@link Task} arrives then the leader
41-
* takes the work and calls the {@link TaskHandler}. It also calls the {@link WorkCenter} to
42-
* promotes one of the followers to be the new leader, who can then process the next work and so on.
43-
*
44-
* <p>The pros for this pattern are: It enhances CPU cache affinity and eliminates unbound
45-
* allocation and data buffer sharing between threads by reading the request into buffer space
46-
* allocated on the stack of the leader or by using the Thread-Specific Storage pattern [22] to
47-
* allocate memory. It minimizes locking overhead by not exchanging data between threads, thereby
48-
* reducing thread synchronization. In bound handle/thread associations, the leader thread
49-
* dispatches the event based on the I/O handle. It can minimize priority inversion because no extra
50-
* queuing is introduced in the server. It does not require a context switch to handle each event,
51-
* reducing the event dispatching latency. Note that promoting a follower thread to fulfill the
52-
* leader role requires a context switch. Programming simplicity: The Leader/Followers pattern
53-
* simplifies the programming of concurrency models where multiple threads can receive requests,
54-
* process responses, and de-multiplex connections using a shared handle set.
55-
*/
8+
@Slf4j
569
public class App {
5710

58-
/** The main method for the leader followers pattern. */
5911
public static void main(String[] args) throws InterruptedException {
6012
var taskSet = new TaskSet();
6113
var taskHandler = new TaskHandler();
@@ -64,18 +16,23 @@ public static void main(String[] args) throws InterruptedException {
6416
execute(workCenter, taskSet);
6517
}
6618

67-
/** Start the work, dispatch tasks and stop the thread pool at last. */
6819
private static void execute(WorkCenter workCenter, TaskSet taskSet) throws InterruptedException {
6920
var workers = workCenter.getWorkers();
7021
var exec = Executors.newFixedThreadPool(workers.size());
71-
workers.forEach(exec::submit);
72-
Thread.sleep(1000);
73-
addTasks(taskSet);
74-
exec.awaitTermination(2, TimeUnit.SECONDS);
75-
exec.shutdownNow();
22+
23+
try {
24+
workers.forEach(exec::submit);
25+
Thread.sleep(1000);
26+
addTasks(taskSet);
27+
boolean terminated = exec.awaitTermination(2, TimeUnit.SECONDS);
28+
if (!terminated) {
29+
LOGGER.warn("Executor did not terminate in the given time.");
30+
}
31+
} finally {
32+
exec.shutdownNow();
33+
}
7634
}
7735

78-
/** Add tasks. */
7936
private static void addTasks(TaskSet taskSet) throws InterruptedException {
8037
var rand = new SecureRandom();
8138
for (var i = 0; i < 5; i++) {

saga/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ Wikipedia says
3131

3232
> Long-running transactions (also known as the saga interaction pattern) are computer database transactions that avoid locks on non-local resources, use compensation to handle failures, potentially aggregate smaller ACID transactions (also referred to as atomic transactions), and typically use a coordinator to complete or abort the transaction. In contrast to rollback in ACID transactions, compensation restores the original state, or an equivalent, and is business-specific. For example, the compensating action for making a hotel reservation is canceling that reservation.
3333
34+
Flowchart
35+
36+
![Saga flowchart](./etc/saga-flowchart.png)
37+
3438
## Programmatic Example of Saga Pattern in Java
3539

3640
The Saga design pattern is a sequence of local transactions where each transaction updates data within a single service. It's particularly useful in a microservices architecture where each service has its own database. The Saga pattern ensures data consistency and fault tolerance across services. Here are the key components of the Saga pattern:

saga/etc/saga-flowchart.png

70.5 KB
Loading

separated-interface/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ In plain words
3131

3232
> Defines a client interface separate from its implementation to allow for flexible and interchangeable components.
3333
34+
Sequence diagram
35+
36+
![Separated Interface sequence diagram](./etc/separated-interface-sequence-diagram.png)
37+
3438
## Programmatic Example of Separated Interface Pattern in Java
3539

3640
The Java Separated Interface design pattern is a crucial software architecture strategy that promotes separating the interface definition from its implementation, crucial for enhancing system flexibility and scalability. This allows the client to be completely unaware of the implementation, promoting loose coupling and enhancing flexibility.
Loading

serialized-entity/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ Wikipedia says
3232

3333
> In computing, serialization is the process of translating a data structure or object state into a format that can be stored (e.g. files in secondary storage devices, data buffers in primary storage devices) or transmitted (e.g. data streams over computer networks) and reconstructed later (possibly in a different computer environment). When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object. For many complex objects, such as those that make extensive use of references, this process is not straightforward. Serialization of objects does not include any of their associated methods with which they were previously linked.
3434
35+
Flowchart
36+
37+
![Serialized Entity flowchart](./etc/serialized-entity-flowchart.png)
38+
3539
## Programmatic Example of Serialized Entity Pattern in Java
3640

3741
The Serialized Entity design pattern is a way to easily persist Java objects to the database. It uses the `Serializable` interface and the DAO (Data Access Object) pattern. The pattern first uses `Serializable` to convert a Java object into a set of bytes, then it uses the DAO pattern to store this set of bytes as a BLOB (Binary Large OBject) in the database.
Loading

serialized-lob/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ In plain words
3030

3131
> The Serialized LOB design pattern manages the storage of large objects, such as files or multimedia, by serializing and storing them directly within a database.
3232
33+
Flowchart
34+
35+
![Serialized LOB flowchart](./etc/serialized-lob-flowchart.png)
36+
3337
## Programmatic Example of Serialized LOB Pattern in Java
3438

3539
The Serialized Large Object (LOB) design pattern is a way to handle large objects in a database. It involves serializing an object graph into a single large object (a BLOB or CLOB, for Binary Large Object or Character Large Object, respectively) and storing it in the database. When the object graph needs to be retrieved, it is read from the database and deserialized back into the original object graph.
39.5 KB
Loading

servant/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ Wikipedia says
3434

3535
> In software engineering, the servant pattern defines an object used to offer some functionality to a group of classes without defining that functionality in each of them. A Servant is a class whose instance (or even just class) provides methods that take care of a desired service, while objects for which (or with whom) the servant does something, are taken as parameters.
3636
37+
Sequence diagram
38+
39+
![Servant sequence diagram](./etc/servant-sequence-diagram.png)
40+
3741
## Programmatic Example of Servant Pattern in Java
3842

3943
The Servant design pattern is a behavioral design pattern that defines a class that provides some sort of service to a group of classes. This pattern is particularly useful when these classes lack some common functionality that can't be added to the superclass. The Servant class brings this common functionality to a group of classes.
69.6 KB
Loading

server-session/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ Wikipedia says
3434

3535
> A session token is a unique identifier that is generated and sent from a server to a client to identify the current interaction session. The client usually stores and sends the token as an HTTP cookie and/or sends it as a parameter in GET or POST queries. The reason to use session tokens is that the client only has to handle the identifier—all session data is stored on the server (usually in a database, to which the client does not have direct access) linked to that identifier.
3636
37+
Sequence diagram
38+
39+
![Server Session sequence diagram](./etc/server-session-sequence-diagram.png)
40+
3741
## Programmatic Example of Server Session Pattern in Java
3842

3943
The Server Session design pattern is a behavioral design pattern that assigns the responsibility of storing session data on the server side. This pattern is particularly useful in the context of stateless protocols like HTTP where all requests are isolated events independent of previous requests.
Loading

service-layer/README.md

-5
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ Architecture diagram
4040

4141
![Service Layer Architecture Diagram](./etc/service-layer-architecture-diagram.png)
4242

43-
4443
## Programmatic Example of Service Layer Pattern in Java
4544

4645
Our Java implementation uses the Service Layer pattern to streamline interactions between data access objects (DAOs) and the business logic, ensuring a clean separation of concerns.
@@ -358,10 +357,6 @@ INFO [2024-05-27 09:16:40,681] com.iluwatar.servicelayer.app.App: Find wizards
358357
INFO [2024-05-27 09:16:40,683] com.iluwatar.servicelayer.app.App: Aderlard Boud has 'Fireball'
359358
```
360359

361-
## Detailed Explanation of Service Layer Pattern with Real-World Examples
362-
363-
![Service Layer](./etc/service-layer.png "Service Layer")
364-
365360
## When to Use the Service Layer Pattern in Java
366361

367362
* Use when you need to separate business logic from presentation logic.

service-locator/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ Wikipedia says
3333

3434
> The service locator pattern is a design pattern used in software development to encapsulate the processes involved in obtaining a service with a strong abstraction layer. This pattern uses a central registry known as the "service locator", which on request returns the information necessary to perform a certain task. Proponents of the pattern say the approach simplifies component-based applications where all dependencies are cleanly listed at the beginning of the whole application design, consequently making traditional dependency injection a more complex way of connecting objects. Critics of the pattern argue that it is an antipattern which obscures dependencies and makes software harder to test.
3535
36+
Sequence diagram
37+
38+
![Service Locator sequence diagram](./etc/service-locator-sequence-diagram.png)
39+
3640
## Programmatic Example of Service Locator Pattern in Java
3741

3842
The Service Locator design pattern is used to abstract the processes involved in obtaining a service. It uses a central registry, the "service locator", which returns the necessary information to perform a task upon request. This Java design pattern is particularly useful in enterprise Java applications where services need centralized management.
Loading

service-stub/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ Wikipedia says
3434

3535
> A test stub is a dummy component used during testing to isolate behavior.
3636
37+
Sequence diagram
38+
39+
![Service Stub sequence diagram](./etc/service-stub-sequence-diagram.png)
40+
3741
## Programmatic Example of Service Stub Pattern in Java
3842

3943
We define a `SentimentAnalysisService` interface and provide two implementations:
Loading

service-to-worker/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ In plain words
2626

2727
> Separates the processing logic from the view in web applications to improve maintainability and scalability.
2828
29+
Sequence diagram
30+
31+
![Service to Worker sequence diagram](./etc/service-to-worker-sequence-diagram.png)
32+
2933
## Programmatic Example of Service to Worker Pattern in Java
3034

3135
The Service to Worker design pattern separates the processing logic from the view in web applications to improve maintainability and scalability. It combines the Dispatcher View and Service Locator patterns to facilitate the separation of processing, control flow, and view management in web applications.
Loading

session-facade/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ In plain words
3434

3535
> The Session Facade design pattern is an excellent choice for decoupling complex components of the system that need to be interacting frequently.
3636
37+
Sequence diagram
38+
39+
![Session Facade sequence diagram](./etc/session-facade-sequence-diagram.png)
40+
3741
## Programmatic Example of Session Facade Pattern in Java
3842

3943
The Session Facade design pattern is a structural design pattern that provides a simplified interface to a set of complex subsystems, reducing the complexity for the client. This pattern is particularly useful in situations where the client needs to interact with multiple services or systems but doesn’t need to know the internal workings of each service.
Loading

sharding/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ Wikipedia says
3535
>
3636
> There are numerous advantages to the horizontal partitioning approach. Since the tables are divided and distributed into multiple servers, the total number of rows in each table in each database is reduced. This reduces index size, which generally improves search performance. A database shard can be placed on separate hardware, and multiple shards can be placed on multiple machines. This enables a distribution of the database over a large number of machines, greatly improving performance. In addition, if the database shard is based on some real-world segmentation of the data (e.g., European customers v. American customers) then it may be possible to infer the appropriate shard membership easily and automatically, and query only the relevant shard.
3737
38+
Flowchart
39+
40+
![Sharding flowchart](./etc/sharding-flowchart.png)
41+
3842
## Programmatic Example of Sharding Pattern in Java
3943

4044
Sharding is a type of database partitioning that separates very large databases into smaller, faster, more easily managed parts called data shards. The word shard means a small part of a whole. In software architecture, it refers to a horizontal partition in a database or search engine. Each individual partition is referred to as a shard or database shard.

sharding/etc/sharding-flowchart.png

68.1 KB
Loading

single-table-inheritance/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ Wikipedia says
3636

3737
> Single table inheritance is a way to emulate object-oriented inheritance in a relational database. When mapping from a database table to an object in an object-oriented language, a field in the database identifies what class in the hierarchy the object belongs to. All fields of all the classes are stored in the same table, hence the name "Single Table Inheritance".
3838
39+
Flowchart
40+
41+
![Single Table Inheritance flowchart](./etc/single-table-inheritance-flowchart.png)
42+
3943
## Programmatic Example of Single Table Inheritance Pattern in Java
4044

4145
Single Table Inheritance is a design pattern that maps an inheritance hierarchy of classes to a single database table. Each row in the table represents an instance of a class in the hierarchy. A special discriminator column is used to identify the class to which each row belongs.
Loading

singleton/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ Wikipedia says
3333

3434
> In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.
3535
36+
Sequence diagram
37+
38+
![Singleton Pattern sequence diagram](./etc/singleton-sequence-diagram.png)
39+
3640
## Programmatic Example of Singleton Pattern in Java
3741

3842
Joshua Bloch, Effective Java 2nd Edition p.18
51.8 KB
Loading

spatial-partition/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ Wikipedia says
3939
>
4040
> For example, in ray tracing, space partitioning helps quickly determine the objects a ray might intersect by narrowing down the search space, leading to faster rendering times. Similarly, in game development, Quadtrees can efficiently manage 2D game environments by segmenting the space into smaller regions, facilitating quicker collision detection and rendering.
4141
42+
Flowchart
43+
44+
![Spatial Partition flowchart](./etc/spatial-partition-flowchart.png)
45+
4246
## Programmatic Example of Spatial Partition Pattern in Java
4347

4448
The Spatial Partition design pattern in Java is a strategic approach for handling multiple objects in expansive game worlds or detailed simulation environments, boosting query efficiency and operational speed. It allows us to efficiently manage these objects and perform operations like collision detection or range queries. The pattern works by dividing the space into smaller, manageable regions, and each object is associated with the region it belongs to. This way, we can limit our operations to a specific region, instead of checking every object against every other object.
Loading

special-case/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ In [Patterns of Enterprise Application Architecture](https://amzn.to/3WfKBPR) Ma
3737

3838
> If you’ll pardon the unresistable pun, I see [Null Object](https://java-design-patterns.com/patterns/null-object/) as special case of Special Case.
3939
40+
Sequnce diagram
41+
42+
![Special Case sequence diagram](./etc/special-case-sequence-diagram.png)
43+
4044
## Programmatic Example of Special Case Pattern in Java
4145

4246
The Special Case Pattern is a software design pattern that is used to handle a specific, often uncommon, case separately from the general case in the code. This pattern is useful when a class has behavior that requires conditional logic based on its state. Instead of cluttering the class with conditional logic, we can encapsulate the special behavior in a subclass.
Loading

specification/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ Wikipedia says
3737

3838
> In computer programming, the specification pattern is a particular software design pattern, whereby business rules can be recombined by chaining the business rules together using boolean logic.
3939
40+
Flowchart
41+
42+
![Specification Pattern flowchart](./etc/specification-flowchart.png)
43+
4044
## Programmatic Example of Specification Pattern in Java
4145

4246
Let's consider a creature pool example. We have a collection of creatures with specific properties. These properties might belong to a predefined, limited set (represented by enums like `Size`, `Movement`, and `Color`) or they might be continuous values (e.g., the mass of a `Creature`). In cases with continuous values, it's better to use a "parameterized specification," where the property value is provided as an argument when the `Creature` is instantiated, allowing for greater flexibility. Additionally, predefined and/or parameterized properties can be combined using boolean logic, offering almost limitless selection possibilities (this is known as a "composite specification," explained further below). The advantages and disadvantages of each approach are detailed in the table at the end of this document.
57 KB
Loading

0 commit comments

Comments
 (0)