From 7c2ce9dd5d89d4e6ddcbe402dd218db596754644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=20G=C3=B3mez?= Date: Tue, 14 May 2019 20:27:51 +0200 Subject: [PATCH 1/4] Replace Stub per ObjectMother --- .gitignore | 2 +- .../CodelyTvStaffUsersRepository.java | 8 ++++---- .../{UserStub.java => UserMother.java} | 2 +- .../stage_3_dependency_inversion/UserSearcherShould.java | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/{UserStub.java => UserMother.java} (95%) diff --git a/.gitignore b/.gitignore index 11756d0..937d2fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # Gradle .gradle build/ - +/out # Ignore Gradle GUI config gradle-app.setting diff --git a/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/CodelyTvStaffUsersRepository.java b/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/CodelyTvStaffUsersRepository.java index 256f317..1a4c7f7 100644 --- a/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/CodelyTvStaffUsersRepository.java +++ b/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/CodelyTvStaffUsersRepository.java @@ -7,13 +7,13 @@ import java.util.Map; import java.util.Optional; -// ℹ️ User repository for test usage. It is used as a _Test double_, more specifically, it's a _Stub_. -// More info on the difference between Stubs and Mocks: https://martinfowler.com/articles/mocksArentStubs.html +// ℹ️ User repository for test usage. It is used as a _Test double_, more specifically, it's a _Mother_. +// More info on the difference between Mothers and Mocks: https://martinfowler.com/articles/mocksArentMothers.html final class CodelyTvStaffUsersRepository implements UsersRepository { private Map users = Collections.unmodifiableMap(new HashMap() { { - put(UserStub.RAFA_ID, UserStub.rafa()); - put(UserStub.JAVI_ID, UserStub.javi()); + put(UserMother.RAFA_ID, UserMother.rafa()); + put(UserMother.JAVI_ID, UserMother.javi()); } }); diff --git a/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserStub.java b/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserMother.java similarity index 95% rename from src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserStub.java rename to src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserMother.java index 71a55fc..e202cd5 100644 --- a/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserStub.java +++ b/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserMother.java @@ -2,7 +2,7 @@ import tv.codely.solid_principles.dependency_inversion_principle.User; -final class UserStub { +final class UserMother { static final int RAFA_ID = 1; static final int JAVI_ID = 2; diff --git a/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserSearcherShould.java b/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserSearcherShould.java index 293455d..3adb170 100644 --- a/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserSearcherShould.java +++ b/src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_3_dependency_inversion/UserSearcherShould.java @@ -21,9 +21,9 @@ void find_existing_users() { UsersRepository codelyTvStaffUsersRepository = new CodelyTvStaffUsersRepository(); UserSearcher userSearcher = new UserSearcher(codelyTvStaffUsersRepository); - Optional expectedUser = Optional.of(UserStub.rafa()); + Optional expectedUser = Optional.of(UserMother.rafa()); - assertEquals(expectedUser, userSearcher.search(UserStub.RAFA_ID)); + assertEquals(expectedUser, userSearcher.search(UserMother.RAFA_ID)); } @Test From 04ba85b4846d6875cdb85e92d66e5a648435497a Mon Sep 17 00:00:00 2001 From: Javier Ferrer Date: Fri, 23 Aug 2019 10:02:07 +0200 Subject: [PATCH 2/4] Update Gradle + Add logger + Set GitHub Workflow --- .editorconfig | 11 ++++ .github/workflows/workflow.yml | 20 +++++++ .gitignore | 2 + .travis.yml | 34 +++++++++++ Makefile | 9 +++ README.md | 57 +++++++++++++++++-- bitbucket-pipelines.yml | 12 ---- build.gradle | 19 +++---- gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 2 +- gradlew.bat | 2 +- .../UserSearcher.java | 3 +- src/main/resources/log4j2.properties | 34 +++++++++++ src/test/resources/log4j2.properties | 33 +++++++++++ var/log/.gitkeep | 0 15 files changed, 207 insertions(+), 34 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/workflow.yml create mode 100644 .travis.yml create mode 100644 Makefile delete mode 100644 bitbucket-pipelines.yml create mode 100644 src/main/resources/log4j2.properties create mode 100644 src/test/resources/log4j2.properties create mode 100644 var/log/.gitkeep diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..219e4cd --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.java] +indent_size = 4 +indent_style = space diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml new file mode 100644 index 0000000..27e6577 --- /dev/null +++ b/.github/workflows/workflow.yml @@ -0,0 +1,20 @@ +name: Main Workflow + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Assemble + run: ./gradlew assemble --warning-mode all + - name: Check + run: ./gradlew check --warning-mode all + diff --git a/.gitignore b/.gitignore index 937d2fe..1b3ab03 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ build/ # Ignore Gradle GUI config gradle-app.setting +var/log/* +!var/log/.gitkeep diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..865538e --- /dev/null +++ b/.travis.yml @@ -0,0 +1,34 @@ +language: java + +jdk: + - openjdk11 + - oraclejdk11 + +os: + - linux + - osx + +before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock + - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ + +cache: + directories: + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ + +# Run commands before TravisCI install step only in some cases +# More info: https://docs.travis-ci.com/user/multi-os/#example-multi-os-build-matrix +before_install: + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi + +# Override default install process on TravisCI +# Avoid default `gradlew assemble` execution. Be explicit about it on the `script` section. +# More info: https://github.com/travis-ci/travis-ci/issues/8667 +install: true + +# Build pipeline +# Compile before running the tests in order to easily check which task could be failing. +script: + - ./gradlew assemble --warning-mode all + - ./gradlew check --warning-mode all diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bcc4bd1 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +.PONY: all build test + +all: build + +build: + @./gradlew assemble --warning-mode all + +test: + @./gradlew check --warning-mode all diff --git a/README.md b/README.md index 874b90b..a0a25f1 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,56 @@ -# SOLID principles examples in Java +# ☕⚛ SOLID principles examples in Java -## How to start + + + +> ⚛ Learn SOLID principles by examples + +[![CodelyTV](https://img.shields.io/badge/codely-tv-green.svg?style=flat-square)](https://codely.tv) +[![Workflow Status](https://github.com/CodelyTV/java-solid-examples/workflows/Main%20Workflow/badge.svg)](https://github.com/CodelyTV/java-basic-skeleton/actions) + +## ℹ️ Introduction + +This is a repository intended to serve as illustrative examples for the course ["Principios SOLID Aplicados" (Spanish)](https://pro.codely.tv/library/principios-solid-aplicados/77070/about/?utm_source=github&utm_medium=social&utm_campaign=java-solid-examples). + +## 🏁 How To Start + +1. Install Java 8: `brew cask install corretto8` +2. Set it as your default JVM: `export JAVA_HOME='/Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home'` +3. Clone this repository: `git clone https://github.com/CodelyTV/java-solid-examples`. +4. Execute some [Gradle lifecycle tasks](https://docs.gradle.org/current/userguide/java_plugin.html#lifecycle_tasks) in order to check everything is OK: + 1. Create [the project JAR](https://docs.gradle.org/current/userguide/java_plugin.html#sec:jar): `make build` + 2. Run the tests and plugins verification tasks: `make test` +5. Start playing around with the different examples of each SOLID principle. You have explanations here and in the test code 🙂 + +## ☝️ How to update dependencies + +* Gradle (current version: 5.6 - [releases](https://gradle.org/releases/)): +`./gradlew wrapper --gradle-version=5.6 --distribution-type=bin` or modifying the [gradle-wrapper.properties](gradle/wrapper/gradle-wrapper.properties#L3) +* JUnit (current version: 5.5.1 - [releases](https://junit.org/junit5/docs/snapshot/release-notes/index.html)): +[`build.gradle:11`](build.gradle#L11-L12) + +## 💡 Related repositories + +### ☕ Java + +* 📂 [Java Basic Skeleton](https://github.com/CodelyTV/java-basic-skeleton) +* ⚛ [Java OOP Examples](https://github.com/CodelyTV/java-oop-examples) +* 🧱 [Java SOLID Examples](https://github.com/CodelyTV/java-solid-examples) +* 🥦 [Java DDD Example](https://github.com/CodelyTV/java-ddd-example) + +### 🐘 PHP + +* 📂 [PHP Basic Skeleton](https://github.com/CodelyTV/php-basic-skeleton) +* 🎩 [PHP DDD Skeleton](https://github.com/CodelyTV/php-ddd-skeleton) +* 🥦 [PHP DDD Example](https://github.com/CodelyTV/php-ddd-example) + +### 🧬 Scala + +* 📂 [Scala Basic Skeleton](https://github.com/CodelyTV/scala-basic-skeleton) +* ⚡ [Scala Basic Skeleton (g8 template)](https://github.com/CodelyTV/scala-basic-skeleton.g8) +* ⚛ [Scala Examples](https://github.com/CodelyTV/scala-examples) +* 🥦 [Scala DDD Example](https://github.com/CodelyTV/scala-ddd-example) -1. Install Java 8 -2. Clone this repository `git clone https://github.com/CodelyTV/solid-principles-java-examples`. -3. Run the tests with `./gradlew test` -4. Start playing around with the different examples of each SOLID principle. You have the explanations in the test code 🙂 ## Liskov Substitution Principle (LSP) diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml deleted file mode 100644 index 303fdae..0000000 --- a/bitbucket-pipelines.yml +++ /dev/null @@ -1,12 +0,0 @@ -image: java:8 - -options: - max-time: 10 - -pipelines: - default: - - step: - caches: - - gradle - script: - - bash ./gradlew build diff --git a/build.gradle b/build.gradle index a117d9c..aa1ed95 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,18 @@ apply plugin: 'java' +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + repositories { mavenCentral() } dependencies { - testCompile('org.junit.jupiter:junit-jupiter-api:5.2.0') - testRuntime('org.junit.jupiter:junit-jupiter-engine:5.2.0') + implementation 'org.apache.logging.log4j:log4j-core:2.12.1' + implementation 'com.vlkan.log4j2:log4j2-logstash-layout:0.19' + + testCompile 'org.junit.jupiter:junit-jupiter-api:5.5.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.1' } test { @@ -15,13 +21,4 @@ test { testLogging { events "passed", "skipped", "failed" } - - reports { - html.enabled = true - } } - -task wrapper(type: Wrapper) { - description = 'Generates gradlew[.bat] scripts' - gradleVersion = '4.6' -} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 556b934..ef9a9e0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 01 07:06:45 CEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/gradlew b/gradlew index 6e5d9ef..cccdd3d 100755 --- a/gradlew +++ b/gradlew @@ -169,4 +169,4 @@ if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then cd "$(dirname "$0")" fi -exec "$JAVACMD" "$@" \ No newline at end of file +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index dee787c..f955316 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -81,4 +81,4 @@ exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal -:omega \ No newline at end of file +:omega diff --git a/src/main/java/tv/codely/solid_principles/dependency_inversion_principle/stage_1_instantiating_from_clients/UserSearcher.java b/src/main/java/tv/codely/solid_principles/dependency_inversion_principle/stage_1_instantiating_from_clients/UserSearcher.java index 84cee80..c265f7e 100644 --- a/src/main/java/tv/codely/solid_principles/dependency_inversion_principle/stage_1_instantiating_from_clients/UserSearcher.java +++ b/src/main/java/tv/codely/solid_principles/dependency_inversion_principle/stage_1_instantiating_from_clients/UserSearcher.java @@ -5,7 +5,8 @@ import java.util.Optional; final class UserSearcher { - private HardcodedInMemoryUsersRepository usersRepository = new HardcodedInMemoryUsersRepository(); + private HardcodedInMemoryUsersRepository usersRepository = + new HardcodedInMemoryUsersRepository(); public Optional search(Integer id) { return usersRepository.search(id); diff --git a/src/main/resources/log4j2.properties b/src/main/resources/log4j2.properties new file mode 100644 index 0000000..83ab852 --- /dev/null +++ b/src/main/resources/log4j2.properties @@ -0,0 +1,34 @@ +name = CodelyTvJavaSolidExamples +property.filename = logs +appenders = console, file + +status = warn + +appender.console.name = CONSOLE +appender.console.type = CONSOLE +appender.console.target = SYSTEM_OUT + +appender.console.logstash.type = LogstashLayout +appender.console.logstash.dateTimeFormatPattern = yyyy-MM-dd'T'HH:mm:ss.SSSZZZ +appender.console.logstash.eventTemplateUri = classpath:LogstashJsonEventLayoutV1.json +appender.console.logstash.prettyPrintEnabled = true +appender.console.logstash.stackTraceEnabled = true + +appender.file.type = File +appender.file.name = LOGFILE +appender.file.fileName=var/log/java-solid-examples.log +appender.file.logstash.type=LogstashLayout +appender.file.logstash.dateTimeFormatPattern = yyyy-MM-dd'T'HH:mm:ss.SSSZZZ +appender.file.logstash.eventTemplateUri = classpath:LogstashJsonEventLayoutV1.json +appender.file.logstash.prettyPrintEnabled = false +appender.file.logstash.stackTraceEnabled = true + +loggers = file +logger.file.name = tv.codely.solid_principles +logger.file.level = info +logger.file.appenderRefs = file +logger.file.appenderRef.file.ref = LOGFILE + +rootLogger.level = info +rootLogger.appenderRefs = stdout +rootLogger.appenderRef.stdout.ref = CONSOLE diff --git a/src/test/resources/log4j2.properties b/src/test/resources/log4j2.properties new file mode 100644 index 0000000..cc28ef9 --- /dev/null +++ b/src/test/resources/log4j2.properties @@ -0,0 +1,33 @@ +name = CodelyTvJavaSolidExamples +property.filename = logs +appenders = console, file + +status = warn + +appender.console.name = CONSOLE +appender.console.type = CONSOLE +appender.console.target = SYSTEM_OUT + +appender.console.layout.type = PatternLayout +appender.console.layout.pattern = [%level] [%date{HH:mm:ss.SSS}] [%class{0}#%method:%line] %message \(%mdc\) %n%throwable +appender.console.filter.threshold.type = ThresholdFilter +appender.console.filter.threshold.level = info + +appender.file.type = File +appender.file.name = LOGFILE +appender.file.fileName=var/log/java-solid-examples-test.log +appender.file.logstash.type=LogstashLayout +appender.file.logstash.dateTimeFormatPattern = yyyy-MM-dd'T'HH:mm:ss.SSSZZZ +appender.file.logstash.eventTemplateUri = classpath:LogstashJsonEventLayoutV1.json +appender.file.logstash.prettyPrintEnabled = false +appender.file.logstash.stackTraceEnabled = true + +loggers = file +logger.file.name = tv.codely.solid_principles +logger.file.level = info +logger.file.appenderRefs = file +logger.file.appenderRef.file.ref = LOGFILE + +rootLogger.level = info +rootLogger.appenderRefs = stdout +rootLogger.appenderRef.stdout.ref = CONSOLE diff --git a/var/log/.gitkeep b/var/log/.gitkeep new file mode 100644 index 0000000..e69de29 From 91caa608e2041d89e85c3b1e6dfaa026a71c5378 Mon Sep 17 00:00:00 2001 From: Javier Ferrer Date: Fri, 23 Aug 2019 10:05:12 +0200 Subject: [PATCH 3/4] Fix GitHub Workflow badge link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a0a25f1..43dab19 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > ⚛ Learn SOLID principles by examples [![CodelyTV](https://img.shields.io/badge/codely-tv-green.svg?style=flat-square)](https://codely.tv) -[![Workflow Status](https://github.com/CodelyTV/java-solid-examples/workflows/Main%20Workflow/badge.svg)](https://github.com/CodelyTV/java-basic-skeleton/actions) +[![Workflow Status](https://github.com/CodelyTV/java-solid-examples/workflows/Main%20Workflow/badge.svg)](https://github.com/CodelyTV/java-solid-examples/actions) ## ℹ️ Introduction From 44600ce024ef957a05e0c4fbe9a76b283b0f84a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=20G=C3=B3mez?= Date: Wed, 7 Sep 2022 16:06:02 +0200 Subject: [PATCH 4/4] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 33c018b..08f7725 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 CodelyTV staff@codely.tv +Copyright (c) 2018 CodelyTV Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal