Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
fb324c3
Increase observer test reliability
lpenap Jun 11, 2025
c55a70e
Merge pull request #4 from lpenap/codex/remove-travis-integration-and…
lpenap Jun 11, 2025
786ec55
Add GitHub workflows for PR and master builds
lpenap Jun 11, 2025
4b5d842
Update merged_master.yml
lpenap Jun 11, 2025
faaaaad
Add JaCoCo config for coverage badge generation in github action
lpenap Jun 11, 2025
6bc5f81
Merge pull request #5 from lpenap/codex/add-github-actions-for-jdk-21…
lpenap Jun 11, 2025
3c2e677
Autogenerated JaCoCo coverage badge
lpenap Jun 11, 2025
1637bb5
Add maven build badge status and generated coverage
lpenap Jun 11, 2025
1584b7e
Add GUI log output
lpenap Jun 11, 2025
d902989
Update pull_request.yml to use java zulu distribution
lpenap Jun 11, 2025
a2899bd
Add Factory and Abstract Factory patterns
lpenap Jun 11, 2025
34863f1
Add Template Method design pattern example
lpenap Jun 11, 2025
c0c0a20
Add GUI log appender tests
lpenap Jun 11, 2025
2c8d3e7
Merge pull request #8 from lpenap/codex/add-design-pattern-implementa…
lpenap Jun 11, 2025
7201bd7
Merge pull request #7 from lpenap/codex/add-factory-and-abstract-fact…
lpenap Jun 11, 2025
3978077
Autogenerated JaCoCo coverage badge
lpenap Jun 11, 2025
d2e3da5
Fix GuiAppender test for headless env
lpenap Jun 11, 2025
7fdf8a7
Merge pull request #6 from lpenap/codex/add-scrolling-text-area-for-o…
lpenap Jun 11, 2025
ee742ac
Autogenerated JaCoCo coverage badge
lpenap Jun 11, 2025
e88c577
Add Adapter and Decorator pattern examples
lpenap Jun 16, 2025
c46ffe7
Merge pull request #9 from lpenap/codex/implement-remaining-design-pa…
lpenap Jun 16, 2025
4e84b7b
Autogenerated JaCoCo coverage badge
lpenap Jun 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/badges/branches.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions .github/badges/jacoco.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions .github/workflows/merged_master.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: maven build

on:
pull_request:
types: [closed]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'zulu'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml

- name: Generate JaCoCo Badge
uses: cicirello/jacoco-badge-generator@v2
with:
generate-branches-badge: true

- name: Log coverage percentage
run: |
echo "coverage = ${{ steps.jacoco.outputs.coverage }}"
echo "branch coverage = ${{ steps.jacoco.outputs.branches }}"

- name: Commit the badge (if it changed)
run: |
if [[ `git status --porcelain` ]]; then
git config --global user.name 'Luis'
git config --global user.email 'lpenap@users.noreply.github.com'
git add -A
git commit -m "Autogenerated JaCoCo coverage badge"
git push
fi

- name: Upload JaCoCo coverage report
uses: actions/upload-artifact@v4
with:
name: jacoco-report
path: target/site/jacoco/
18 changes: 18 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: PR Build

on:
pull_request:
branches: ['**']

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '21'
- name: Build and Test
run: ./mvnw -B verify
2 changes: 1 addition & 1 deletion .mvn/wrapper/MavenWrapperDownloader.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class MavenWrapperDownloader {
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL =
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar";
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar";

/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
Expand Down
2 changes: 1 addition & 1 deletion .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
6 changes: 0 additions & 6 deletions .travis.yml

This file was deleted.

13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[![codebeat badge](https://codebeat.co/badges/4c328c5d-1722-459f-aaa1-437a0ed6201f)](https://codebeat.co/projects/github-com-lpenap-java-patterns-and-constructs-master)
[![Build Status](https://travis-ci.org/lpenap/java-patterns-and-constructs.svg)](https://travis-ci.org/lpenap/java-patterns-and-constructs)
[![maven build](https://github.com/lpenap/java-patterns-and-constructs/actions/workflows/merged_master.yml/badge.svg)](https://github.com/lpenap/java-patterns-and-constructs/actions/workflows/merged_master.yml)
[![GitHub release](https://img.shields.io/github/release/lpenap/java-patterns-and-constructs)](//github.com/lpenap/java-patterns-and-constructs/releases/latest)
[![codebeat badge](https://codebeat.co/badges/4c328c5d-1722-459f-aaa1-437a0ed6201f)](https://codebeat.co/projects/github-com-lpenap-java-patterns-and-constructs-master)
![Coverage](.github/badges/jacoco.svg)

# Java Design Patterns and Constructs
Collection of patterns and other constructs in Java for educational purposes. (See *Contributing* section if you would like to contribute).

## Quickstart
* Install a Java 11 implementation (like openjdk11)
* Install a Java 21 implementation (like openjdk21)
* Clone and run the spring-boot maven goal:
```bash
git clone https://github.com/lpenap/java-patterns-and-constructs
Expand All @@ -15,9 +16,15 @@ cd java-patterns-and-constructs
```
## Da List
### Patterns
* [Abstract Factory](src/main/java/com/penapereira/example/constructs/abstractfactory/)
* [Adapter](src/main/java/com/penapereira/example/constructs/adapter/)
* [Decorator](src/main/java/com/penapereira/example/constructs/decorator/)
* [Factory](src/main/java/com/penapereira/example/constructs/factory/)
* [Factory Method](src/main/java/com/penapereira/example/constructs/factorymethod/)
* [Observer](src/main/java/com/penapereira/example/constructs/observer/)
* [Singleton](src/main/java/com/penapereira/example/constructs/singleton/)
* [Strategy](src/main/java/com/penapereira/example/constructs/strategy/)
* [Template Method](src/main/java/com/penapereira/example/constructs/templatemethod/)
### Constructs and Problems
* [Producer/Consumer](src/main/java/com/penapereira/example/constructs/producerconsumer/), a multi-process synchronization problem.

Expand Down
86 changes: 70 additions & 16 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<groupId>com.penapereira</groupId>
<artifactId>java-patterns-and-constructs</artifactId>
<version>0.0.2</version>
<name>java-patterns-and-constructs</name>
<description>Collection of patterns and other constructs in Java</description>

<properties>
<java.version>11</java.version>
</properties>
<java.version>21</java.version>
</properties>

<dependencies>
<dependency>
Expand Down Expand Up @@ -47,13 +47,67 @@
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>generate-code-coverage-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>0.90</minimum>
</limit>
</limits>
</rule>
</rules>
<excludes>
<exclude>**/*ExampleRunner*</exclude>
<exclude>**/AppCommandLineRunner*</exclude>
<exclude>**/ExamplesCommandLineRunner*</exclude>
<exclude>**/ProducerConsumerExampleRunner*</exclude>
<exclude>**/Consumer*</exclude>
<exclude>**/JavaPatternsAndConstructsApplication*</exclude>
<exclude>**/MainWindow*</exclude>
<exclude>**/Messages*</exclude>
<exclude>**/ApplicationProperties*</exclude>
<exclude>**/HyperlinkMouseListener*</exclude>
<exclude>**/ObservableAbstract*</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.penapereira.example.constructs.abstractfactory;

public interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.penapereira.example.constructs.abstractfactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.penapereira.example.constructs.app.ExampleRunnerInterface;

@Component
public class AbstractFactoryExampleRunner implements ExampleRunnerInterface {

private static final Logger log =
LoggerFactory.getLogger(AbstractFactoryExampleRunner.class);

@Override
public void runExample() throws Exception {
log.trace("Executing Abstract Factory Pattern Implementation:");

AbstractFactory factory1 = new Factory1();
AbstractFactory factory2 = new Factory2();

log.trace(" " + factory1.createProductA().name());
log.trace(" " + factory1.createProductB().name());

log.trace(" " + factory2.createProductA().name());
log.trace(" " + factory2.createProductB().name());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.penapereira.example.constructs.abstractfactory;

public class Factory1 implements AbstractFactory {

@Override
public ProductA createProductA() {
return new ProductA1();
}

@Override
public ProductB createProductB() {
return new ProductB1();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.penapereira.example.constructs.abstractfactory;

public class Factory2 implements AbstractFactory {

@Override
public ProductA createProductA() {
return new ProductA2();
}

@Override
public ProductB createProductB() {
return new ProductB2();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.penapereira.example.constructs.abstractfactory;

public interface ProductA {
String name();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.penapereira.example.constructs.abstractfactory;

public class ProductA1 implements ProductA {

@Override
public String name() {
return "ProductA1";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.penapereira.example.constructs.abstractfactory;

public class ProductA2 implements ProductA {

@Override
public String name() {
return "ProductA2";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.penapereira.example.constructs.abstractfactory;

public interface ProductB {
String name();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.penapereira.example.constructs.abstractfactory;

public class ProductB1 implements ProductB {

@Override
public String name() {
return "ProductB1";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.penapereira.example.constructs.abstractfactory;

public class ProductB2 implements ProductB {

@Override
public String name() {
return "ProductB2";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.penapereira.example.constructs.adapter;

public class Adaptee {
public String specificRequest() {
return "Adaptee";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.penapereira.example.constructs.adapter;

public class Adapter implements Target {
private final Adaptee adaptee;

public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}

@Override
public String request() {
return "Adapter(" + adaptee.specificRequest() + ")";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.penapereira.example.constructs.adapter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.penapereira.example.constructs.app.ExampleRunnerInterface;

@Component
public class AdapterExampleRunner implements ExampleRunnerInterface {

private static final Logger log = LoggerFactory.getLogger(AdapterExampleRunner.class);

@Override
public void runExample() throws Exception {
log.trace("Executing Adapter Pattern Implementation");

Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);

log.trace(" " + target.request());
}
}
Loading