├── README.md ├── courses-examples └── behavioral-design-patterns-course │ ├── chain-of-responsibility │ ├── command-bus-middleware │ │ ├── README.md │ │ └── java │ │ │ ├── .editorconfig │ │ │ ├── .env │ │ │ ├── .github │ │ │ └── workflows │ │ │ │ └── ci.yml │ │ │ ├── .gitignore │ │ │ ├── Dockerfile │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── apps │ │ │ ├── main │ │ │ │ ├── resources │ │ │ │ │ ├── .env │ │ │ │ │ ├── backoffice_frontend │ │ │ │ │ │ ├── public │ │ │ │ │ │ │ └── images │ │ │ │ │ │ │ │ └── logo.png │ │ │ │ │ │ └── templates │ │ │ │ │ │ │ ├── master.ftl │ │ │ │ │ │ │ ├── pages │ │ │ │ │ │ │ ├── courses │ │ │ │ │ │ │ │ ├── courses.ftl │ │ │ │ │ │ │ │ └── partials │ │ │ │ │ │ │ │ │ ├── list_courses.ftl │ │ │ │ │ │ │ │ │ └── new_course_form.ftl │ │ │ │ │ │ │ └── home.ftl │ │ │ │ │ │ │ └── partials │ │ │ │ │ │ │ ├── footer.ftl │ │ │ │ │ │ │ └── header.ftl │ │ │ │ │ └── log4j2.properties │ │ │ │ └── tv │ │ │ │ │ └── codely │ │ │ │ │ └── apps │ │ │ │ │ ├── Starter.java │ │ │ │ │ ├── backoffice │ │ │ │ │ ├── backend │ │ │ │ │ │ ├── BackofficeBackendApplication.java │ │ │ │ │ │ ├── command │ │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ │ ├── config │ │ │ │ │ │ │ ├── BackofficeBackendServerConfiguration.java │ │ │ │ │ │ │ └── BackofficeBackendServerPortCustomizer.java │ │ │ │ │ │ ├── controller │ │ │ │ │ │ │ ├── courses │ │ │ │ │ │ │ │ └── CoursesGetController.java │ │ │ │ │ │ │ └── health_check │ │ │ │ │ │ │ │ └── HealthCheckGetController.java │ │ │ │ │ │ └── middleware │ │ │ │ │ │ │ └── BasicHttpAuthMiddleware.java │ │ │ │ │ └── frontend │ │ │ │ │ │ ├── BackofficeFrontendApplication.java │ │ │ │ │ │ ├── config │ │ │ │ │ │ ├── BackofficeFrontendServerPortCustomizer.java │ │ │ │ │ │ └── BackofficeFrontendWebConfig.java │ │ │ │ │ │ └── controller │ │ │ │ │ │ ├── courses │ │ │ │ │ │ ├── CoursesGetWebController.java │ │ │ │ │ │ └── CoursesPostWebController.java │ │ │ │ │ │ ├── health_check │ │ │ │ │ │ └── HealthCheckGetController.java │ │ │ │ │ │ └── home │ │ │ │ │ │ └── HomeGetWebController.java │ │ │ │ │ └── mooc │ │ │ │ │ └── backend │ │ │ │ │ ├── MoocBackendApplication.java │ │ │ │ │ ├── command │ │ │ │ │ ├── ConsumeMySqlDomainEventsCommand.java │ │ │ │ │ └── ConsumeRabbitMqDomainEventsCommand.java │ │ │ │ │ ├── config │ │ │ │ │ ├── MoocBackendServerConfiguration.java │ │ │ │ │ └── MoocBackendServerPortCustomizer.java │ │ │ │ │ └── controller │ │ │ │ │ ├── courses │ │ │ │ │ ├── CourseGetController.java │ │ │ │ │ └── CoursesPutController.java │ │ │ │ │ ├── courses_counter │ │ │ │ │ └── CoursesCounterGetController.java │ │ │ │ │ ├── health_check │ │ │ │ │ └── HealthCheckGetController.java │ │ │ │ │ └── notifications │ │ │ │ │ └── NewsletterNotificationPutController.java │ │ │ └── test │ │ │ │ ├── resources │ │ │ │ └── log4j2.properties │ │ │ │ └── tv │ │ │ │ └── codely │ │ │ │ └── apps │ │ │ │ ├── ApplicationTestCase.java │ │ │ │ ├── backoffice │ │ │ │ ├── BackofficeApplicationTestCase.java │ │ │ │ ├── backend │ │ │ │ │ └── controller │ │ │ │ │ │ └── health_check │ │ │ │ │ │ └── HealthCheckGetControllerShould.java │ │ │ │ └── frontend │ │ │ │ │ └── controller │ │ │ │ │ └── health_check │ │ │ │ │ └── HealthCheckGetControllerShould.java │ │ │ │ └── mooc │ │ │ │ ├── MoocApplicationTestCase.java │ │ │ │ └── backend │ │ │ │ └── controller │ │ │ │ ├── courses │ │ │ │ ├── CourseGetControllerShould.java │ │ │ │ └── CoursesPutControllerShould.java │ │ │ │ ├── courses_counter │ │ │ │ └── CoursesCounterGetControllerShould.java │ │ │ │ ├── health_check │ │ │ │ └── HealthCheckGetControllerShould.java │ │ │ │ └── notifications │ │ │ │ └── NewsletterNotificationPutControllerShould.java │ │ │ ├── build.gradle │ │ │ ├── doc │ │ │ └── endpoints │ │ │ │ └── backoffice_frontend.http │ │ │ ├── docker-compose.yml │ │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ ├── settings.gradle │ │ │ ├── src │ │ │ ├── analytics │ │ │ │ └── main │ │ │ │ │ └── tv │ │ │ │ │ └── codely │ │ │ │ │ └── analytics │ │ │ │ │ └── domain_events │ │ │ │ │ ├── application │ │ │ │ │ └── store │ │ │ │ │ │ ├── DomainEventStorer.java │ │ │ │ │ │ └── StoreDomainEventOnOccurred.java │ │ │ │ │ └── domain │ │ │ │ │ ├── AnalyticsDomainEvent.java │ │ │ │ │ ├── AnalyticsDomainEventAggregateId.java │ │ │ │ │ ├── AnalyticsDomainEventBody.java │ │ │ │ │ ├── AnalyticsDomainEventId.java │ │ │ │ │ ├── AnalyticsDomainEventName.java │ │ │ │ │ └── DomainEventsRepository.java │ │ │ ├── backoffice │ │ │ │ ├── build.gradle │ │ │ │ ├── main │ │ │ │ │ ├── resources │ │ │ │ │ │ └── database │ │ │ │ │ │ │ ├── backoffice.sql │ │ │ │ │ │ │ └── backoffice │ │ │ │ │ │ │ └── backoffice_courses.json │ │ │ │ │ └── tv │ │ │ │ │ │ └── codely │ │ │ │ │ │ └── backoffice │ │ │ │ │ │ ├── auth │ │ │ │ │ │ ├── application │ │ │ │ │ │ │ └── authenticate │ │ │ │ │ │ │ │ ├── AuthenticateUserCommand.java │ │ │ │ │ │ │ │ ├── AuthenticateUserCommandHandler.java │ │ │ │ │ │ │ │ └── UserAuthenticator.java │ │ │ │ │ │ ├── domain │ │ │ │ │ │ │ ├── AuthPassword.java │ │ │ │ │ │ │ ├── AuthRepository.java │ │ │ │ │ │ │ ├── AuthUser.java │ │ │ │ │ │ │ ├── AuthUsername.java │ │ │ │ │ │ │ ├── InvalidAuthCredentials.java │ │ │ │ │ │ │ └── InvalidAuthUsername.java │ │ │ │ │ │ └── infrastructure │ │ │ │ │ │ │ └── persistence │ │ │ │ │ │ │ └── InMemoryAuthRepository.java │ │ │ │ │ │ ├── courses │ │ │ │ │ │ ├── application │ │ │ │ │ │ │ ├── BackofficeCourseResponse.java │ │ │ │ │ │ │ ├── BackofficeCoursesResponse.java │ │ │ │ │ │ │ ├── create │ │ │ │ │ │ │ │ ├── BackofficeCourseCreator.java │ │ │ │ │ │ │ │ └── CreateBackofficeCourseOnCourseCreated.java │ │ │ │ │ │ │ ├── search_all │ │ │ │ │ │ │ │ ├── AllBackofficeCoursesSearcher.java │ │ │ │ │ │ │ │ ├── SearchAllBackofficeCoursesQuery.java │ │ │ │ │ │ │ │ └── SearchAllBackofficeCoursesQueryHandler.java │ │ │ │ │ │ │ └── search_by_criteria │ │ │ │ │ │ │ │ ├── BackofficeCoursesByCriteriaSearcher.java │ │ │ │ │ │ │ │ ├── SearchBackofficeCoursesByCriteriaQuery.java │ │ │ │ │ │ │ │ └── SearchBackofficeCoursesByCriteriaQueryHandler.java │ │ │ │ │ │ ├── domain │ │ │ │ │ │ │ ├── BackofficeCourse.java │ │ │ │ │ │ │ └── BackofficeCourseRepository.java │ │ │ │ │ │ └── infrastructure │ │ │ │ │ │ │ └── persistence │ │ │ │ │ │ │ ├── ElasticsearchBackofficeCourseRepository.java │ │ │ │ │ │ │ ├── InMemoryCacheBackofficeCourseRepository.java │ │ │ │ │ │ │ ├── MySqlBackofficeCourseRepository.java │ │ │ │ │ │ │ └── hibernate │ │ │ │ │ │ │ └── BackofficeCourse.hbm.xml │ │ │ │ │ │ └── shared │ │ │ │ │ │ └── infrastructure │ │ │ │ │ │ └── persistence │ │ │ │ │ │ ├── BackofficeElasticsearchConfiguration.java │ │ │ │ │ │ ├── BackofficeHibernateConfiguration.java │ │ │ │ │ │ ├── BackofficeMySqlEventBusConfiguration.java │ │ │ │ │ │ └── BackofficeRabbitMqEventBusConfiguration.java │ │ │ │ └── test │ │ │ │ │ └── tv │ │ │ │ │ └── codely │ │ │ │ │ └── backoffice │ │ │ │ │ ├── BackofficeContextInfrastructureTestCase.java │ │ │ │ │ ├── auth │ │ │ │ │ ├── AuthModuleUnitTestCase.java │ │ │ │ │ ├── application │ │ │ │ │ │ └── authenticate │ │ │ │ │ │ │ ├── AuthenticateUserCommandHandlerShould.java │ │ │ │ │ │ │ └── AuthenticateUserCommandMother.java │ │ │ │ │ └── domain │ │ │ │ │ │ ├── AuthPasswordMother.java │ │ │ │ │ │ ├── AuthUserMother.java │ │ │ │ │ │ └── AuthUsernameMother.java │ │ │ │ │ └── courses │ │ │ │ │ ├── ElasticsearchEnvironmentArranger.java │ │ │ │ │ ├── domain │ │ │ │ │ ├── BackofficeCourseCriteriaMother.java │ │ │ │ │ └── BackofficeCourseMother.java │ │ │ │ │ └── infrastructure │ │ │ │ │ └── persistence │ │ │ │ │ ├── ElasticsearchBackofficeCourseRepositoryShould.java │ │ │ │ │ ├── InMemoryCacheBackofficeCourseRepositoryShould.java │ │ │ │ │ └── MySqlBackofficeCourseRepositoryShould.java │ │ │ ├── mooc │ │ │ │ ├── build.gradle │ │ │ │ ├── main │ │ │ │ │ ├── resources │ │ │ │ │ │ └── database │ │ │ │ │ │ │ └── mooc.sql │ │ │ │ │ └── tv │ │ │ │ │ │ └── codely │ │ │ │ │ │ └── mooc │ │ │ │ │ │ ├── courses │ │ │ │ │ │ ├── application │ │ │ │ │ │ │ ├── CourseResponse.java │ │ │ │ │ │ │ ├── CoursesResponse.java │ │ │ │ │ │ │ ├── create │ │ │ │ │ │ │ │ ├── CourseCreator.java │ │ │ │ │ │ │ │ ├── CreateCourseCommand.java │ │ │ │ │ │ │ │ └── CreateCourseCommandHandler.java │ │ │ │ │ │ │ ├── find │ │ │ │ │ │ │ │ ├── CourseFinder.java │ │ │ │ │ │ │ │ ├── FindCourseQuery.java │ │ │ │ │ │ │ │ └── FindCourseQueryHandler.java │ │ │ │ │ │ │ └── search_last │ │ │ │ │ │ │ │ ├── LastCoursesSearcher.java │ │ │ │ │ │ │ │ ├── SearchLastCoursesQuery.java │ │ │ │ │ │ │ │ └── SearchLastCoursesQueryHandler.java │ │ │ │ │ │ ├── domain │ │ │ │ │ │ │ ├── Course.java │ │ │ │ │ │ │ ├── CourseDuration.java │ │ │ │ │ │ │ ├── CourseId.java │ │ │ │ │ │ │ ├── CourseName.java │ │ │ │ │ │ │ ├── CourseNotExist.java │ │ │ │ │ │ │ └── CourseRepository.java │ │ │ │ │ │ └── infrastructure │ │ │ │ │ │ │ └── persistence │ │ │ │ │ │ │ ├── InMemoryCourseRepository.java │ │ │ │ │ │ │ ├── MySqlCourseRepository.java │ │ │ │ │ │ │ └── hibernate │ │ │ │ │ │ │ └── Course.hbm.xml │ │ │ │ │ │ ├── courses_counter │ │ │ │ │ │ ├── application │ │ │ │ │ │ │ ├── find │ │ │ │ │ │ │ │ ├── CoursesCounterFinder.java │ │ │ │ │ │ │ │ ├── CoursesCounterResponse.java │ │ │ │ │ │ │ │ ├── FindCoursesCounterQuery.java │ │ │ │ │ │ │ │ └── FindCoursesCounterQueryHandler.java │ │ │ │ │ │ │ └── increment │ │ │ │ │ │ │ │ ├── CoursesCounterIncrementer.java │ │ │ │ │ │ │ │ └── IncrementCoursesCounterOnCourseCreated.java │ │ │ │ │ │ ├── domain │ │ │ │ │ │ │ ├── CoursesCounter.java │ │ │ │ │ │ │ ├── CoursesCounterId.java │ │ │ │ │ │ │ ├── CoursesCounterNotInitialized.java │ │ │ │ │ │ │ ├── CoursesCounterRepository.java │ │ │ │ │ │ │ └── CoursesCounterTotal.java │ │ │ │ │ │ └── infrastructure │ │ │ │ │ │ │ └── persistence │ │ │ │ │ │ │ ├── MySqlCoursesCounterRepository.java │ │ │ │ │ │ │ └── hibernate │ │ │ │ │ │ │ ├── CoursesCounter.hbm.xml │ │ │ │ │ │ │ └── CustomTypes.hbm.xml │ │ │ │ │ │ ├── notifications │ │ │ │ │ │ ├── application │ │ │ │ │ │ │ └── send_new_courses_newsletter │ │ │ │ │ │ │ │ ├── NewCoursesNewsletterSender.java │ │ │ │ │ │ │ │ ├── SendNewCoursesNewsletterCommand.java │ │ │ │ │ │ │ │ └── SendNewCoursesNewsletterCommandHandler.java │ │ │ │ │ │ ├── domain │ │ │ │ │ │ │ ├── Email.java │ │ │ │ │ │ │ ├── EmailId.java │ │ │ │ │ │ │ ├── EmailSender.java │ │ │ │ │ │ │ ├── NewCoursesNewsletter.java │ │ │ │ │ │ │ └── NewCoursesNewsletterEmailSent.java │ │ │ │ │ │ └── infrastructure │ │ │ │ │ │ │ └── FakeEmailSender.java │ │ │ │ │ │ ├── shared │ │ │ │ │ │ └── infrastructure │ │ │ │ │ │ │ └── persistence │ │ │ │ │ │ │ ├── MoocHibernateConfiguration.java │ │ │ │ │ │ │ ├── MoocMySqlEventBusConfiguration.java │ │ │ │ │ │ │ └── MoocRabbitMqEventBusConfiguration.java │ │ │ │ │ │ ├── steps │ │ │ │ │ │ ├── domain │ │ │ │ │ │ │ ├── Step.java │ │ │ │ │ │ │ ├── StepId.java │ │ │ │ │ │ │ ├── StepRepository.java │ │ │ │ │ │ │ ├── StepTitle.java │ │ │ │ │ │ │ ├── challenge │ │ │ │ │ │ │ │ ├── ChallengeStep.java │ │ │ │ │ │ │ │ └── ChallengeStepStatement.java │ │ │ │ │ │ │ └── video │ │ │ │ │ │ │ │ ├── VideoStep.java │ │ │ │ │ │ │ │ └── VideoStepText.java │ │ │ │ │ │ └── infrastructure │ │ │ │ │ │ │ └── persistence │ │ │ │ │ │ │ ├── MySqlStepRepository.java │ │ │ │ │ │ │ └── hibernate │ │ │ │ │ │ │ └── VideoStep.hbm.xml │ │ │ │ │ │ └── students │ │ │ │ │ │ ├── application │ │ │ │ │ │ ├── StudentResponse.java │ │ │ │ │ │ ├── StudentsResponse.java │ │ │ │ │ │ └── search_all │ │ │ │ │ │ │ ├── AllStudentsSearcher.java │ │ │ │ │ │ │ ├── SearchAllStudentsQuery.java │ │ │ │ │ │ │ └── SearchAllStudentsQueryHandler.java │ │ │ │ │ │ ├── domain │ │ │ │ │ │ ├── Student.java │ │ │ │ │ │ ├── StudentId.java │ │ │ │ │ │ └── StudentRepository.java │ │ │ │ │ │ └── infrastructure │ │ │ │ │ │ └── InMemoryStudentRepository.java │ │ │ │ └── test │ │ │ │ │ └── tv │ │ │ │ │ └── codely │ │ │ │ │ └── mooc │ │ │ │ │ ├── MoocContextInfrastructureTestCase.java │ │ │ │ │ ├── courses │ │ │ │ │ ├── CoursesModuleInfrastructureTestCase.java │ │ │ │ │ ├── CoursesModuleUnitTestCase.java │ │ │ │ │ ├── application │ │ │ │ │ │ ├── CourseResponseMother.java │ │ │ │ │ │ ├── CoursesResponseMother.java │ │ │ │ │ │ ├── create │ │ │ │ │ │ │ ├── CreateCourseCommandHandlerShould.java │ │ │ │ │ │ │ └── CreateCourseCommandMother.java │ │ │ │ │ │ └── search_last │ │ │ │ │ │ │ └── SearchLastCoursesQueryMother.java │ │ │ │ │ ├── domain │ │ │ │ │ │ ├── CourseCreatedDomainEventMother.java │ │ │ │ │ │ ├── CourseDurationMother.java │ │ │ │ │ │ ├── CourseIdMother.java │ │ │ │ │ │ ├── CourseMother.java │ │ │ │ │ │ └── CourseNameMother.java │ │ │ │ │ └── infrastructure │ │ │ │ │ │ └── persistence │ │ │ │ │ │ ├── InMemoryCourseRepositoryShould.java │ │ │ │ │ │ └── MySqlCourseRepositoryShould.java │ │ │ │ │ ├── courses_counter │ │ │ │ │ ├── CoursesCounterModuleInfrastructureTestCase.java │ │ │ │ │ ├── CoursesCounterModuleUnitTestCase.java │ │ │ │ │ ├── application │ │ │ │ │ │ ├── find │ │ │ │ │ │ │ ├── CoursesCounterResponseMother.java │ │ │ │ │ │ │ └── FindCoursesCounterQueryHandlerShould.java │ │ │ │ │ │ └── increment │ │ │ │ │ │ │ └── IncrementCoursesCounterOnCourseCreatedShould.java │ │ │ │ │ ├── domain │ │ │ │ │ │ ├── CoursesCounterIdMother.java │ │ │ │ │ │ ├── CoursesCounterMother.java │ │ │ │ │ │ └── CoursesCounterTotalMother.java │ │ │ │ │ └── infrastructure │ │ │ │ │ │ └── persistence │ │ │ │ │ │ └── MySqlCoursesCounterRepositoryShould.java │ │ │ │ │ ├── notifications │ │ │ │ │ ├── application │ │ │ │ │ │ ├── NotificationsModuleUnitTestCase.java │ │ │ │ │ │ └── send_new_courses_newsletter │ │ │ │ │ │ │ ├── SendNewCoursesNewsletterCommandHandlerShould.java │ │ │ │ │ │ │ └── SendNewCoursesNewsletterCommandMother.java │ │ │ │ │ └── domain │ │ │ │ │ │ ├── EmailIdMother.java │ │ │ │ │ │ ├── NewCoursesNewsletterEmailSentMother.java │ │ │ │ │ │ └── NewCoursesNewsletterMother.java │ │ │ │ │ ├── shared │ │ │ │ │ └── infrastructure │ │ │ │ │ │ └── bus │ │ │ │ │ │ └── event │ │ │ │ │ │ ├── mysql │ │ │ │ │ │ └── MySqlEventBusShould.java │ │ │ │ │ │ └── rabbitmq │ │ │ │ │ │ ├── RabbitMqEventBusShould.java │ │ │ │ │ │ └── TestAllWorksOnRabbitMqEventsPublished.java │ │ │ │ │ ├── steps │ │ │ │ │ ├── StepsModuleInfrastructureTestCase.java │ │ │ │ │ ├── domain │ │ │ │ │ │ ├── StepIdMother.java │ │ │ │ │ │ ├── StepTitleMother.java │ │ │ │ │ │ ├── challenge │ │ │ │ │ │ │ ├── ChallengeStepMother.java │ │ │ │ │ │ │ └── ChallengeStepStatementMother.java │ │ │ │ │ │ └── video │ │ │ │ │ │ │ ├── VideoStepMother.java │ │ │ │ │ │ │ └── VideoStepTextMother.java │ │ │ │ │ └── infrastructure │ │ │ │ │ │ └── persistence │ │ │ │ │ │ └── MySqlStepRepositoryShould.java │ │ │ │ │ └── students │ │ │ │ │ ├── application │ │ │ │ │ ├── StudentResponseMother.java │ │ │ │ │ ├── StudentsResponseMother.java │ │ │ │ │ └── search_all │ │ │ │ │ │ └── SearchAllStudentsQueryMother.java │ │ │ │ │ └── domain │ │ │ │ │ └── StudentIdMother.java │ │ │ └── shared │ │ │ │ ├── build.gradle │ │ │ │ ├── main │ │ │ │ └── tv │ │ │ │ │ └── codely │ │ │ │ │ └── shared │ │ │ │ │ ├── domain │ │ │ │ │ ├── AggregateRoot.java │ │ │ │ │ ├── DomainError.java │ │ │ │ │ ├── Identifier.java │ │ │ │ │ ├── IntValueObject.java │ │ │ │ │ ├── Logger.java │ │ │ │ │ ├── Monitoring.java │ │ │ │ │ ├── Service.java │ │ │ │ │ ├── StringValueObject.java │ │ │ │ │ ├── Utils.java │ │ │ │ │ ├── UuidGenerator.java │ │ │ │ │ ├── VideoUrl.java │ │ │ │ │ ├── bus │ │ │ │ │ │ ├── command │ │ │ │ │ │ │ ├── Command.java │ │ │ │ │ │ │ ├── CommandBus.java │ │ │ │ │ │ │ ├── CommandHandler.java │ │ │ │ │ │ │ ├── CommandHandlerExecutionError.java │ │ │ │ │ │ │ ├── CommandNotRegisteredError.java │ │ │ │ │ │ │ └── Middleware.java │ │ │ │ │ │ ├── event │ │ │ │ │ │ │ ├── DomainEvent.java │ │ │ │ │ │ │ ├── DomainEventSubscriber.java │ │ │ │ │ │ │ └── EventBus.java │ │ │ │ │ │ └── query │ │ │ │ │ │ │ ├── Query.java │ │ │ │ │ │ │ ├── QueryBus.java │ │ │ │ │ │ │ ├── QueryHandler.java │ │ │ │ │ │ │ ├── QueryHandlerExecutionError.java │ │ │ │ │ │ │ ├── QueryNotRegisteredError.java │ │ │ │ │ │ │ └── Response.java │ │ │ │ │ ├── course │ │ │ │ │ │ └── CourseCreatedDomainEvent.java │ │ │ │ │ └── criteria │ │ │ │ │ │ ├── Criteria.java │ │ │ │ │ │ ├── Filter.java │ │ │ │ │ │ ├── FilterField.java │ │ │ │ │ │ ├── FilterOperator.java │ │ │ │ │ │ ├── FilterValue.java │ │ │ │ │ │ ├── Filters.java │ │ │ │ │ │ ├── Order.java │ │ │ │ │ │ ├── OrderBy.java │ │ │ │ │ │ └── OrderType.java │ │ │ │ │ └── infrastructure │ │ │ │ │ ├── ConsoleLogger.java │ │ │ │ │ ├── JavaUuidGenerator.java │ │ │ │ │ ├── bus │ │ │ │ │ ├── command │ │ │ │ │ │ ├── CommandHandlerMiddleware.java │ │ │ │ │ │ ├── CommandHandlersInformation.java │ │ │ │ │ │ ├── InMemoryCommandBus.java │ │ │ │ │ │ ├── LoggerMiddleware.java │ │ │ │ │ │ └── TransactionalMiddleware.java │ │ │ │ │ ├── event │ │ │ │ │ │ ├── DomainEventJsonDeserializer.java │ │ │ │ │ │ ├── DomainEventJsonSerializer.java │ │ │ │ │ │ ├── DomainEventSubscriberInformation.java │ │ │ │ │ │ ├── DomainEventSubscribersInformation.java │ │ │ │ │ │ ├── DomainEventsInformation.java │ │ │ │ │ │ ├── mysql │ │ │ │ │ │ │ ├── MySqlDomainEventsConsumer.java │ │ │ │ │ │ │ └── MySqlEventBus.java │ │ │ │ │ │ ├── rabbitmq │ │ │ │ │ │ │ ├── RabbitMqDomainEventsConsumer.java │ │ │ │ │ │ │ ├── RabbitMqEventBus.java │ │ │ │ │ │ │ ├── RabbitMqEventBusConfiguration.java │ │ │ │ │ │ │ ├── RabbitMqExchangeNameFormatter.java │ │ │ │ │ │ │ ├── RabbitMqPublisher.java │ │ │ │ │ │ │ └── RabbitMqQueueNameFormatter.java │ │ │ │ │ │ └── spring │ │ │ │ │ │ │ └── SpringApplicationEventBus.java │ │ │ │ │ └── query │ │ │ │ │ │ ├── InMemoryQueryBus.java │ │ │ │ │ │ └── QueryHandlersInformation.java │ │ │ │ │ ├── cli │ │ │ │ │ └── ConsoleCommand.java │ │ │ │ │ ├── config │ │ │ │ │ ├── EnvironmentConfig.java │ │ │ │ │ ├── Parameter.java │ │ │ │ │ └── ParameterNotExist.java │ │ │ │ │ ├── elasticsearch │ │ │ │ │ ├── ElasticsearchClient.java │ │ │ │ │ ├── ElasticsearchCriteriaConverter.java │ │ │ │ │ └── ElasticsearchRepository.java │ │ │ │ │ ├── hibernate │ │ │ │ │ ├── HibernateConfigurationFactory.java │ │ │ │ │ ├── HibernateCriteriaConverter.java │ │ │ │ │ ├── HibernateRepository.java │ │ │ │ │ └── JsonListType.java │ │ │ │ │ ├── spring │ │ │ │ │ ├── ApiController.java │ │ │ │ │ └── ApiExceptionMiddleware.java │ │ │ │ │ └── validation │ │ │ │ │ ├── ValidationResponse.java │ │ │ │ │ ├── Validator.java │ │ │ │ │ ├── ValidatorNotExist.java │ │ │ │ │ └── validators │ │ │ │ │ ├── FieldValidator.java │ │ │ │ │ ├── NotEmptyValidator.java │ │ │ │ │ ├── RequiredValidator.java │ │ │ │ │ ├── StringValidator.java │ │ │ │ │ └── UuidValidator.java │ │ │ │ └── test │ │ │ │ └── tv │ │ │ │ └── codely │ │ │ │ └── shared │ │ │ │ ├── domain │ │ │ │ ├── EmailMother.java │ │ │ │ ├── IntegerMother.java │ │ │ │ ├── ListMother.java │ │ │ │ ├── MotherCreator.java │ │ │ │ ├── RandomElementPicker.java │ │ │ │ ├── UuidMother.java │ │ │ │ ├── VideoUrlMother.java │ │ │ │ └── WordMother.java │ │ │ │ └── infrastructure │ │ │ │ ├── InfrastructureTestCase.java │ │ │ │ └── UnitTestCase.java │ │ │ └── var │ │ │ └── log │ │ │ └── .gitkeep │ └── functional │ │ └── ts │ │ ├── .editorconfig │ │ ├── .eslintrc.js │ │ ├── .github │ │ └── workflows │ │ │ └── ci.yml │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── Command.ts │ │ ├── CommandHandler.ts │ │ ├── InMemoryCommandBus.ts │ │ ├── LoggerMiddleware.ts │ │ ├── Middleware.ts │ │ ├── TransactionalMiddleware.ts │ │ └── index.ts │ │ ├── tests │ │ └── .eslintrc │ │ └── tsconfig.json │ ├── command │ ├── README.md │ └── java │ │ ├── .editorconfig │ │ ├── .github │ │ └── workflows │ │ │ └── workflow.yml │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── README.md │ │ ├── build.gradle │ │ ├── doc │ │ └── endpoints │ │ │ └── mooc_courses.http │ │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── src │ │ ├── main │ │ │ ├── java │ │ │ │ └── tv │ │ │ │ │ └── codely │ │ │ │ │ └── mooc │ │ │ │ │ └── api │ │ │ │ │ ├── Application │ │ │ │ │ ├── Command.java │ │ │ │ │ ├── CommandHandler.java │ │ │ │ │ └── Create │ │ │ │ │ │ ├── CourseCreator.java │ │ │ │ │ │ ├── CreateCourseCommand.java │ │ │ │ │ │ └── CreateCourseCommandHandler.java │ │ │ │ │ ├── Domain │ │ │ │ │ ├── Course.java │ │ │ │ │ ├── CourseDuration.java │ │ │ │ │ ├── CourseId.java │ │ │ │ │ ├── CourseName.java │ │ │ │ │ ├── CourseNotExist.java │ │ │ │ │ ├── CourseRepository.java │ │ │ │ │ ├── DomainError.java │ │ │ │ │ ├── Identifier.java │ │ │ │ │ └── StringValueObject.java │ │ │ │ │ ├── Infrastructure │ │ │ │ │ └── Persistence │ │ │ │ │ │ └── InMemoryCourseRepository.java │ │ │ │ │ ├── MoocApplication.java │ │ │ │ │ └── Ui │ │ │ │ │ ├── Api │ │ │ │ │ └── Controller │ │ │ │ │ │ ├── CoursePutControllerRequestBody.java │ │ │ │ │ │ ├── CoursesGetController.java │ │ │ │ │ │ └── CoursesPutController.java │ │ │ │ │ └── Console │ │ │ │ │ └── CreateCourseConsoleCommand.java │ │ │ └── resources │ │ │ │ └── log4j2.properties │ │ └── test │ │ │ ├── java │ │ │ └── tv │ │ │ │ └── codely │ │ │ │ └── mooc │ │ │ │ └── api │ │ │ │ ├── ApiTestCase.java │ │ │ │ └── Ui │ │ │ │ └── Api │ │ │ │ └── Controller │ │ │ │ ├── CoursesGetControllerShould.java │ │ │ │ └── CoursesPutControllerShould.java │ │ │ └── resources │ │ │ ├── application.properties │ │ │ ├── log4j2.properties │ │ │ └── logback-test.xml │ │ └── var │ │ └── log │ │ └── .gitkeep │ ├── iterator │ ├── README.md │ └── typescript │ │ ├── .eslintrc.js │ │ ├── .github │ │ └── workflows │ │ │ └── ci.yml │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── AggregateRoot.ts │ │ ├── Course.ts │ │ ├── CourseRepository.ts │ │ ├── CourseReview.ts │ │ ├── CourseReviews.ts │ │ ├── CourseReviewsSnapshot.ts │ │ ├── CourseSnapshot.ts │ │ ├── DomainEvent.ts │ │ ├── FileEventSourcedCourseRepository.ts │ │ ├── FileSnapshotCourseRepository.ts │ │ ├── Generator.ts │ │ ├── ReviewAdded.ts │ │ └── Stars.ts │ │ ├── tests │ │ ├── .eslintrc │ │ ├── FileCourseSnapshotRepository.test.ts │ │ ├── FileEventSourcedCourseRepository.test.ts │ │ └── Generator.test.ts │ │ └── tsconfig.json │ ├── mediator │ ├── README.md │ └── typescript │ │ ├── .eslintrc.js │ │ ├── .github │ │ └── workflows │ │ │ ├── lint.yml │ │ │ └── test.yml │ │ ├── .gitignore │ │ ├── jest.config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ └── courses │ │ │ ├── bash.jpg │ │ │ ├── ddd-en-php.jpg │ │ │ ├── ddd-java.jpg │ │ │ ├── layouts-css.jpg │ │ │ ├── makefiles.jpg │ │ │ ├── novedades-vue-3.jpg │ │ │ └── terminal-zsh.jpg │ │ ├── readme.md │ │ ├── src │ │ ├── app.ts │ │ ├── controllers │ │ │ └── api.ts │ │ ├── entity │ │ │ ├── Role.ts │ │ │ ├── User.ts │ │ │ ├── UserRepository.ts │ │ │ ├── Workspace.ts │ │ │ └── WorkspaceRepository.ts │ │ ├── server.ts │ │ └── service │ │ │ ├── DomainEvent.ts │ │ │ ├── Email.ts │ │ │ ├── EventBus.ts │ │ │ ├── InMemoryEventBus.ts │ │ │ ├── Mailer.ts │ │ │ ├── Observer.ts │ │ │ ├── SendWelcomeEmailOnUserSignUp.ts │ │ │ ├── UserSignUpDomainEvent.ts │ │ │ └── UserSignUpServiceManagerHandler.ts │ │ ├── test │ │ └── api.spec.ts │ │ └── tsconfig.json │ ├── memento │ ├── README.md │ └── typescript │ │ ├── .eslintrc.js │ │ ├── .github │ │ └── workflows │ │ │ └── ci.yml │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── jest.config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── AggregateRoot.ts │ │ ├── Course.ts │ │ ├── CourseRepository.ts │ │ ├── CourseReview.ts │ │ ├── CourseReviews.ts │ │ ├── CourseReviewsSnapshot.ts │ │ ├── CourseSnapshot.ts │ │ ├── DomainEvent.ts │ │ ├── FileEventSourcedCourseRepository.ts │ │ ├── FileSnapshotCourseRepository.ts │ │ ├── ReviewAdded.ts │ │ └── Stars.ts │ │ ├── tests │ │ ├── .eslintrc │ │ ├── FileCourseSnapshotRepository.test.ts │ │ └── FileEventSourcedCourseRepository.test.ts │ │ └── tsconfig.json │ ├── observer │ ├── README.md │ └── typescript │ │ ├── .eslintrc.js │ │ ├── .github │ │ └── workflows │ │ │ ├── lint.yml │ │ │ └── test.yml │ │ ├── .gitignore │ │ ├── jest.config.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ └── courses │ │ │ ├── bash.jpg │ │ │ ├── ddd-en-php.jpg │ │ │ ├── ddd-java.jpg │ │ │ ├── layouts-css.jpg │ │ │ ├── makefiles.jpg │ │ │ ├── novedades-vue-3.jpg │ │ │ └── terminal-zsh.jpg │ │ ├── readme.md │ │ ├── src │ │ ├── app.ts │ │ ├── controllers │ │ │ └── api.ts │ │ ├── entity │ │ │ ├── DefaultWorkspaceCreated.ts │ │ │ ├── Role.ts │ │ │ ├── User.ts │ │ │ ├── UserRegistered.ts │ │ │ ├── UserRepository.ts │ │ │ ├── Workspace.ts │ │ │ └── WorkspaceRepository.ts │ │ ├── server.ts │ │ └── service │ │ │ ├── AssignUserToWorkspace.ts │ │ │ ├── CreateDefaultWorkspace.ts │ │ │ ├── Email.ts │ │ │ ├── Mailer.ts │ │ │ ├── Observable.ts │ │ │ ├── Observer.ts │ │ │ ├── SendWelcomeEmail.ts │ │ │ └── UserSignUpServiceManagerHandler.ts │ │ ├── test │ │ └── api.spec.ts │ │ └── tsconfig.json │ ├── state │ ├── README.md │ └── php │ │ ├── .editorconfig │ │ ├── .github │ │ ├── FUNDING.yml │ │ └── workflows │ │ │ └── ci.yml │ │ ├── .gitignore │ │ ├── .scrutinizer.yml │ │ ├── .semver │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ ├── composer.lock │ │ ├── phpunit.xml │ │ ├── src │ │ ├── ArchiveCourse.php │ │ ├── Course.php │ │ ├── CourseDuration.php │ │ ├── CourseId.php │ │ ├── CourseName.php │ │ ├── CourseStatus.php │ │ ├── DomainError.php │ │ ├── DraftCourse.php │ │ ├── PublishedCourse.php │ │ └── StringValueObject.php │ │ └── tests │ │ └── CourseTest.php │ ├── strategy │ ├── README.md │ ├── achivements-functional │ │ └── ts │ │ │ ├── .eslintrc.js │ │ │ ├── .github │ │ │ └── workflows │ │ │ │ └── ci.yml │ │ │ ├── .gitignore │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── jest.config.js │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── src │ │ │ └── index.ts │ │ │ ├── tests │ │ │ └── .eslintrc │ │ │ └── tsconfig.json │ └── kotlin │ │ ├── .github │ │ └── workflows │ │ │ └── main.yml │ │ ├── .gitignore │ │ ├── README.md │ │ ├── build.gradle.kts │ │ ├── gradle.properties │ │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── settings.gradle.kts │ │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── codely │ │ │ └── achievement │ │ │ ├── AchievementDealer.kt │ │ │ ├── AchievementType.kt │ │ │ ├── Codely.kt │ │ │ ├── ConstantLearnerRepository.kt │ │ │ ├── DummyStepRepository.kt │ │ │ ├── EarnedPoints.kt │ │ │ ├── InMemoryLearnerAchievementRepository.kt │ │ │ ├── Learner.kt │ │ │ ├── LearnerAchievement.kt │ │ │ ├── LearnerAchievementDealer.kt │ │ │ ├── LearnerAchievementRepository.kt │ │ │ ├── LearnerEarnedPoints.kt │ │ │ ├── LearnerRepository.kt │ │ │ ├── LearnerStep.kt │ │ │ ├── LearnerStepRepository.kt │ │ │ ├── Step.kt │ │ │ ├── StepCompleter.kt │ │ │ ├── StepRepository.kt │ │ │ ├── VoidLearnerStepsRepository.kt │ │ │ ├── achievements │ │ │ ├── BackendGuru.kt │ │ │ ├── FrontendGuru.kt │ │ │ ├── FullStackGuru.kt │ │ │ ├── PointsEarned100.kt │ │ │ ├── PointsEarned2500.kt │ │ │ └── PointsEarned500.kt │ │ │ └── factories │ │ │ ├── AchievementDealerFactory.kt │ │ │ └── LearnerAchievementDealerFactory.kt │ │ └── test │ │ └── kotlin │ │ └── com │ │ └── codely │ │ └── achievement │ │ └── LearnerAchievementDealerShould.kt │ └── visitor │ ├── README.md │ └── typescript │ ├── .eslintrc.js │ ├── .github │ └── workflows │ │ └── ci.yml │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── ElementA.ts │ ├── ElementB.ts │ ├── ExportVisitor.ts │ ├── PrintVisitor.ts │ ├── ValidatorVisitor.ts │ ├── VisitingElement.ts │ └── Visitor.ts │ ├── tests │ ├── .eslintrc │ └── Visitor.test.ts │ └── tsconfig.json ├── design-patterns ├── behavioral │ ├── chain-of-responsibility │ │ └── .gitkeep │ ├── command │ │ └── .gitkeep │ ├── iterator │ │ └── .gitkeep │ ├── mediator │ │ └── .gitkeep │ ├── memento │ │ └── .gitkeep │ ├── observer │ │ └── .gitkeep │ ├── state │ │ └── .gitkeep │ ├── strategy │ │ └── .gitkeep │ ├── template-method │ │ └── .gitkeep │ └── visitor │ │ └── .gitkeep ├── creational │ ├── abstract-factory │ │ └── .gitkeep │ ├── builder │ │ └── .gitkeep │ ├── factory-method │ │ └── .gitkeep │ ├── prototype │ │ └── .gitkeep │ └── singleton │ │ └── .gitkeep └── structural │ ├── adapter │ └── .gitkeep │ ├── bridge │ └── .gitkeep │ ├── composite │ └── .gitkeep │ ├── decorator │ └── .gitkeep │ ├── facade │ └── .gitkeep │ ├── flyweight │ └── .gitkeep │ └── proxy │ └── .gitkeep ├── exercises └── .gitkeep ├── node_modules ├── .package-lock.json └── .yarn-integrity ├── package-lock.json └── yarn.lock /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/README.md: -------------------------------------------------------------------------------- 1 | Chain of responsibility applied to CommandBus Middlewares 2 | ========================================================= 3 | 4 | An example of the Chain of responsibility pattern applied 5 | to CommandBus Middlewares. 6 | 7 | ## Description 8 | 9 | In this example we implement a middleware system for a 10 | CommandBus, using the chain of responsibility pattern. 11 | 12 | Each element of the chain decorates the execution of the 13 | command: 14 | - LoggerMiddleware: Logs every command dispatched to the command bus 15 | - TransactionalMiddleware: Create a database transaction for each dispatched command 16 | - CommandHandlerMiddleware: Executes the command handler 17 | 18 | ## Languages 19 | 20 | - [Java](java) 21 | 22 | ## Patterns used in this example 23 | 24 | - [Chain of Responsibility](/design-patterns/behavioral/chain-of-responsibility) 25 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [*.java] 10 | indent_size = 4 11 | indent_style = space 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/.env: -------------------------------------------------------------------------------- 1 | # See apps/main/resources/.env 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | 13 | - name: Start all the environment 14 | run: docker-compose up -d 15 | 16 | - name: Wait for the environment to get up 17 | run: | 18 | while ! make ping-mysql &>/dev/null; do 19 | echo "Waiting for database connection..." 20 | sleep 2 21 | done 22 | 23 | - name: Run the tests 24 | run: make test 25 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle 2 | .gradle 3 | build/ 4 | 5 | # Ignore Gradle GUI config 6 | gradle-app.setting 7 | 8 | /var/log/* 9 | !/var/log/.gitkeep 10 | 11 | .env.local 12 | .env.*.local 13 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:11-slim-buster 2 | WORKDIR /app 3 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: build 3 | 4 | .PHONY: up 5 | up: 6 | @docker-compose up -d 7 | 8 | .PHONY: build 9 | build: 10 | @./gradlew build --warning-mode all 11 | 12 | .PHONY: run-tests 13 | run-tests: 14 | @./gradlew test --warning-mode all 15 | 16 | .PHONY: test 17 | test: 18 | @docker exec codelytv-ddd_skeleton-java ./gradlew test --warning-mode all 19 | 20 | .PHONY: run 21 | run: 22 | @./gradlew :run 23 | 24 | .PHONY: ping-mysql 25 | ping-mysql: 26 | @docker exec codelytv-java_ddd_skeleton-mysql mysqladmin --user=root --password= --host "127.0.0.1" ping --silent 27 | 28 | # Start the app 29 | .PHONY: start-mooc_backend 30 | start-mooc_backend: 31 | @./gradlew :run --args='mooc_backend server' 32 | 33 | .PHONY: start-backoffice_frontend 34 | start-backoffice_frontend: 35 | @./gradlew :run --args='backoffice_frontend server' 36 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/README.md: -------------------------------------------------------------------------------- 1 | # Chain of responsibility design pattern: Java 2 | 3 | Java implementation of the [Chain of responsibility applied to CommandBus Middlewares example](../README.md). 4 | 5 | ## Steps 6 | 7 | To navigate between steps use `git checkout` command 8 | using the specified commit hash below 👇 9 | 10 | 1. Chain of responsibility applied to CommandBus middlewares 11 | 12 | ```bash 13 | # step 1 14 | git checkout d76d554d 15 | `` 16 | 17 | 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/resources/backoffice_frontend/public/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/resources/backoffice_frontend/public/images/logo.png -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/resources/backoffice_frontend/templates/pages/courses/courses.ftl: -------------------------------------------------------------------------------- 1 | <#include "../../master.ftl"> 2 | 3 | <#macro page_title>Cursos 4 | 5 | <#macro main> 6 |
7 | Sunset in the mountains 8 |
9 |
Cursos
10 |

11 | Actualmente CodelyTV Pro cuenta con ${courses_counter} cursos. 12 |

13 |
14 |
15 | 16 | <#include "partials/new_course_form.ftl"> 17 |
18 |
19 | <#include "partials/list_courses.ftl"> 20 | 21 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/resources/backoffice_frontend/templates/pages/home.ftl: -------------------------------------------------------------------------------- 1 | <#include "../master.ftl"> 2 | 3 | <#macro page_title>HOME 4 | 5 | <#macro main> 6 | Estamos en la home! 7 | 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/resources/backoffice_frontend/templates/partials/footer.ftl: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/tv/codely/apps/backoffice/backend/command/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/tv/codely/apps/backoffice/backend/command/.gitkeep -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetController.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.backoffice.frontend.controller.health_check; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | import java.util.HashMap; 7 | 8 | @RestController 9 | public final class HealthCheckGetController { 10 | @GetMapping("/health-check") 11 | public HashMap index() { 12 | HashMap status = new HashMap<>(); 13 | status.put("application", "backoffice_frontend"); 14 | status.put("status", "ok"); 15 | 16 | return status; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/tv/codely/apps/backoffice/frontend/controller/home/HomeGetWebController.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.backoffice.frontend.controller.home; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.servlet.ModelAndView; 6 | 7 | import java.io.Serializable; 8 | import java.util.HashMap; 9 | 10 | @Controller 11 | public final class HomeGetWebController { 12 | @GetMapping("/") 13 | public ModelAndView index() { 14 | return new ModelAndView("pages/home", new HashMap() {{ 15 | put("title", "Welcome"); 16 | put("description", "CodelyTV - Backoffice"); 17 | }}); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/tv/codely/apps/mooc/backend/command/ConsumeMySqlDomainEventsCommand.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.mooc.backend.command; 2 | 3 | import tv.codely.shared.infrastructure.bus.event.mysql.MySqlDomainEventsConsumer; 4 | import tv.codely.shared.infrastructure.cli.ConsoleCommand; 5 | 6 | public final class ConsumeMySqlDomainEventsCommand extends ConsoleCommand { 7 | private final MySqlDomainEventsConsumer consumer; 8 | 9 | public ConsumeMySqlDomainEventsCommand(MySqlDomainEventsConsumer consumer) { 10 | this.consumer = consumer; 11 | } 12 | 13 | @Override 14 | public void execute(String[] args) { 15 | consumer.consume(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/main/tv/codely/apps/mooc/backend/command/ConsumeRabbitMqDomainEventsCommand.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.mooc.backend.command; 2 | 3 | import tv.codely.shared.infrastructure.bus.event.rabbitmq.RabbitMqDomainEventsConsumer; 4 | import tv.codely.shared.infrastructure.cli.ConsoleCommand; 5 | 6 | public final class ConsumeRabbitMqDomainEventsCommand extends ConsoleCommand { 7 | private final RabbitMqDomainEventsConsumer consumer; 8 | 9 | public ConsumeRabbitMqDomainEventsCommand(RabbitMqDomainEventsConsumer consumer) { 10 | this.consumer = consumer; 11 | } 12 | 13 | @Override 14 | public void execute(String[] args) { 15 | consumer.consume(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/test/tv/codely/apps/backoffice/BackofficeApplicationTestCase.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.backoffice; 2 | 3 | import org.springframework.transaction.annotation.Transactional; 4 | import tv.codely.apps.ApplicationTestCase; 5 | 6 | @Transactional("backoffice-transaction_manager") 7 | public abstract class BackofficeApplicationTestCase extends ApplicationTestCase { 8 | } 9 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/test/tv/codely/apps/backoffice/frontend/controller/health_check/HealthCheckGetControllerShould.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.backoffice.frontend.controller.health_check; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import tv.codely.apps.ApplicationTestCase; 5 | 6 | final class HealthCheckGetControllerShould extends ApplicationTestCase { 7 | @Test 8 | void check_the_app_is_working_ok() throws Exception { 9 | assertResponse("/health-check", 200, "{'application':'backoffice_frontend','status':'ok'}"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/test/tv/codely/apps/mooc/MoocApplicationTestCase.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.mooc; 2 | 3 | import org.springframework.transaction.annotation.Transactional; 4 | import tv.codely.apps.ApplicationTestCase; 5 | 6 | @Transactional("mooc-transaction_manager") 7 | public abstract class MoocApplicationTestCase extends ApplicationTestCase { 8 | } 9 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/test/tv/codely/apps/mooc/backend/controller/courses/CoursesPutControllerShould.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.mooc.backend.controller.courses; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import tv.codely.apps.mooc.MoocApplicationTestCase; 5 | 6 | public final class CoursesPutControllerShould extends MoocApplicationTestCase { 7 | @Test 8 | void create_a_valid_non_existing_course() throws Exception { 9 | assertRequestWithBody( 10 | "PUT", 11 | "/courses/1aab45ba-3c7a-4344-8936-78466eca77fa", 12 | "{\"name\": \"The best course\", \"duration\": \"5 hours\"}", 13 | 201 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/test/tv/codely/apps/mooc/backend/controller/health_check/HealthCheckGetControllerShould.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.mooc.backend.controller.health_check; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import tv.codely.apps.mooc.MoocApplicationTestCase; 5 | 6 | final class HealthCheckGetControllerShould extends MoocApplicationTestCase { 7 | @Test 8 | void check_the_app_is_working_ok() throws Exception { 9 | assertResponse("/health-check", 200, "{'application':'mooc_backend','status':'ok'}"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/apps/test/tv/codely/apps/mooc/backend/controller/notifications/NewsletterNotificationPutControllerShould.java: -------------------------------------------------------------------------------- 1 | package tv.codely.apps.mooc.backend.controller.notifications; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import tv.codely.apps.mooc.MoocApplicationTestCase; 5 | 6 | final class NewsletterNotificationPutControllerShould extends MoocApplicationTestCase { 7 | @Test 8 | void create_a_valid_non_existing_course() throws Exception { 9 | assertRequest( 10 | "PUT", 11 | "/newsletter/6eebbe60-50e7-400a-810c-3e0af0943ee6", 12 | 201 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'java-ddd-skeleton' 2 | 3 | include ':shared' 4 | project(':shared').projectDir = new File('src/shared') 5 | 6 | include ':analytics' 7 | project(':analytics').projectDir = new File('src/analytics') 8 | 9 | include ':backoffice' 10 | project(':backoffice').projectDir = new File('src/backoffice') 11 | 12 | include ':mooc' 13 | project(':mooc').projectDir = new File('src/mooc') 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/analytics/main/tv/codely/analytics/domain_events/application/store/DomainEventStorer.java: -------------------------------------------------------------------------------- 1 | package tv.codely.analytics.domain_events.application.store; 2 | 3 | import tv.codely.analytics.domain_events.domain.*; 4 | 5 | public final class DomainEventStorer { 6 | private DomainEventsRepository repository; 7 | 8 | public DomainEventStorer(DomainEventsRepository repository) { 9 | this.repository = repository; 10 | } 11 | 12 | public void store( 13 | AnalyticsDomainEventId id, 14 | AnalyticsDomainEventAggregateId aggregateId, 15 | AnalyticsDomainEventName name, 16 | AnalyticsDomainEventBody body 17 | ) { 18 | AnalyticsDomainEvent domainEvent = new AnalyticsDomainEvent(id, aggregateId, name, body); 19 | 20 | repository.save(domainEvent); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/analytics/main/tv/codely/analytics/domain_events/domain/AnalyticsDomainEventAggregateId.java: -------------------------------------------------------------------------------- 1 | package tv.codely.analytics.domain_events.domain; 2 | 3 | import tv.codely.shared.domain.Identifier; 4 | 5 | public final class AnalyticsDomainEventAggregateId extends Identifier { 6 | public AnalyticsDomainEventAggregateId(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/analytics/main/tv/codely/analytics/domain_events/domain/AnalyticsDomainEventBody.java: -------------------------------------------------------------------------------- 1 | package tv.codely.analytics.domain_events.domain; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | 6 | public final class AnalyticsDomainEventBody { 7 | private HashMap value; 8 | 9 | public HashMap getValue() { 10 | return value; 11 | } 12 | 13 | public AnalyticsDomainEventBody(HashMap value) { 14 | this.value = value; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/analytics/main/tv/codely/analytics/domain_events/domain/AnalyticsDomainEventId.java: -------------------------------------------------------------------------------- 1 | package tv.codely.analytics.domain_events.domain; 2 | 3 | import tv.codely.shared.domain.Identifier; 4 | 5 | public final class AnalyticsDomainEventId extends Identifier { 6 | public AnalyticsDomainEventId(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/analytics/main/tv/codely/analytics/domain_events/domain/AnalyticsDomainEventName.java: -------------------------------------------------------------------------------- 1 | package tv.codely.analytics.domain_events.domain; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class AnalyticsDomainEventName extends StringValueObject { 6 | public AnalyticsDomainEventName(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/analytics/main/tv/codely/analytics/domain_events/domain/DomainEventsRepository.java: -------------------------------------------------------------------------------- 1 | package tv.codely.analytics.domain_events.domain; 2 | 3 | public interface DomainEventsRepository { 4 | void save(AnalyticsDomainEvent event); 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | } 3 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/resources/database/backoffice.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS `courses` ( 2 | `id` CHAR(36) NOT NULL, 3 | `name` VARCHAR(255) NOT NULL, 4 | `duration` VARCHAR(255) NOT NULL, 5 | PRIMARY KEY (`id`) 6 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/resources/database/backoffice/backoffice_courses.json: -------------------------------------------------------------------------------- 1 | { 2 | "mappings": { 3 | "courses": { 4 | "properties": { 5 | "id": { 6 | "type": "keyword", 7 | "index": true 8 | }, 9 | "name": { 10 | "type": "text", 11 | "index": true, 12 | "fielddata": true 13 | }, 14 | "duration": { 15 | "type": "text", 16 | "index": true, 17 | "fielddata": true 18 | } 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/auth/application/authenticate/AuthenticateUserCommand.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.application.authenticate; 2 | 3 | import tv.codely.shared.domain.bus.command.Command; 4 | 5 | public final class AuthenticateUserCommand implements Command { 6 | private final String username; 7 | private final String password; 8 | 9 | public AuthenticateUserCommand(String username, String password) { 10 | this.username = username; 11 | this.password = password; 12 | } 13 | 14 | public String username() { 15 | return username; 16 | } 17 | 18 | public String password() { 19 | return password; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/auth/domain/AuthPassword.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.domain; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class AuthPassword extends StringValueObject { 6 | public AuthPassword(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/auth/domain/AuthRepository.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.domain; 2 | 3 | import java.util.Optional; 4 | 5 | public interface AuthRepository { 6 | Optional search(AuthUsername username); 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/auth/domain/AuthUser.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.domain; 2 | 3 | public final class AuthUser { 4 | private final AuthUsername username; 5 | private final AuthPassword password; 6 | 7 | public AuthUser(AuthUsername username, AuthPassword password) { 8 | this.username = username; 9 | this.password = password; 10 | } 11 | 12 | public AuthUsername username() { 13 | return username; 14 | } 15 | 16 | public boolean passwordMatches(AuthPassword password) { 17 | return this.password.equals(password); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/auth/domain/AuthUsername.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.domain; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class AuthUsername extends StringValueObject { 6 | public AuthUsername(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/auth/domain/InvalidAuthCredentials.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.domain; 2 | 3 | public final class InvalidAuthCredentials extends RuntimeException { 4 | public InvalidAuthCredentials(AuthUsername username) { 5 | super(String.format("The credentials for <%s> are invalid", username.value())); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/auth/domain/InvalidAuthUsername.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.domain; 2 | 3 | public final class InvalidAuthUsername extends RuntimeException { 4 | public InvalidAuthUsername(AuthUsername username) { 5 | super(String.format("The user <%s> does not exist", username.value())); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/courses/application/BackofficeCoursesResponse.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.courses.application; 2 | 3 | import tv.codely.shared.domain.bus.query.Response; 4 | 5 | import java.util.List; 6 | 7 | public final class BackofficeCoursesResponse implements Response { 8 | private final List courses; 9 | 10 | public BackofficeCoursesResponse(List courses) { 11 | this.courses = courses; 12 | } 13 | 14 | public List courses() { 15 | return courses; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/courses/application/create/BackofficeCourseCreator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.courses.application.create; 2 | 3 | import tv.codely.backoffice.courses.domain.BackofficeCourse; 4 | import tv.codely.backoffice.courses.domain.BackofficeCourseRepository; 5 | import tv.codely.shared.domain.Service; 6 | 7 | @Service 8 | public final class BackofficeCourseCreator { 9 | private final BackofficeCourseRepository repository; 10 | 11 | public BackofficeCourseCreator(BackofficeCourseRepository repository) { 12 | this.repository = repository; 13 | } 14 | 15 | public void create(String id, String name, String duration) { 16 | this.repository.save(new BackofficeCourse(id, name, duration)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/courses/application/search_all/SearchAllBackofficeCoursesQuery.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.courses.application.search_all; 2 | 3 | import tv.codely.shared.domain.bus.query.Query; 4 | 5 | public final class SearchAllBackofficeCoursesQuery implements Query { 6 | } 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/courses/domain/BackofficeCourseRepository.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.courses.domain; 2 | 3 | import tv.codely.shared.domain.criteria.Criteria; 4 | 5 | import java.util.List; 6 | 7 | public interface BackofficeCourseRepository { 8 | void save(BackofficeCourse course); 9 | 10 | List searchAll(); 11 | 12 | List matching(Criteria criteria); 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/main/tv/codely/backoffice/courses/infrastructure/persistence/hibernate/BackofficeCourse.hbm.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/test/tv/codely/backoffice/auth/application/authenticate/AuthenticateUserCommandMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.application.authenticate; 2 | 3 | import tv.codely.backoffice.auth.domain.AuthPassword; 4 | import tv.codely.backoffice.auth.domain.AuthPasswordMother; 5 | import tv.codely.backoffice.auth.domain.AuthUsername; 6 | import tv.codely.backoffice.auth.domain.AuthUsernameMother; 7 | 8 | public final class AuthenticateUserCommandMother { 9 | public static AuthenticateUserCommand create(AuthUsername username, AuthPassword password) { 10 | return new AuthenticateUserCommand(username.value(), password.value()); 11 | } 12 | 13 | public static AuthenticateUserCommand random() { 14 | return create(AuthUsernameMother.random(), AuthPasswordMother.random()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/test/tv/codely/backoffice/auth/domain/AuthPasswordMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.domain; 2 | 3 | import tv.codely.shared.domain.WordMother; 4 | 5 | public final class AuthPasswordMother { 6 | public static AuthPassword create(String value) { 7 | return new AuthPassword(value); 8 | } 9 | 10 | public static AuthPassword random() { 11 | return create(WordMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/test/tv/codely/backoffice/auth/domain/AuthUsernameMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.auth.domain; 2 | 3 | import tv.codely.shared.domain.WordMother; 4 | 5 | public final class AuthUsernameMother { 6 | public static AuthUsername create(String value) { 7 | return new AuthUsername(value); 8 | } 9 | 10 | public static AuthUsername random() { 11 | return create(WordMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/test/tv/codely/backoffice/courses/domain/BackofficeCourseCriteriaMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.courses.domain; 2 | 3 | import tv.codely.shared.domain.criteria.Criteria; 4 | import tv.codely.shared.domain.criteria.Filter; 5 | import tv.codely.shared.domain.criteria.Filters; 6 | import tv.codely.shared.domain.criteria.Order; 7 | 8 | import java.util.Arrays; 9 | 10 | public final class BackofficeCourseCriteriaMother { 11 | public static Criteria nameAndDurationContains(String name, String duration) { 12 | Filter nameFilter = Filter.create("name", "contains", name); 13 | Filter durationFilter = Filter.create("duration", "contains", duration); 14 | 15 | return new Criteria(new Filters(Arrays.asList(nameFilter, durationFilter)), Order.asc("name")); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/backoffice/test/tv/codely/backoffice/courses/domain/BackofficeCourseMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.backoffice.courses.domain; 2 | 3 | import tv.codely.shared.domain.UuidMother; 4 | import tv.codely.shared.domain.WordMother; 5 | 6 | public final class BackofficeCourseMother { 7 | public static BackofficeCourse create(String id, String name, String duration) { 8 | return new BackofficeCourse(id, name, duration); 9 | } 10 | 11 | public static BackofficeCourse create(String name, String duration) { 12 | return new BackofficeCourse(UuidMother.random(), name, duration); 13 | } 14 | 15 | public static BackofficeCourse random() { 16 | return create(UuidMother.random(), WordMother.random(), WordMother.random()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | } 3 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses/application/CoursesResponse.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.application; 2 | 3 | import tv.codely.shared.domain.bus.query.Response; 4 | 5 | import java.util.List; 6 | 7 | public final class CoursesResponse implements Response { 8 | private final List courses; 9 | 10 | public CoursesResponse(List courses) { 11 | this.courses = courses; 12 | } 13 | 14 | public List courses() { 15 | return courses; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses/application/create/CreateCourseCommand.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.application.create; 2 | 3 | import tv.codely.shared.domain.bus.command.Command; 4 | 5 | public final class CreateCourseCommand implements Command { 6 | private final String id; 7 | private final String name; 8 | private final String duration; 9 | 10 | public CreateCourseCommand(String id, String name, String duration) { 11 | this.id = id; 12 | this.name = name; 13 | this.duration = duration; 14 | } 15 | 16 | public String id() { 17 | return id; 18 | } 19 | 20 | public String name() { 21 | return name; 22 | } 23 | 24 | public String duration() { 25 | return duration; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses/application/find/FindCourseQuery.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.application.find; 2 | 3 | import tv.codely.shared.domain.bus.query.Query; 4 | 5 | public final class FindCourseQuery implements Query { 6 | private final String id; 7 | 8 | public FindCourseQuery(String id) { 9 | this.id = id; 10 | } 11 | 12 | public String id() { 13 | return id; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses/application/search_last/SearchLastCoursesQueryHandler.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.application.search_last; 2 | 3 | import tv.codely.mooc.courses.application.CoursesResponse; 4 | import tv.codely.shared.domain.Service; 5 | import tv.codely.shared.domain.bus.query.QueryHandler; 6 | 7 | @Service 8 | public final class SearchLastCoursesQueryHandler implements QueryHandler { 9 | private final LastCoursesSearcher searcher; 10 | 11 | public SearchLastCoursesQueryHandler(LastCoursesSearcher searcher) { 12 | this.searcher = searcher; 13 | } 14 | 15 | @Override 16 | public CoursesResponse handle(SearchLastCoursesQuery query) { 17 | return searcher.search(query.total()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses/domain/CourseDuration.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class CourseDuration extends StringValueObject { 6 | public CourseDuration(String value) { 7 | super(value); 8 | } 9 | 10 | private CourseDuration() { 11 | super(""); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses/domain/CourseId.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.shared.domain.Identifier; 4 | 5 | public final class CourseId extends Identifier { 6 | public CourseId(String value) { 7 | super(value); 8 | } 9 | 10 | public CourseId() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses/domain/CourseName.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class CourseName extends StringValueObject { 6 | public CourseName(String value) { 7 | super(value); 8 | } 9 | 10 | public CourseName() { 11 | super(""); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses/domain/CourseNotExist.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.shared.domain.DomainError; 4 | 5 | public final class CourseNotExist extends DomainError { 6 | public CourseNotExist(CourseId id) { 7 | super("course_not_exist", String.format("The course <%s> doesn't exist", id.value())); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses/domain/CourseRepository.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.shared.domain.criteria.Criteria; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | public interface CourseRepository { 9 | void save(Course course); 10 | 11 | Optional search(CourseId id); 12 | 13 | List matching(Criteria criteria); 14 | } 15 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses_counter/application/find/FindCoursesCounterQuery.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter.application.find; 2 | 3 | import tv.codely.shared.domain.bus.query.Query; 4 | 5 | public final class FindCoursesCounterQuery implements Query { 6 | } 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses_counter/application/find/FindCoursesCounterQueryHandler.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter.application.find; 2 | 3 | import tv.codely.shared.domain.Service; 4 | import tv.codely.shared.domain.bus.query.QueryHandler; 5 | 6 | @Service 7 | public final class FindCoursesCounterQueryHandler implements QueryHandler { 8 | private final CoursesCounterFinder finder; 9 | 10 | public FindCoursesCounterQueryHandler(CoursesCounterFinder finder) { 11 | this.finder = finder; 12 | } 13 | 14 | @Override 15 | public CoursesCounterResponse handle(FindCoursesCounterQuery query) { 16 | return finder.find(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses_counter/domain/CoursesCounterId.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter.domain; 2 | 3 | import tv.codely.shared.domain.Identifier; 4 | 5 | public final class CoursesCounterId extends Identifier { 6 | public CoursesCounterId(String value) { 7 | super(value); 8 | } 9 | 10 | private CoursesCounterId() { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses_counter/domain/CoursesCounterNotInitialized.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter.domain; 2 | 3 | public final class CoursesCounterNotInitialized extends RuntimeException { 4 | } 5 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses_counter/domain/CoursesCounterRepository.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter.domain; 2 | 3 | import java.util.Optional; 4 | 5 | public interface CoursesCounterRepository { 6 | void save(CoursesCounter counter); 7 | 8 | Optional search(); 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses_counter/domain/CoursesCounterTotal.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter.domain; 2 | 3 | import tv.codely.shared.domain.IntValueObject; 4 | 5 | public final class CoursesCounterTotal extends IntValueObject { 6 | public CoursesCounterTotal(Integer value) { 7 | super(value); 8 | } 9 | 10 | public CoursesCounterTotal() { 11 | super(null); 12 | } 13 | 14 | public static CoursesCounterTotal initialize() { 15 | return new CoursesCounterTotal(0); 16 | } 17 | 18 | public CoursesCounterTotal increment() { 19 | return new CoursesCounterTotal(value() + 1); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/courses_counter/infrastructure/persistence/hibernate/CustomTypes.hbm.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/notifications/application/send_new_courses_newsletter/SendNewCoursesNewsletterCommand.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.notifications.application.send_new_courses_newsletter; 2 | 3 | import tv.codely.shared.domain.bus.command.Command; 4 | 5 | public final class SendNewCoursesNewsletterCommand implements Command { 6 | private final String id; 7 | 8 | public SendNewCoursesNewsletterCommand(String id) { 9 | this.id = id; 10 | } 11 | 12 | public String id() { 13 | return id; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/notifications/application/send_new_courses_newsletter/SendNewCoursesNewsletterCommandHandler.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.notifications.application.send_new_courses_newsletter; 2 | 3 | import tv.codely.shared.domain.Service; 4 | import tv.codely.shared.domain.bus.command.CommandHandler; 5 | 6 | @Service 7 | public final class SendNewCoursesNewsletterCommandHandler implements CommandHandler { 8 | private final NewCoursesNewsletterSender sender; 9 | 10 | public SendNewCoursesNewsletterCommandHandler(NewCoursesNewsletterSender sender) { 11 | this.sender = sender; 12 | } 13 | 14 | @Override 15 | public void handle(SendNewCoursesNewsletterCommand command) { 16 | sender.send(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/notifications/domain/EmailId.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.notifications.domain; 2 | 3 | import tv.codely.shared.domain.Identifier; 4 | 5 | public final class EmailId extends Identifier { 6 | public EmailId(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/notifications/domain/EmailSender.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.notifications.domain; 2 | 3 | public interface EmailSender { 4 | void send(Email email); 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/notifications/infrastructure/FakeEmailSender.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.notifications.infrastructure; 2 | 3 | import tv.codely.mooc.notifications.domain.Email; 4 | import tv.codely.mooc.notifications.domain.EmailSender; 5 | import tv.codely.shared.domain.Service; 6 | 7 | @Service 8 | public final class FakeEmailSender implements EmailSender { 9 | @Override 10 | public void send(Email email) { 11 | // In the future... 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/steps/domain/StepId.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain; 2 | 3 | import tv.codely.shared.domain.Identifier; 4 | 5 | public final class StepId extends Identifier { 6 | public StepId(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/steps/domain/StepRepository.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain; 2 | 3 | import java.util.Optional; 4 | 5 | public interface StepRepository { 6 | void save(Step step); 7 | 8 | Optional search(StepId id); 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/steps/domain/StepTitle.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class StepTitle extends StringValueObject { 6 | public StepTitle(String value) { 7 | super(value); 8 | } 9 | 10 | private StepTitle() { 11 | super(null); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/steps/domain/challenge/ChallengeStepStatement.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain.challenge; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class ChallengeStepStatement extends StringValueObject { 6 | public ChallengeStepStatement(String value) { 7 | super(value); 8 | } 9 | 10 | public ChallengeStepStatement() { 11 | super(null); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/steps/domain/video/VideoStep.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain.video; 2 | 3 | import tv.codely.mooc.steps.domain.Step; 4 | import tv.codely.mooc.steps.domain.StepId; 5 | import tv.codely.mooc.steps.domain.StepTitle; 6 | import tv.codely.shared.domain.VideoUrl; 7 | 8 | public final class VideoStep extends Step { 9 | private final VideoUrl videoUrl; 10 | private final VideoStepText text; 11 | 12 | public VideoStep(StepId id, StepTitle title, VideoUrl videoUrl, VideoStepText text) { 13 | super(id, title); 14 | 15 | this.videoUrl = videoUrl; 16 | this.text = text; 17 | } 18 | 19 | private VideoStep() { 20 | super(null, null); 21 | 22 | this.videoUrl = null; 23 | this.text = null; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/steps/domain/video/VideoStepText.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain.video; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class VideoStepText extends StringValueObject { 6 | public VideoStepText(String value) { 7 | super(value); 8 | } 9 | 10 | private VideoStepText() { 11 | super(null); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/students/application/StudentsResponse.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.application; 2 | 3 | import tv.codely.shared.domain.bus.query.Response; 4 | 5 | import java.util.List; 6 | 7 | public final class StudentsResponse implements Response { 8 | private final List students; 9 | 10 | public StudentsResponse(List students) { 11 | this.students = students; 12 | } 13 | 14 | public List students() { 15 | return students; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/students/application/search_all/SearchAllStudentsQuery.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.application.search_all; 2 | 3 | import tv.codely.shared.domain.bus.query.Query; 4 | 5 | import java.util.Objects; 6 | 7 | public final class SearchAllStudentsQuery implements Query { 8 | @Override 9 | public boolean equals(Object o) { 10 | if (this == o) { 11 | return true; 12 | } 13 | return o != null && getClass() == o.getClass(); 14 | } 15 | 16 | @Override 17 | public int hashCode() { 18 | return Objects.hash("SearchAllStudentsQuery"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/students/application/search_all/SearchAllStudentsQueryHandler.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.application.search_all; 2 | 3 | import tv.codely.mooc.students.application.StudentsResponse; 4 | import tv.codely.shared.domain.Service; 5 | import tv.codely.shared.domain.bus.query.QueryHandler; 6 | 7 | @Service 8 | public final class SearchAllStudentsQueryHandler implements QueryHandler { 9 | private final AllStudentsSearcher searcher; 10 | 11 | public SearchAllStudentsQueryHandler(AllStudentsSearcher searcher) { 12 | this.searcher = searcher; 13 | } 14 | 15 | @Override 16 | public StudentsResponse handle(SearchAllStudentsQuery query) { 17 | return searcher.search(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/students/domain/Student.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.domain; 2 | 3 | public final class Student { 4 | private final StudentId id; 5 | private final String name; 6 | private final String surname; 7 | private final String email; 8 | 9 | public Student(StudentId id, String name, String surname, String email) { 10 | this.id = id; 11 | this.name = name; 12 | this.surname = surname; 13 | this.email = email; 14 | } 15 | 16 | public StudentId id() { 17 | return id; 18 | } 19 | 20 | public String name() { 21 | return name; 22 | } 23 | 24 | public String surname() { 25 | return surname; 26 | } 27 | 28 | public String email() { 29 | return email; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/students/domain/StudentId.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.domain; 2 | 3 | import tv.codely.shared.domain.Identifier; 4 | 5 | public final class StudentId extends Identifier { 6 | public StudentId(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/main/tv/codely/mooc/students/domain/StudentRepository.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.domain; 2 | 3 | import java.util.List; 4 | 5 | public interface StudentRepository { 6 | List searchAll(); 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/MoocContextInfrastructureTestCase.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc; 2 | 3 | import org.springframework.boot.test.context.SpringBootTest; 4 | import org.springframework.test.context.ContextConfiguration; 5 | import tv.codely.apps.mooc.backend.MoocBackendApplication; 6 | import tv.codely.shared.infrastructure.InfrastructureTestCase; 7 | 8 | @ContextConfiguration(classes = MoocBackendApplication.class) 9 | @SpringBootTest 10 | public abstract class MoocContextInfrastructureTestCase extends InfrastructureTestCase { 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/CoursesModuleInfrastructureTestCase.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import tv.codely.mooc.MoocContextInfrastructureTestCase; 5 | import tv.codely.mooc.courses.domain.CourseRepository; 6 | import tv.codely.mooc.courses.infrastructure.persistence.InMemoryCourseRepository; 7 | 8 | public abstract class CoursesModuleInfrastructureTestCase extends MoocContextInfrastructureTestCase { 9 | protected InMemoryCourseRepository inMemoryCourseRepository = new InMemoryCourseRepository(); 10 | @Autowired 11 | protected CourseRepository mySqlCourseRepository; 12 | } 13 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/CoursesModuleUnitTestCase.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import tv.codely.mooc.courses.domain.Course; 5 | import tv.codely.mooc.courses.domain.CourseRepository; 6 | import tv.codely.shared.infrastructure.UnitTestCase; 7 | 8 | import static org.mockito.Mockito.*; 9 | 10 | public abstract class CoursesModuleUnitTestCase extends UnitTestCase { 11 | protected CourseRepository repository; 12 | 13 | @BeforeEach 14 | protected void setUp() { 15 | super.setUp(); 16 | 17 | repository = mock(CourseRepository.class); 18 | } 19 | 20 | public void shouldHaveSaved(Course course) { 21 | verify(repository, atLeastOnce()).save(course); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/application/CourseResponseMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.application; 2 | 3 | import tv.codely.mooc.courses.domain.*; 4 | 5 | public final class CourseResponseMother { 6 | public static CourseResponse create(CourseId id, CourseName name, CourseDuration duration) { 7 | return new CourseResponse(id.value(), name.value(), duration.value()); 8 | } 9 | 10 | public static CourseResponse random() { 11 | return create(CourseIdMother.random(), CourseNameMother.random(), CourseDurationMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/application/CoursesResponseMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.application; 2 | 3 | import tv.codely.shared.domain.ListMother; 4 | 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | public final class CoursesResponseMother { 9 | public static CoursesResponse create(List courses) { 10 | return new CoursesResponse(courses); 11 | } 12 | 13 | public static CoursesResponse random() { 14 | return create(ListMother.random(CourseResponseMother::random)); 15 | } 16 | 17 | public static CoursesResponse times(int times) { 18 | return create(ListMother.create(times, CourseResponseMother::random)); 19 | } 20 | 21 | public static CoursesResponse empty() { 22 | return create(Collections.emptyList()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/application/create/CreateCourseCommandMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.application.create; 2 | 3 | import tv.codely.mooc.courses.domain.*; 4 | 5 | public final class CreateCourseCommandMother { 6 | public static CreateCourseCommand create(CourseId id, CourseName name, CourseDuration duration) { 7 | return new CreateCourseCommand(id.value(), name.value(), duration.value()); 8 | } 9 | 10 | public static CreateCourseCommand random() { 11 | return create(CourseIdMother.random(), CourseNameMother.random(), CourseDurationMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/application/search_last/SearchLastCoursesQueryMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.application.search_last; 2 | 3 | import tv.codely.shared.domain.IntegerMother; 4 | 5 | public final class SearchLastCoursesQueryMother { 6 | public static SearchLastCoursesQuery create(Integer total) { 7 | return new SearchLastCoursesQuery(total); 8 | } 9 | 10 | public static SearchLastCoursesQuery random() { 11 | return create(IntegerMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/domain/CourseCreatedDomainEventMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.shared.domain.course.CourseCreatedDomainEvent; 4 | 5 | public final class CourseCreatedDomainEventMother { 6 | public static CourseCreatedDomainEvent create(CourseId id, CourseName name, CourseDuration duration) { 7 | return new CourseCreatedDomainEvent(id.value(), name.value(), duration.value()); 8 | } 9 | 10 | public static CourseCreatedDomainEvent fromCourse(Course course) { 11 | return create(course.id(), course.name(), course.duration()); 12 | } 13 | 14 | public static CourseCreatedDomainEvent random() { 15 | return create(CourseIdMother.random(), CourseNameMother.random(), CourseDurationMother.random()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/domain/CourseDurationMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.shared.domain.IntegerMother; 4 | import tv.codely.shared.domain.RandomElementPicker; 5 | 6 | public final class CourseDurationMother { 7 | public static CourseDuration create(String value) { 8 | return new CourseDuration(value); 9 | } 10 | 11 | public static CourseDuration random() { 12 | return create( 13 | String.format( 14 | "%s %s", 15 | IntegerMother.random(), 16 | RandomElementPicker.from("months", "years", "days", "hours", "minutes", "seconds") 17 | ) 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/domain/CourseIdMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.shared.domain.UuidMother; 4 | 5 | public final class CourseIdMother { 6 | public static CourseId create(String value) { 7 | return new CourseId(value); 8 | } 9 | 10 | public static CourseId random() { 11 | return create(UuidMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/domain/CourseMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.mooc.courses.application.create.CreateCourseCommand; 4 | 5 | public final class CourseMother { 6 | public static Course create(CourseId id, CourseName name, CourseDuration duration) { 7 | return new Course(id, name, duration); 8 | } 9 | 10 | public static Course fromRequest(CreateCourseCommand request) { 11 | return create( 12 | CourseIdMother.create(request.id()), 13 | CourseNameMother.create(request.name()), 14 | CourseDurationMother.create(request.duration()) 15 | ); 16 | } 17 | 18 | public static Course random() { 19 | return create(CourseIdMother.random(), CourseNameMother.random(), CourseDurationMother.random()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses/domain/CourseNameMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses.domain; 2 | 3 | import tv.codely.shared.domain.WordMother; 4 | 5 | public final class CourseNameMother { 6 | public static CourseName create(String value) { 7 | return new CourseName(value); 8 | } 9 | 10 | public static CourseName random() { 11 | return create(WordMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses_counter/CoursesCounterModuleInfrastructureTestCase.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import tv.codely.mooc.MoocContextInfrastructureTestCase; 5 | import tv.codely.mooc.courses_counter.domain.CoursesCounterRepository; 6 | 7 | public abstract class CoursesCounterModuleInfrastructureTestCase extends MoocContextInfrastructureTestCase { 8 | @Autowired 9 | protected CoursesCounterRepository repository; 10 | } 11 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses_counter/application/find/CoursesCounterResponseMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter.application.find; 2 | 3 | import tv.codely.shared.domain.IntegerMother; 4 | 5 | final class CoursesCounterResponseMother { 6 | public static CoursesCounterResponse create(Integer value) { 7 | return new CoursesCounterResponse(value); 8 | } 9 | 10 | public static CoursesCounterResponse random() { 11 | return create(IntegerMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses_counter/domain/CoursesCounterIdMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter.domain; 2 | 3 | import tv.codely.shared.domain.UuidMother; 4 | 5 | public final class CoursesCounterIdMother { 6 | public static CoursesCounterId create(String value) { 7 | return new CoursesCounterId(value); 8 | } 9 | 10 | public static CoursesCounterId random() { 11 | return create(UuidMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/courses_counter/domain/CoursesCounterTotalMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.courses_counter.domain; 2 | 3 | import tv.codely.shared.domain.IntegerMother; 4 | 5 | public final class CoursesCounterTotalMother { 6 | public static CoursesCounterTotal create(Integer value) { 7 | return new CoursesCounterTotal(value); 8 | } 9 | 10 | public static CoursesCounterTotal random() { 11 | return create(IntegerMother.random()); 12 | } 13 | 14 | public static CoursesCounterTotal one() { 15 | return create(1); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/notifications/application/send_new_courses_newsletter/SendNewCoursesNewsletterCommandMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.notifications.application.send_new_courses_newsletter; 2 | 3 | import tv.codely.shared.domain.UuidMother; 4 | 5 | public final class SendNewCoursesNewsletterCommandMother { 6 | public static SendNewCoursesNewsletterCommand random() { 7 | return new SendNewCoursesNewsletterCommand(UuidMother.random()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/notifications/domain/EmailIdMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.notifications.domain; 2 | 3 | import tv.codely.shared.domain.UuidMother; 4 | 5 | public final class EmailIdMother { 6 | public static EmailId create(String value) { 7 | return new EmailId(value); 8 | } 9 | 10 | public static EmailId random() { 11 | return create(UuidMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/notifications/domain/NewCoursesNewsletterEmailSentMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.notifications.domain; 2 | 3 | import tv.codely.mooc.students.domain.StudentIdMother; 4 | 5 | public final class NewCoursesNewsletterEmailSentMother { 6 | public static NewCoursesNewsletterEmailSent create(EmailId id, String studentId) { 7 | return new NewCoursesNewsletterEmailSent(id.value(), studentId); 8 | } 9 | 10 | public static NewCoursesNewsletterEmailSent random() { 11 | return create(EmailIdMother.random(), StudentIdMother.random().value()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/shared/infrastructure/bus/event/rabbitmq/TestAllWorksOnRabbitMqEventsPublished.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.shared.infrastructure.bus.event.rabbitmq; 2 | 3 | import tv.codely.shared.domain.Service; 4 | import tv.codely.shared.domain.bus.event.DomainEventSubscriber; 5 | import tv.codely.shared.domain.course.CourseCreatedDomainEvent; 6 | 7 | @Service 8 | @DomainEventSubscriber({CourseCreatedDomainEvent.class}) 9 | public final class TestAllWorksOnRabbitMqEventsPublished { 10 | public Boolean hasBeenExecuted = false; 11 | 12 | public void on(CourseCreatedDomainEvent event) { 13 | hasBeenExecuted = true; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/steps/StepsModuleInfrastructureTestCase.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import tv.codely.mooc.MoocContextInfrastructureTestCase; 5 | import tv.codely.mooc.steps.domain.StepRepository; 6 | 7 | public abstract class StepsModuleInfrastructureTestCase extends MoocContextInfrastructureTestCase { 8 | @Autowired 9 | protected StepRepository repository; 10 | } 11 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/steps/domain/StepIdMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain; 2 | 3 | import tv.codely.shared.domain.UuidMother; 4 | 5 | public final class StepIdMother { 6 | public static StepId create(String value) { 7 | return new StepId(value); 8 | } 9 | 10 | public static StepId random() { 11 | return create(UuidMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/steps/domain/StepTitleMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain; 2 | 3 | import tv.codely.shared.domain.WordMother; 4 | 5 | public final class StepTitleMother { 6 | public static StepTitle create(String value) { 7 | return new StepTitle(value); 8 | } 9 | 10 | public static StepTitle random() { 11 | return create(WordMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/steps/domain/challenge/ChallengeStepMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain.challenge; 2 | 3 | import tv.codely.mooc.steps.domain.StepId; 4 | import tv.codely.mooc.steps.domain.StepIdMother; 5 | import tv.codely.mooc.steps.domain.StepTitle; 6 | import tv.codely.mooc.steps.domain.StepTitleMother; 7 | 8 | public final class ChallengeStepMother { 9 | public static ChallengeStep create(StepId id, StepTitle title, ChallengeStepStatement statement) { 10 | return new ChallengeStep(id, title, statement); 11 | } 12 | 13 | public static ChallengeStep random() { 14 | return create(StepIdMother.random(), StepTitleMother.random(), ChallengeStepStatementMother.random()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/steps/domain/challenge/ChallengeStepStatementMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain.challenge; 2 | 3 | import tv.codely.shared.domain.WordMother; 4 | 5 | public final class ChallengeStepStatementMother { 6 | public static ChallengeStepStatement create(String value) { 7 | return new ChallengeStepStatement(value); 8 | } 9 | 10 | public static ChallengeStepStatement random() { 11 | return create(WordMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/steps/domain/video/VideoStepTextMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.steps.domain.video; 2 | 3 | import tv.codely.shared.domain.WordMother; 4 | 5 | public final class VideoStepTextMother { 6 | public static VideoStepText create(String value) { 7 | return new VideoStepText(value); 8 | } 9 | 10 | public static VideoStepText random() { 11 | return create(WordMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/students/application/StudentResponseMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.application; 2 | 3 | import tv.codely.mooc.students.domain.StudentId; 4 | import tv.codely.mooc.students.domain.StudentIdMother; 5 | import tv.codely.shared.domain.EmailMother; 6 | import tv.codely.shared.domain.WordMother; 7 | 8 | public final class StudentResponseMother { 9 | public static StudentResponse create(StudentId id, String name, String surname, String email) { 10 | return new StudentResponse(id.value(), name, surname, email); 11 | } 12 | 13 | public static StudentResponse random() { 14 | return create(StudentIdMother.random(), WordMother.random(), WordMother.random(), EmailMother.random()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/students/application/StudentsResponseMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.application; 2 | 3 | import tv.codely.shared.domain.ListMother; 4 | 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | public final class StudentsResponseMother { 9 | public static StudentsResponse create(List courses) { 10 | return new StudentsResponse(courses); 11 | } 12 | 13 | public static StudentsResponse random() { 14 | return create(ListMother.random(StudentResponseMother::random)); 15 | } 16 | 17 | public static StudentsResponse empty() { 18 | return create(Collections.emptyList()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/students/application/search_all/SearchAllStudentsQueryMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.application.search_all; 2 | 3 | public final class SearchAllStudentsQueryMother { 4 | public static SearchAllStudentsQuery random() { 5 | return new SearchAllStudentsQuery(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/mooc/test/tv/codely/mooc/students/domain/StudentIdMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.students.domain; 2 | 3 | import tv.codely.shared.domain.UuidMother; 4 | 5 | public final class StudentIdMother { 6 | public static StudentId create(String value) { 7 | return new StudentId(value); 8 | } 9 | 10 | public static StudentId random() { 11 | return create(UuidMother.random()); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | } 3 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/AggregateRoot.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | import tv.codely.shared.domain.bus.event.DomainEvent; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | public abstract class AggregateRoot { 10 | private List domainEvents = new ArrayList<>(); 11 | 12 | final public List pullDomainEvents() { 13 | List events = domainEvents; 14 | 15 | domainEvents = Collections.emptyList(); 16 | 17 | return events; 18 | } 19 | 20 | final protected void record(DomainEvent event) { 21 | domainEvents.add(event); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/DomainError.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | public abstract class DomainError extends RuntimeException { 4 | private final String errorCode; 5 | private final String errorMessage; 6 | 7 | public DomainError(String errorCode, String errorMessage) { 8 | super(errorMessage); 9 | 10 | this.errorCode = errorCode; 11 | this.errorMessage = errorMessage; 12 | } 13 | 14 | public String errorCode() { 15 | return errorCode; 16 | } 17 | 18 | public String errorMessage() { 19 | return errorMessage; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/IntValueObject.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | import java.util.Objects; 4 | 5 | public abstract class IntValueObject { 6 | private Integer value; 7 | 8 | public IntValueObject(Integer value) { 9 | this.value = value; 10 | } 11 | 12 | public Integer value() { 13 | return value; 14 | } 15 | 16 | @Override 17 | public boolean equals(Object o) { 18 | if (this == o) { 19 | return true; 20 | } 21 | if (o == null || getClass() != o.getClass()) { 22 | return false; 23 | } 24 | IntValueObject that = (IntValueObject) o; 25 | return value.equals(that.value); 26 | } 27 | 28 | @Override 29 | public int hashCode() { 30 | return Objects.hash(value); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/Logger.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | 6 | public interface Logger { 7 | void info(String message); 8 | void info(String message, HashMap context); 9 | 10 | void warning(String message); 11 | void warning(String message, HashMap context); 12 | 13 | void critical(String message); 14 | void critical(String message, HashMap context); 15 | } 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/Monitoring.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | import java.util.HashMap; 4 | 5 | public interface Monitoring { 6 | void incrementCounter(int times); 7 | 8 | void incrementGauge(int times); 9 | void decrementGauge(int times); 10 | void setGauge(int value); 11 | 12 | void observeHistogram(int value, HashMap labels); 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/Service.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Retention(RetentionPolicy.RUNTIME) 6 | @Target(ElementType.TYPE) 7 | @Inherited 8 | public @interface Service { 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/UuidGenerator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | public interface UuidGenerator { 4 | String generate(); 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/VideoUrl.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | public final class VideoUrl extends StringValueObject { 4 | public VideoUrl(String value) { 5 | super(value); 6 | } 7 | 8 | public VideoUrl() { 9 | super(null); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/command/Command.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.command; 2 | 3 | public interface Command { 4 | } 5 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/command/CommandBus.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.command; 2 | 3 | public interface CommandBus { 4 | void dispatch(Command command) throws CommandHandlerExecutionError; 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/command/CommandHandler.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.command; 2 | 3 | public interface CommandHandler { 4 | void handle(T command); 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/command/CommandHandlerExecutionError.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.command; 2 | 3 | public final class CommandHandlerExecutionError extends RuntimeException { 4 | public CommandHandlerExecutionError(Throwable cause) { 5 | super(cause); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/command/CommandNotRegisteredError.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.command; 2 | 3 | public final class CommandNotRegisteredError extends Exception { 4 | public CommandNotRegisteredError(Class command) { 5 | super(String.format("The command <%s> hasn't a command handler associated", command.toString())); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/command/Middleware.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.command; 2 | 3 | public interface Middleware { 4 | void handle(T command); 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/event/DomainEventSubscriber.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.event; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Retention(RetentionPolicy.RUNTIME) 6 | @Target(ElementType.TYPE) 7 | @Inherited 8 | public @interface DomainEventSubscriber { 9 | Class[] value(); 10 | } 11 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/event/EventBus.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.event; 2 | 3 | import java.util.List; 4 | 5 | public interface EventBus { 6 | void publish(final List events); 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/query/Query.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.query; 2 | 3 | public interface Query { 4 | } 5 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/query/QueryBus.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.query; 2 | 3 | public interface QueryBus { 4 | R ask(Query query) throws QueryHandlerExecutionError; 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/query/QueryHandler.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.query; 2 | 3 | public interface QueryHandler { 4 | R handle(Q query); 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/query/QueryHandlerExecutionError.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.query; 2 | 3 | public final class QueryHandlerExecutionError extends RuntimeException { 4 | public QueryHandlerExecutionError(Throwable cause) { 5 | super(cause); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/query/QueryNotRegisteredError.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.query; 2 | 3 | public final class QueryNotRegisteredError extends Exception { 4 | public QueryNotRegisteredError(Class query) { 5 | super(String.format("The query <%s> hasn't a query handler associated", query.toString())); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/bus/query/Response.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.bus.query; 2 | 3 | public interface Response { 4 | } 5 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/criteria/FilterField.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.criteria; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class FilterField extends StringValueObject { 6 | public FilterField(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/criteria/FilterValue.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.criteria; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class FilterValue extends StringValueObject { 6 | public FilterValue(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/criteria/OrderBy.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.criteria; 2 | 3 | import tv.codely.shared.domain.StringValueObject; 4 | 5 | public final class OrderBy extends StringValueObject { 6 | public OrderBy(String value) { 7 | super(value); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/domain/criteria/OrderType.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain.criteria; 2 | 3 | public enum OrderType { 4 | ASC("asc"), 5 | DESC("desc"), 6 | NONE("none"); 7 | private final String type; 8 | 9 | OrderType(String type) { 10 | this.type = type; 11 | } 12 | 13 | public boolean isNone() { 14 | return this == NONE; 15 | } 16 | 17 | public boolean isAsc() { 18 | return this == ASC; 19 | } 20 | 21 | public String value() { 22 | return type; 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/JavaUuidGenerator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure; 2 | 3 | import tv.codely.shared.domain.Service; 4 | import tv.codely.shared.domain.UuidGenerator; 5 | 6 | import java.util.UUID; 7 | 8 | @Service 9 | public final class JavaUuidGenerator implements UuidGenerator { 10 | @Override 11 | public String generate() { 12 | return UUID.randomUUID().toString(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/bus/command/CommandHandlerMiddleware.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.bus.command; 2 | 3 | import tv.codely.shared.domain.bus.command.Command; 4 | import tv.codely.shared.domain.bus.command.CommandHandler; 5 | import tv.codely.shared.domain.bus.command.Middleware; 6 | 7 | public class CommandHandlerMiddleware implements Middleware { 8 | private final CommandHandler commandHandler; 9 | 10 | CommandHandlerMiddleware(CommandHandler commandHandler) { 11 | this.commandHandler = commandHandler; 12 | } 13 | 14 | @Override 15 | public void handle(T command) { 16 | commandHandler.handle(command); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/bus/event/rabbitmq/RabbitMqExchangeNameFormatter.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.bus.event.rabbitmq; 2 | 3 | public final class RabbitMqExchangeNameFormatter { 4 | public static String retry(String exchangeName) { 5 | return String.format("retry-%s", exchangeName); 6 | } 7 | 8 | public static String deadLetter(String exchangeName) { 9 | return String.format("dead_letter-%s", exchangeName); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/bus/event/rabbitmq/RabbitMqQueueNameFormatter.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.bus.event.rabbitmq; 2 | 3 | import tv.codely.shared.infrastructure.bus.event.DomainEventSubscriberInformation; 4 | 5 | public final class RabbitMqQueueNameFormatter { 6 | public static String format(DomainEventSubscriberInformation information) { 7 | return information.formatRabbitMqQueueName(); 8 | } 9 | 10 | public static String formatRetry(DomainEventSubscriberInformation information) { 11 | return String.format("retry.%s", format(information)); 12 | } 13 | 14 | public static String formatDeadLetter(DomainEventSubscriberInformation information) { 15 | return String.format("dead_letter.%s", format(information)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/config/Parameter.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.config; 2 | 3 | import io.github.cdimascio.dotenv.Dotenv; 4 | import tv.codely.shared.domain.Service; 5 | 6 | @Service 7 | public final class Parameter { 8 | private final Dotenv dotenv; 9 | 10 | public Parameter(Dotenv dotenv) { 11 | this.dotenv = dotenv; 12 | } 13 | 14 | public String get(String key) throws ParameterNotExist { 15 | String value = dotenv.get(key); 16 | 17 | if (null == value) { 18 | throw new ParameterNotExist(key); 19 | } 20 | 21 | return value; 22 | } 23 | 24 | public Integer getInt(String key) throws ParameterNotExist { 25 | String value = get(key); 26 | 27 | return Integer.parseInt(value); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/config/ParameterNotExist.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.config; 2 | 3 | public final class ParameterNotExist extends Throwable { 4 | public ParameterNotExist(String key) { 5 | super(String.format("The parameter <%s> does not exist in the environment file", key)); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/validation/ValidationResponse.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.validation; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | 6 | public final class ValidationResponse { 7 | private HashMap> validationErrors; 8 | 9 | public ValidationResponse(HashMap> validationErrors) { 10 | this.validationErrors = validationErrors; 11 | } 12 | 13 | public Boolean hasErrors() { 14 | return !validationErrors.isEmpty(); 15 | } 16 | 17 | public HashMap> errors() { 18 | return validationErrors; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/validation/ValidatorNotExist.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.validation; 2 | 3 | public final class ValidatorNotExist extends Exception { 4 | public ValidatorNotExist(String name) { 5 | super(String.format("The validator <%s> does not exist", name)); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/validation/validators/FieldValidator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.validation.validators; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | 6 | public interface FieldValidator { 7 | Boolean isValid(String fieldName, HashMap fields); 8 | 9 | String errorMessage(String fieldName); 10 | } 11 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/validation/validators/NotEmptyValidator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.validation.validators; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | 6 | public final class NotEmptyValidator implements FieldValidator { 7 | @Override 8 | public Boolean isValid(String fieldName, HashMap fields) { 9 | return !fields.get(fieldName).toString().isEmpty(); 10 | } 11 | 12 | @Override 13 | public String errorMessage(String fieldName) { 14 | return String.format("The field <%s> should not be empty", fieldName); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/validation/validators/RequiredValidator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.validation.validators; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | 6 | public final class RequiredValidator implements FieldValidator { 7 | @Override 8 | public Boolean isValid(String fieldName, HashMap fields) { 9 | return fields.containsKey(fieldName); 10 | } 11 | 12 | @Override 13 | public String errorMessage(String fieldName) { 14 | return String.format("The field <%s> is required", fieldName); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/validation/validators/StringValidator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.validation.validators; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | 6 | public final class StringValidator implements FieldValidator { 7 | @Override 8 | public Boolean isValid(String fieldName, HashMap fields) { 9 | return true; 10 | } 11 | 12 | @Override 13 | public String errorMessage(String fieldName) { 14 | return String.format("The field <%s> should be of type string", fieldName); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/main/tv/codely/shared/infrastructure/validation/validators/UuidValidator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.infrastructure.validation.validators; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | import java.util.regex.Pattern; 6 | 7 | public final class UuidValidator implements FieldValidator { 8 | @Override 9 | public Boolean isValid(String fieldName, HashMap fields) { 10 | Pattern uuidPattern = Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"); 11 | 12 | return uuidPattern.matcher((String) fields.get(fieldName)).matches(); 13 | } 14 | 15 | @Override 16 | public String errorMessage(String fieldName) { 17 | return String.format("The field <%s> is not a valid uuid", fieldName); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/test/tv/codely/shared/domain/EmailMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | public final class EmailMother { 4 | public static String random() { 5 | return MotherCreator.random().internet().emailAddress(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/test/tv/codely/shared/domain/IntegerMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | public final class IntegerMother { 4 | public static Integer random() { 5 | return MotherCreator.random().number().randomDigit(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/test/tv/codely/shared/domain/ListMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.function.Supplier; 7 | 8 | public final class ListMother { 9 | public static List create(Integer size, Supplier creator) { 10 | ArrayList list = new ArrayList<>(); 11 | 12 | for (int i = 0; i < size; i++) { 13 | list.add(creator.get()); 14 | } 15 | 16 | return list; 17 | } 18 | 19 | public static List random(Supplier creator) { 20 | return create(IntegerMother.random(), creator); 21 | } 22 | 23 | public static List one(T element) { 24 | return Collections.singletonList(element); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/test/tv/codely/shared/domain/MotherCreator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | import com.github.javafaker.Faker; 4 | 5 | public final class MotherCreator { 6 | private final static Faker faker = new Faker(); 7 | 8 | public static Faker random() { 9 | return faker; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/test/tv/codely/shared/domain/RandomElementPicker.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | import java.util.Random; 4 | 5 | public final class RandomElementPicker { 6 | @SafeVarargs 7 | public static T from(T... elements) { 8 | Random rand = new Random(); 9 | 10 | return elements[rand.nextInt(elements.length)]; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/test/tv/codely/shared/domain/UuidMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | import java.util.UUID; 4 | 5 | public final class UuidMother { 6 | public static String random() { 7 | return UUID.randomUUID().toString(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/test/tv/codely/shared/domain/VideoUrlMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | public final class VideoUrlMother { 4 | public static VideoUrl create(String value) { 5 | return new VideoUrl(value); 6 | } 7 | 8 | public static VideoUrl random() { 9 | return create(MotherCreator.random().internet().url()); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/src/shared/test/tv/codely/shared/domain/WordMother.java: -------------------------------------------------------------------------------- 1 | package tv.codely.shared.domain; 2 | 3 | public final class WordMother { 4 | public static String random() { 5 | return MotherCreator.random().lorem().word(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/var/log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/chain-of-responsibility/command-bus-middleware/java/var/log/.gitkeep -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | max_line_length = 100 5 | indent_style = space 6 | indent_size = 2 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: "@typescript-eslint/parser", 3 | extends: [ 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:prettier/recommended", 6 | ], 7 | plugins: ["simple-import-sort", "import"], 8 | parserOptions: { 9 | ecmaVersion: 12, 10 | sourceType: "module", 11 | }, 12 | rules: { 13 | "simple-import-sort/imports": "error", 14 | "simple-import-sort/exports": "error", 15 | "import/first": "error", 16 | "import/newline-after-import": "error", 17 | "import/no-duplicates": "error", 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testMatch: ["**/tests/**/*.test.ts"], 3 | transform: { 4 | "\\.ts$": "@swc/jest", 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/src/Command.ts: -------------------------------------------------------------------------------- 1 | export interface Command {} 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/src/CommandHandler.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "./Command"; 2 | 3 | export interface CommandHandler { 4 | handle(command: Command): void; 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/src/InMemoryCommandBus.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "./Command"; 2 | import { CommandHandler } from "./CommandHandler"; 3 | import { functionalLoggerMiddleware } from "./LoggerMiddleware"; 4 | import { functionalTransactionalMiddleware } from "./TransactionalMiddleware"; 5 | 6 | export class InMemoryCommandBus { 7 | constructor(private readonly commandHandler: CommandHandler) {} 8 | 9 | dispatch(command: Command): void { 10 | const transactionalMiddleware = functionalTransactionalMiddleware(this.commandHandler.handle); 11 | const loggerMiddleware = functionalLoggerMiddleware(transactionalMiddleware); 12 | 13 | loggerMiddleware(command); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/src/LoggerMiddleware.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "./Command"; 2 | import { Middleware } from "./Middleware"; 3 | 4 | export function functionalLoggerMiddleware(next: Middleware): Middleware { 5 | return function (command: Command): void { 6 | console.log(`Ejecutando ${command.constructor.name}`); 7 | 8 | next(command); 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/src/Middleware.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "./Command"; 2 | 3 | export type Middleware = (command: Command) => void; 4 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/src/TransactionalMiddleware.ts: -------------------------------------------------------------------------------- 1 | import { Command } from "./Command"; 2 | import { Middleware } from "./Middleware"; 3 | 4 | export function functionalTransactionalMiddleware(next: Middleware): Middleware { 5 | return function (command: Command): void { 6 | try { 7 | next(command); 8 | } catch (error: unknown) { 9 | // Rollback 10 | throw error; 11 | } 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/src/index.ts: -------------------------------------------------------------------------------- 1 | import { InMemoryCommandBus } from "./InMemoryCommandBus"; 2 | 3 | const commandBus = new InMemoryCommandBus(); 4 | commandBus.dispatch(); 5 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/tests/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["jest"], 3 | "env": { 4 | "jest/globals": true 5 | } 6 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/chain-of-responsibility/functional/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "experimentalDecorators": true 11 | }, 12 | "include": ["src/**/*.ts"], 13 | "exclude": ["node_modules"] 14 | } 15 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [*.java] 10 | indent_size = 4 11 | indent_style = space 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/.github/workflows/workflow.yml: -------------------------------------------------------------------------------- 1 | name: Main Workflow 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | 13 | - uses: actions/setup-java@v1 14 | with: 15 | java-version: 17 16 | 17 | - name: Assemble 18 | run: ./gradlew assemble --warning-mode all 19 | 20 | - name: Check 21 | run: ./gradlew check --warning-mode all 22 | 23 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle 2 | .gradle 3 | build/ 4 | 5 | # Ignore Gradle GUI config 6 | gradle-app.setting 7 | 8 | var/log/* 9 | !var/log/.gitkeep 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: build 3 | 4 | .PHONY: build 5 | build: 6 | @./gradlew assemble --warning-mode all 7 | 8 | .PHONY: test 9 | test: 10 | @./gradlew check --warning-mode all 11 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/README.md: -------------------------------------------------------------------------------- 1 | # Command design pattern: Java 2 | 3 | Java implementation of the [Command pattern applied to HTTP Controllers example](../README.md). 4 | 5 | ## Steps 6 | 7 | To navigate between steps use `git checkout` command 8 | using the specified commit hash below 👇 9 | 10 | 1. Starting point 11 | 2. Apply the Command design pattern 12 | 3. Replace Command with CommandHandler 13 | 4. Command pattern for query actions 14 | 15 | ```bash 16 | # step 1 17 | git checkout 473e7160 18 | 19 | # step 2 20 | git checkout 20f84858 21 | 22 | # step 3 23 | git checkout d37f2bc8 24 | 25 | # step 4 26 | git checkout 11a50aa8 27 | ``` 28 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/doc/endpoints/mooc_courses.http: -------------------------------------------------------------------------------- 1 | ### Create a course 2 | PUT localhost:8080/courses/6854aaba-0ded-4837-bf18-cae3caad45ed 3 | Content-Type: application/json 4 | 5 | { 6 | "name": "Patrones de Diseño", 7 | "duration": "2 horas" 8 | } 9 | 10 | ### Find a course 11 | GET localhost:8080/courses/6854aaba-0ded-4837-bf18-cae3caad45ed 12 | 13 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/command/java/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Application/Command.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Application; 2 | 3 | public interface Command { 4 | } 5 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Application/CommandHandler.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Application; 2 | 3 | public abstract class CommandHandler { 4 | public R execute(T command) { 5 | var result = this.run(command); 6 | this.log(command); 7 | return result; 8 | } 9 | 10 | abstract protected void log(T command); 11 | abstract protected R run(T command); 12 | } 13 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Application/Create/CourseCreator.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Application.Create; 2 | 3 | import org.springframework.stereotype.Service; 4 | import tv.codely.mooc.api.Domain.Course; 5 | import tv.codely.mooc.api.Domain.CourseRepository; 6 | 7 | @Service 8 | public class CourseCreator { 9 | private final CourseRepository repository; 10 | 11 | public CourseCreator(CourseRepository repository) { 12 | this.repository = repository; 13 | } 14 | 15 | public void create(String id, String name, String duration) { 16 | var course = new Course(id, name, duration); 17 | repository.save(course); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Application/Create/CreateCourseCommand.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Application.Create; 2 | 3 | import tv.codely.mooc.api.Application.Command; 4 | 5 | public record CreateCourseCommand(String id, String name, String duration) implements Command { 6 | } 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Domain/Course.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Domain; 2 | 3 | public class Course { 4 | private final CourseId id; 5 | private final CourseName name; 6 | private final CourseDuration duration; 7 | 8 | public Course(String id, String name, String duration) { 9 | this.id = new CourseId(id); 10 | this.name = new CourseName(name); 11 | this.duration = new CourseDuration(duration); 12 | } 13 | 14 | public String id() { 15 | return id.value(); 16 | } 17 | 18 | public String name() { 19 | return name.value(); 20 | } 21 | 22 | public String duration() { 23 | return duration.value(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Domain/CourseDuration.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Domain; 2 | 3 | public final class CourseDuration extends StringValueObject { 4 | public CourseDuration(String value) { 5 | super(value); 6 | } 7 | 8 | private CourseDuration() { 9 | super(""); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Domain/CourseId.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Domain; 2 | 3 | public final class CourseId extends Identifier { 4 | public CourseId(String value) { 5 | super(value); 6 | } 7 | 8 | public CourseId() { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Domain/CourseName.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Domain; 2 | 3 | public final class CourseName extends StringValueObject { 4 | public CourseName(String value) { 5 | super(value); 6 | } 7 | 8 | public CourseName() { 9 | super(""); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Domain/CourseNotExist.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Domain; 2 | 3 | public final class CourseNotExist extends DomainError { 4 | public CourseNotExist(CourseId id) { 5 | super("course_not_exist", String.format("The course <%s> doesn't exist", id.value())); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Domain/CourseRepository.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Domain; 2 | 3 | import java.util.Optional; 4 | 5 | public interface CourseRepository { 6 | void save(Course course); 7 | 8 | Optional search(CourseId id); 9 | } 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Domain/DomainError.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Domain; 2 | 3 | public abstract class DomainError extends RuntimeException { 4 | private final String errorCode; 5 | private final String errorMessage; 6 | 7 | public DomainError(String errorCode, String errorMessage) { 8 | super(errorMessage); 9 | 10 | this.errorCode = errorCode; 11 | this.errorMessage = errorMessage; 12 | } 13 | 14 | public String errorCode() { 15 | return errorCode; 16 | } 17 | 18 | public String errorMessage() { 19 | return errorMessage; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Infrastructure/Persistence/InMemoryCourseRepository.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Infrastructure.Persistence; 2 | 3 | import org.springframework.stereotype.Service; 4 | import tv.codely.mooc.api.Domain.Course; 5 | import tv.codely.mooc.api.Domain.CourseId; 6 | import tv.codely.mooc.api.Domain.CourseRepository; 7 | 8 | import java.util.HashMap; 9 | import java.util.Optional; 10 | 11 | @Service 12 | public class InMemoryCourseRepository implements CourseRepository { 13 | private final HashMap courses = new HashMap<>(); 14 | 15 | public void save(Course course) { 16 | courses.put(course.id(), course); 17 | } 18 | 19 | public Optional search(CourseId id) { 20 | return Optional.ofNullable(courses.get(id.value())); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/MoocApplication.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class MoocApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(MoocApplication.class, args); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/main/java/tv/codely/mooc/api/Ui/Api/Controller/CoursePutControllerRequestBody.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Ui.Api.Controller; 2 | 3 | record CoursePutControllerRequestBody(String name, String duration) {} 4 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/test/java/tv/codely/mooc/api/Ui/Api/Controller/CoursesPutControllerShould.java: -------------------------------------------------------------------------------- 1 | package tv.codely.mooc.api.Ui.Api.Controller; 2 | 3 | import org.json.JSONObject; 4 | import org.junit.jupiter.api.Test; 5 | import tv.codely.mooc.api.ApiTestCase; 6 | 7 | public class CoursesPutControllerShould extends ApiTestCase { 8 | @Test 9 | public void create_a_valid_non_existing_course() throws Exception { 10 | var newCourseJsonBody = new JSONObject() 11 | .put("name", "The best course") 12 | .put("duration", "5 hours") 13 | .toString(); 14 | 15 | whenPutRequestSentTo("/courses/0def00e9-b7b0-4d2b-ba98-721a1f6acf8a", newCourseJsonBody); 16 | 17 | assertEmptyJsonResponse(201); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/test/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/command/java/src/test/resources/application.properties -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/command/java/var/log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/command/java/var/log/.gitkeep -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/README.md: -------------------------------------------------------------------------------- 1 | Iterator pattern applied to Data Access 2 | ======================================= 3 | 4 | An example using Generators using the Iterator pattern 5 | to access database data in an efficient way. 6 | 7 | ## Languages 8 | 9 | - [TypeScript](typescript) 10 | 11 | ## Patterns used in this example 12 | 13 | - [Visitor](/design-patterns/behavioral/memento) 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: "@typescript-eslint/parser", 3 | extends: [ 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:prettier/recommended", 6 | ], 7 | plugins: ["simple-import-sort", "import"], 8 | parserOptions: { 9 | ecmaVersion: 12, 10 | sourceType: "module", 11 | }, 12 | rules: { 13 | "simple-import-sort/imports": "error", 14 | "simple-import-sort/exports": "error", 15 | "import/first": "error", 16 | "import/newline-after-import": "error", 17 | "import/no-duplicates": "error", 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testMatch: ["**/tests/**/*.test.ts"], 3 | transform: { 4 | "\\.ts$": "@swc/jest", 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/AggregateRoot.ts: -------------------------------------------------------------------------------- 1 | import { DomainEvent } from "./DomainEvent"; 2 | 3 | export class AggregateRoot { 4 | private recordedEvents: DomainEvent[] = []; 5 | 6 | record(domainEvent: DomainEvent): void { 7 | this.recordedEvents.push(domainEvent); 8 | } 9 | 10 | pullDomainEvents(): DomainEvent[] { 11 | const events = this.recordedEvents; 12 | this.recordedEvents = []; 13 | return events; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/CourseRepository.ts: -------------------------------------------------------------------------------- 1 | import { Course } from "./Course"; 2 | 3 | export interface CourseRepository { 4 | save(course: Course): void; 5 | 6 | find(id: string): Course; 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/CourseReview.ts: -------------------------------------------------------------------------------- 1 | import { Stars } from "./Stars"; 2 | 3 | export class CourseReview { 4 | constructor(public readonly stars: Stars) {} 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/CourseReviews.ts: -------------------------------------------------------------------------------- 1 | import { CourseReview } from "./CourseReview"; 2 | import { CourseReviewsSnapshot } from "./CourseReviewsSnapshot"; 3 | import { Stars } from "./Stars"; 4 | 5 | export class CourseReviews { 6 | constructor(private reviews: CourseReview[]) {} 7 | 8 | meanStars(): number { 9 | const totalStars = this.reviews 10 | .map((review) => review.stars.value) 11 | .reduce((stars: number, total: number) => stars + total, 0); 12 | 13 | const totalReviews = this.reviews.length; 14 | return totalStars / totalReviews; 15 | } 16 | 17 | add(stars: Stars) { 18 | this.reviews.push(new CourseReview(stars)); 19 | } 20 | 21 | createSnapshot(): CourseReviewsSnapshot { 22 | return { 23 | reviews: this.reviews.map((review) => { 24 | return { stars: review.stars.value }; 25 | }), 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/CourseReviewsSnapshot.ts: -------------------------------------------------------------------------------- 1 | export type CourseReviewSnapshot = { stars: number }; 2 | 3 | export type CourseReviewsSnapshot = { 4 | reviews: Array; 5 | }; 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/CourseSnapshot.ts: -------------------------------------------------------------------------------- 1 | import { CourseReviewsSnapshot } from "./CourseReviewsSnapshot"; 2 | 3 | export type CourseSnapshot = { 4 | id: string; 5 | reviews: CourseReviewsSnapshot; 6 | date: Date; 7 | }; 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/DomainEvent.ts: -------------------------------------------------------------------------------- 1 | export interface DomainEvent {} 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/Generator.ts: -------------------------------------------------------------------------------- 1 | export function* generator(...values: number[]): Generator { 2 | for (const value of values) { 3 | yield value; 4 | console.log("continue!"); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/ReviewAdded.ts: -------------------------------------------------------------------------------- 1 | export class ReviewAdded { 2 | constructor(public readonly id: string, public readonly stars: number) {} 3 | } 4 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/src/Stars.ts: -------------------------------------------------------------------------------- 1 | export class Stars { 2 | constructor(public readonly value: number) { 3 | if (value < 1 || value > 5) { 4 | throw new Error("Invalid stars value"); 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/tests/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["jest"], 3 | "env": { 4 | "jest/globals": true 5 | } 6 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/tests/Generator.test.ts: -------------------------------------------------------------------------------- 1 | import { generator } from "../src/Generator"; 2 | 3 | describe("Iterator should", () => { 4 | it("saves and restores a Course", () => { 5 | for (const value of generator(1, 2, 3, 4, 5)) { 6 | console.log(value); 7 | } 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/iterator/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "experimentalDecorators": true 11 | }, 12 | "include": ["src/**/*.ts"], 13 | "exclude": ["node_modules"] 14 | } 15 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/README.md: -------------------------------------------------------------------------------- 1 | Mediator pattern applied to a Backend use case 2 | ============================================== 3 | 4 | An example of the Mediator pattern applied 5 | to a Backend use case, to decouple SignUp main 6 | use case from the derived use cases like SendWelcomeEmail. 7 | 8 | ## Description 9 | 10 | In this example we start with a single use case, in which all 11 | the application logic is executed. 12 | 13 | In this example we apply the Mediator design pattern as an 14 | abstraction to split the SignUp main use case from the derived 15 | use cases: 16 | - CreateDefaultWorkspace 17 | - AssignUserToWorkspace 18 | - SendWelcomeEmail 19 | 20 | ## Languages 21 | 22 | - [typeScript](typescript) 23 | 24 | ## Patterns used in this example 25 | 26 | - [Mediator](/design-patterns/behavioral/mediator) 27 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: "@typescript-eslint/parser", 3 | extends: [ 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:prettier/recommended", 6 | ], 7 | plugins: ["simple-import-sort", "import"], 8 | parserOptions: { 9 | ecmaVersion: 12, 10 | sourceType: "module", 11 | }, 12 | rules: { 13 | "simple-import-sort/imports": "error", 14 | "simple-import-sort/exports": "error", 15 | "import/first": "error", 16 | "import/newline-after-import": "error", 17 | "import/no-duplicates": "error", 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | 3 | on: push 4 | 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | 12 | - name: Cache node modules 13 | uses: actions/cache@v2 14 | env: 15 | cache-name: cache-node-modules 16 | with: 17 | path: ~/.npm 18 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 19 | restore-keys: | 20 | ${{ runner.os }}-build-${{ env.cache-name }}- 21 | ${{ runner.os }}-build- 22 | ${{ runner.os }}- 23 | 24 | - name: Install Dependencies 25 | run: npm install 26 | 27 | - name: Lint 28 | run: npm run lint -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: push 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | 12 | - name: Cache node modules 13 | uses: actions/cache@v2 14 | env: 15 | cache-name: cache-node-modules 16 | with: 17 | path: ~/.npm 18 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 19 | restore-keys: | 20 | ${{ runner.os }}-build-${{ env.cache-name }}- 21 | ${{ runner.os }}-build- 22 | ${{ runner.os }}- 23 | 24 | - name: Install Dependencies 25 | run: npm install 26 | 27 | - name: Test 28 | run: npm run test -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | # API keys and secrets 2 | .env 3 | 4 | # Dependency directory 5 | node_modules 6 | 7 | # Ignore built ts files 8 | dist 9 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | globals: { 3 | "ts-jest": { 4 | tsconfig: "tsconfig.json", 5 | }, 6 | }, 7 | moduleFileExtensions: ["ts", "js"], 8 | transform: { 9 | "^.+\\.(ts|tsx)$": "ts-jest", 10 | }, 11 | testMatch: ["**/test/**/*.spec.(ts|js)"], 12 | testEnvironment: "node", 13 | }; 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/bash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/bash.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/ddd-en-php.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/ddd-en-php.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/ddd-java.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/ddd-java.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/layouts-css.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/layouts-css.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/makefiles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/makefiles.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/novedades-vue-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/novedades-vue-3.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/terminal-zsh.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/mediator/typescript/public/courses/terminal-zsh.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/app.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import path from "path"; 3 | 4 | import { loadApiEndpoints } from "./controllers/api"; 5 | 6 | // Create Express server 7 | const app = express(); 8 | 9 | // Express configuration 10 | app.set("port", process.env.PORT || 3000); 11 | app.use(express.json()); 12 | app.use(express.urlencoded({ extended: true })); 13 | 14 | app.use( 15 | express.static(path.join(__dirname, "../public"), { maxAge: 31557600000 }) 16 | ); 17 | 18 | loadApiEndpoints(app); 19 | 20 | export default app; 21 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/entity/Role.ts: -------------------------------------------------------------------------------- 1 | export enum Role { 2 | admin, 3 | editor, 4 | } 5 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/entity/User.ts: -------------------------------------------------------------------------------- 1 | export class User { 2 | constructor( 3 | public readonly id: string, 4 | public readonly name: string, 5 | public readonly emailAddress: string, 6 | public readonly password: string 7 | ) {} 8 | } 9 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/entity/UserRepository.ts: -------------------------------------------------------------------------------- 1 | import { User } from "./User"; 2 | 3 | export class UserRepository { 4 | save(user: User) { 5 | console.log(user); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/entity/Workspace.ts: -------------------------------------------------------------------------------- 1 | import { Role } from "./Role"; 2 | 3 | export class Workspace { 4 | static default(): Workspace { 5 | return new Workspace(); 6 | } 7 | 8 | assignUser(user: string, role: Role): void { 9 | console.log(`User ${user} assigned to default workspace with role ${role}`); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/entity/WorkspaceRepository.ts: -------------------------------------------------------------------------------- 1 | import { Workspace } from "./Workspace"; 2 | 3 | export class WorkspaceRepository { 4 | save(workspace: Workspace) { 5 | console.log(workspace); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/server.ts: -------------------------------------------------------------------------------- 1 | import app from "./app"; 2 | 3 | /** 4 | * Start Express server. 5 | */ 6 | const server = app.listen(app.get("port"), () => { 7 | console.log( 8 | " App is running at http://localhost:%d in %s mode", 9 | app.get("port"), 10 | app.get("env") 11 | ); 12 | console.log(" Press CTRL-C to stop\n"); 13 | }); 14 | 15 | export default server; 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/service/DomainEvent.ts: -------------------------------------------------------------------------------- 1 | export abstract class DomainEvent { 2 | static EVENT_NAME: string; 3 | 4 | abstract eventName(): string; 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/service/Email.ts: -------------------------------------------------------------------------------- 1 | export class Email { 2 | constructor( 3 | private readonly to: string, 4 | private readonly subject: string, 5 | private readonly body: string 6 | ) {} 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/service/EventBus.ts: -------------------------------------------------------------------------------- 1 | import { DomainEvent } from "./DomainEvent"; 2 | 3 | export interface EventBus { 4 | notify(event: T): void; 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/service/InMemoryEventBus.ts: -------------------------------------------------------------------------------- 1 | import { DomainEvent } from "./DomainEvent"; 2 | import { EventBus } from "./EventBus"; 3 | import { Observer } from "./Observer"; 4 | 5 | export class InMemoryEventBus implements EventBus { 6 | constructor( 7 | private readonly observers: Map[]> 8 | ) {} 9 | 10 | notify(event: T): void { 11 | const observers = this.observers.get(event.eventName()); 12 | 13 | if (observers) { 14 | observers.forEach((observer) => observer.update(event)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/service/Mailer.ts: -------------------------------------------------------------------------------- 1 | import { Email } from "./Email"; 2 | 3 | export class Mailer { 4 | send = (email: Email) => { 5 | console.log(email); 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/service/Observer.ts: -------------------------------------------------------------------------------- 1 | import { DomainEvent } from "./DomainEvent"; 2 | 3 | export interface Observer { 4 | update(event: T): void; 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/service/SendWelcomeEmailOnUserSignUp.ts: -------------------------------------------------------------------------------- 1 | import { Email } from "./Email"; 2 | import { Mailer } from "./Mailer"; 3 | import { Observer } from "./Observer"; 4 | import { UserSignUpDomainEvent } from "./UserSignUpDomainEvent"; 5 | 6 | export class SendWelcomeEmailOnUserSignUp 7 | implements Observer 8 | { 9 | constructor(private mailer: Mailer) {} 10 | 11 | update(event: UserSignUpDomainEvent): void { 12 | console.log("2 - Send welcome email"); 13 | const subject = "Welcome to ..."; 14 | const body = "Welcome email body"; 15 | this.mailer.send(new Email(event.emailAddress, subject, body)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/src/service/UserSignUpDomainEvent.ts: -------------------------------------------------------------------------------- 1 | import { DomainEvent } from "./DomainEvent"; 2 | 3 | export class UserSignUpDomainEvent extends DomainEvent { 4 | static EVENT_NAME = "user_sign_up"; 5 | 6 | constructor(public readonly emailAddress: string) { 7 | super(); 8 | } 9 | 10 | eventName(): string { 11 | return UserSignUpDomainEvent.EVENT_NAME; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/test/api.spec.ts: -------------------------------------------------------------------------------- 1 | import request from "supertest"; 2 | 3 | import app from "../src/app"; 4 | 5 | describe("GET /api/signup", () => { 6 | it("should return 201", () => { 7 | return request(app).get("/api/signup").expect(201); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/mediator/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "allowSyntheticDefaultImports": true, 6 | "target": "es6", 7 | "strict": true, 8 | "moduleResolution": "node", 9 | "sourceMap": true, 10 | "outDir": "dist", 11 | "resolveJsonModule": true 12 | }, 13 | "include": [ 14 | "src/**/*" 15 | ] 16 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/README.md: -------------------------------------------------------------------------------- 1 | Memento pattern applied to EventSourced system 2 | =============================================== 3 | 4 | An example using Memento pattern applied to EventSourced 5 | system. 6 | 7 | ## Languages 8 | 9 | - [TypeScript](typescript) 10 | 11 | ## Patterns used in this example 12 | 13 | - [Visitor](/design-patterns/behavioral/memento) 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: "@typescript-eslint/parser", 3 | extends: [ 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:prettier/recommended", 6 | ], 7 | plugins: ["simple-import-sort", "import"], 8 | parserOptions: { 9 | ecmaVersion: 12, 10 | sourceType: "module", 11 | }, 12 | rules: { 13 | "simple-import-sort/imports": "error", 14 | "simple-import-sort/exports": "error", 15 | "import/first": "error", 16 | "import/newline-after-import": "error", 17 | "import/no-duplicates": "error", 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testMatch: ["**/tests/**/*.test.ts"], 3 | transform: { 4 | "\\.ts$": "@swc/jest", 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/src/AggregateRoot.ts: -------------------------------------------------------------------------------- 1 | import { DomainEvent } from "./DomainEvent"; 2 | 3 | export class AggregateRoot { 4 | private recordedEvents: DomainEvent[] = []; 5 | 6 | record(domainEvent: DomainEvent): void { 7 | this.recordedEvents.push(domainEvent); 8 | } 9 | 10 | pullDomainEvents(): DomainEvent[] { 11 | const events = this.recordedEvents; 12 | this.recordedEvents = []; 13 | return events; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/src/CourseRepository.ts: -------------------------------------------------------------------------------- 1 | import { Course } from "./Course"; 2 | 3 | export interface CourseRepository { 4 | save(course: Course): void; 5 | 6 | find(id: string): Course; 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/src/CourseReview.ts: -------------------------------------------------------------------------------- 1 | import { Stars } from "./Stars"; 2 | 3 | export class CourseReview { 4 | constructor(public readonly stars: Stars) {} 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/src/CourseReviews.ts: -------------------------------------------------------------------------------- 1 | import { CourseReview } from "./CourseReview"; 2 | import { CourseReviewsSnapshot } from "./CourseReviewsSnapshot"; 3 | import { Stars } from "./Stars"; 4 | 5 | export class CourseReviews { 6 | constructor(private reviews: CourseReview[]) {} 7 | 8 | meanStars(): number { 9 | const totalStars = this.reviews 10 | .map((review) => review.stars.value) 11 | .reduce((stars: number, total: number) => stars + total, 0); 12 | 13 | const totalReviews = this.reviews.length; 14 | return totalStars / totalReviews; 15 | } 16 | 17 | add(stars: Stars) { 18 | this.reviews.push(new CourseReview(stars)); 19 | } 20 | 21 | createSnapshot(): CourseReviewsSnapshot { 22 | return { 23 | reviews: this.reviews.map((review) => { 24 | return { stars: review.stars.value }; 25 | }), 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/src/CourseReviewsSnapshot.ts: -------------------------------------------------------------------------------- 1 | export type CourseReviewSnapshot = { stars: number }; 2 | 3 | export type CourseReviewsSnapshot = { 4 | reviews: Array; 5 | }; 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/src/CourseSnapshot.ts: -------------------------------------------------------------------------------- 1 | import { CourseReviewsSnapshot } from "./CourseReviewsSnapshot"; 2 | 3 | export type CourseSnapshot = { 4 | id: string; 5 | reviews: CourseReviewsSnapshot; 6 | date: Date; 7 | }; 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/src/DomainEvent.ts: -------------------------------------------------------------------------------- 1 | export interface DomainEvent {} 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/src/ReviewAdded.ts: -------------------------------------------------------------------------------- 1 | export class ReviewAdded { 2 | constructor(public readonly id: string, public readonly stars: number) {} 3 | } 4 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/src/Stars.ts: -------------------------------------------------------------------------------- 1 | export class Stars { 2 | constructor(public readonly value: number) { 3 | if (value < 1 || value > 5) { 4 | throw new Error("Invalid stars value"); 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/tests/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["jest"], 3 | "env": { 4 | "jest/globals": true 5 | } 6 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/memento/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "experimentalDecorators": true 11 | }, 12 | "include": ["src/**/*.ts"], 13 | "exclude": ["node_modules"] 14 | } 15 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/README.md: -------------------------------------------------------------------------------- 1 | Observer pattern applied to a Backend use case 2 | ============================================== 3 | 4 | An example of the Observer pattern applied 5 | to a Backend use case, to decouple SignUp main 6 | use case from the derived use cases like SendWelcomeEmail. 7 | 8 | ## Description 9 | 10 | In this example we start with a single use case, in which all 11 | the application logic is executed. 12 | 13 | In this example we apply the Observer design pattern as an 14 | abstraction to split the SignUp main use case from the derived 15 | use cases: 16 | - CreateDefaultWorkspace 17 | - AssignUserToWorkspace 18 | - SendWelcomeEmail 19 | 20 | ## Languages 21 | 22 | - [typeScript](typescript) 23 | 24 | ## Patterns used in this example 25 | 26 | - [Observer](/design-patterns/behavioral/observer) 27 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: "@typescript-eslint/parser", 3 | extends: [ 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:prettier/recommended", 6 | ], 7 | plugins: ["simple-import-sort", "import"], 8 | parserOptions: { 9 | ecmaVersion: 12, 10 | sourceType: "module", 11 | }, 12 | rules: { 13 | "simple-import-sort/imports": "error", 14 | "simple-import-sort/exports": "error", 15 | "import/first": "error", 16 | "import/newline-after-import": "error", 17 | "import/no-duplicates": "error", 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | 3 | on: push 4 | 5 | jobs: 6 | lint: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | 12 | - name: Cache node modules 13 | uses: actions/cache@v2 14 | env: 15 | cache-name: cache-node-modules 16 | with: 17 | path: ~/.npm 18 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 19 | restore-keys: | 20 | ${{ runner.os }}-build-${{ env.cache-name }}- 21 | ${{ runner.os }}-build- 22 | ${{ runner.os }}- 23 | 24 | - name: Install Dependencies 25 | run: npm install 26 | 27 | - name: Lint 28 | run: npm run lint -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: push 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | 12 | - name: Cache node modules 13 | uses: actions/cache@v2 14 | env: 15 | cache-name: cache-node-modules 16 | with: 17 | path: ~/.npm 18 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 19 | restore-keys: | 20 | ${{ runner.os }}-build-${{ env.cache-name }}- 21 | ${{ runner.os }}-build- 22 | ${{ runner.os }}- 23 | 24 | - name: Install Dependencies 25 | run: npm install 26 | 27 | - name: Test 28 | run: npm run test -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | # API keys and secrets 2 | .env 3 | 4 | # Dependency directory 5 | node_modules 6 | 7 | # Ignore built ts files 8 | dist 9 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | globals: { 3 | "ts-jest": { 4 | tsconfig: "tsconfig.json", 5 | }, 6 | }, 7 | moduleFileExtensions: ["ts", "js"], 8 | transform: { 9 | "^.+\\.(ts|tsx)$": "ts-jest", 10 | }, 11 | testMatch: ["**/test/**/*.spec.(ts|js)"], 12 | testEnvironment: "node", 13 | }; 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/bash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/bash.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/ddd-en-php.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/ddd-en-php.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/ddd-java.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/ddd-java.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/layouts-css.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/layouts-css.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/makefiles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/makefiles.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/novedades-vue-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/novedades-vue-3.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/terminal-zsh.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/observer/typescript/public/courses/terminal-zsh.jpg -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/app.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import path from "path"; 3 | 4 | import { loadApiEndpoints } from "./controllers/api"; 5 | 6 | // Create Express server 7 | const app = express(); 8 | 9 | // Express configuration 10 | app.set("port", process.env.PORT || 3000); 11 | app.use(express.json()); 12 | app.use(express.urlencoded({ extended: true })); 13 | 14 | app.use( 15 | express.static(path.join(__dirname, "../public"), { maxAge: 31557600000 }) 16 | ); 17 | 18 | loadApiEndpoints(app); 19 | 20 | export default app; 21 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/entity/DefaultWorkspaceCreated.ts: -------------------------------------------------------------------------------- 1 | export class DefaultWorkspaceCreated { 2 | constructor( 3 | public readonly workspaceId: string, 4 | public readonly userId: string 5 | ) {} 6 | } 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/entity/Role.ts: -------------------------------------------------------------------------------- 1 | export enum Role { 2 | admin, 3 | editor, 4 | } 5 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/entity/User.ts: -------------------------------------------------------------------------------- 1 | export class User { 2 | constructor( 3 | public readonly id: string, 4 | public readonly name: string, 5 | public readonly emailAddress: string, 6 | public readonly password: string 7 | ) {} 8 | } 9 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/entity/UserRegistered.ts: -------------------------------------------------------------------------------- 1 | export class UserRegistered { 2 | constructor( 3 | public readonly id: string, 4 | public readonly name: string, 5 | public readonly emailAddress: string, 6 | public readonly password: string 7 | ) {} 8 | } 9 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/entity/UserRepository.ts: -------------------------------------------------------------------------------- 1 | import { User } from "./User"; 2 | 3 | export class UserRepository { 4 | save(user: User) { 5 | console.log(user); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/entity/Workspace.ts: -------------------------------------------------------------------------------- 1 | import { Role } from "./Role"; 2 | 3 | export class Workspace { 4 | constructor(public readonly id: string) {} 5 | 6 | static default(): Workspace { 7 | return new Workspace("fake random uuid"); 8 | } 9 | 10 | assignUser(user: string, role: Role): void { 11 | console.log(`User ${user} assigned to default workspace with role ${role}`); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/entity/WorkspaceRepository.ts: -------------------------------------------------------------------------------- 1 | import { Workspace } from "./Workspace"; 2 | 3 | export class WorkspaceRepository { 4 | save(workspace: Workspace) { 5 | console.log(workspace); 6 | } 7 | 8 | find(id: string) { 9 | return new Workspace(id); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/server.ts: -------------------------------------------------------------------------------- 1 | import app from "./app"; 2 | 3 | /** 4 | * Start Express server. 5 | */ 6 | const server = app.listen(app.get("port"), () => { 7 | console.log( 8 | " App is running at http://localhost:%d in %s mode", 9 | app.get("port"), 10 | app.get("env") 11 | ); 12 | console.log(" Press CTRL-C to stop\n"); 13 | }); 14 | 15 | export default server; 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/service/AssignUserToWorkspace.ts: -------------------------------------------------------------------------------- 1 | import { DefaultWorkspaceCreated } from "../entity/DefaultWorkspaceCreated"; 2 | import { Role } from "../entity/Role"; 3 | import { WorkspaceRepository } from "../entity/WorkspaceRepository"; 4 | import { Observer } from "./Observer"; 5 | 6 | export class AssignUserToWorkspace 7 | implements Observer 8 | { 9 | constructor(private readonly workspaceRepository: WorkspaceRepository) {} 10 | 11 | update(event: DefaultWorkspaceCreated): void { 12 | console.log("4 - Assign user to workspace"); 13 | const workspace = this.workspaceRepository.find(event.workspaceId); 14 | workspace.assignUser(event.userId, Role.admin); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/service/Email.ts: -------------------------------------------------------------------------------- 1 | export class Email { 2 | constructor( 3 | private readonly to: string, 4 | private readonly subject: string, 5 | private readonly body: string 6 | ) {} 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/service/Mailer.ts: -------------------------------------------------------------------------------- 1 | import { Email } from "./Email"; 2 | 3 | export class Mailer { 4 | send = (email: Email) => { 5 | console.log(email); 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/service/Observable.ts: -------------------------------------------------------------------------------- 1 | import { Observer } from "./Observer"; 2 | 3 | export abstract class Observable { 4 | private observers: Observer[] = []; 5 | 6 | addObserver(observer: Observer): void { 7 | this.observers.push(observer); 8 | } 9 | 10 | async notify(event: T): Promise { 11 | this.observers.forEach((observer) => observer.update(event)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/service/Observer.ts: -------------------------------------------------------------------------------- 1 | export interface Observer { 2 | update(event: T): void; 3 | } 4 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/src/service/SendWelcomeEmail.ts: -------------------------------------------------------------------------------- 1 | import { UserRegistered } from "../entity/UserRegistered"; 2 | import { Email } from "./Email"; 3 | import { Mailer } from "./Mailer"; 4 | import { Observer } from "./Observer"; 5 | 6 | export class SendWelcomeEmail implements Observer { 7 | constructor(private readonly mailer: Mailer) {} 8 | 9 | async update(event: UserRegistered): Promise { 10 | console.log("2 - Send welcome email"); 11 | const subject = "Welcome to ..."; 12 | const body = "Welcome email body"; 13 | this.mailer.send(new Email(event.emailAddress, subject, body)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/test/api.spec.ts: -------------------------------------------------------------------------------- 1 | import request from "supertest"; 2 | 3 | import app from "../src/app"; 4 | 5 | describe("GET /api/signup", () => { 6 | it("should return 201", () => { 7 | return request(app).get("/api/signup").expect(201); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/observer/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "allowSyntheticDefaultImports": true, 6 | "target": "es6", 7 | "strict": true, 8 | "moduleResolution": "node", 9 | "sourceMap": true, 10 | "outDir": "dist", 11 | "resolveJsonModule": true 12 | }, 13 | "include": [ 14 | "src/**/*" 15 | ] 16 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.php] 13 | indent_size = 4 14 | indent_style = space 15 | 16 | [*.md] 17 | trim_trailing_whitespace = false 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://bit.ly/CodelyTvPro 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | os: [ubuntu-latest, windows-latest, macOS-latest] 15 | php-versions: ['7.4', '8.0'] 16 | 17 | name: Test on ${{ matrix.os }} with PHP ${{ matrix.php-versions }} 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | 22 | - name: Setup PHP 23 | uses: shivammathur/setup-php@v1 24 | with: 25 | php-version: ${{ matrix.php-versions }} 26 | coverage: none 27 | 28 | - name: Install dependencies 29 | run: composer install --ignore-platform-reqs 30 | 31 | - name: Run the tests 32 | run: composer phpunit 33 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | .phpunit.result.cache 3 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | build: 2 | environment: 3 | php: 4 | version: '7.2' 5 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/.semver: -------------------------------------------------------------------------------- 1 | --- 2 | :major: 1 3 | :minor: 2 4 | :patch: 1 5 | :special: '' 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/phpunit.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | tests 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/src/ArchiveCourse.php: -------------------------------------------------------------------------------- 1 | status = CourseStatus::archived(); 19 | } 20 | 21 | /** @throws Exception */ 22 | public function publish(): PublishedCourse 23 | { 24 | throw new Exception('Invalid operation'); 25 | } 26 | 27 | public function archive(): ArchiveCourse 28 | { 29 | return $this; 30 | } 31 | 32 | protected function ensureCanRename(CourseName $newName): void 33 | { 34 | throw new Exception('Invalid operation'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/src/CourseDuration.php: -------------------------------------------------------------------------------- 1 | errorMessage()); 14 | } 15 | 16 | abstract public function errorCode(): string; 17 | 18 | abstract protected function errorMessage(): string; 19 | } 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/state/php/src/StringValueObject.php: -------------------------------------------------------------------------------- 1 | value; 16 | } 17 | 18 | public function __toString(): string 19 | { 20 | return $this->value(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/achivements-functional/ts/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: "@typescript-eslint/parser", 3 | extends: [ 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:prettier/recommended", 6 | ], 7 | plugins: ["simple-import-sort", "import"], 8 | parserOptions: { 9 | ecmaVersion: 12, 10 | sourceType: "module", 11 | }, 12 | rules: { 13 | "simple-import-sort/imports": "error", 14 | "simple-import-sort/exports": "error", 15 | "import/first": "error", 16 | "import/newline-after-import": "error", 17 | "import/no-duplicates": "error", 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/achivements-functional/ts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/achivements-functional/ts/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testMatch: ["**/tests/**/*.test.ts"], 3 | transform: { 4 | "\\.ts$": "@swc/jest", 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/achivements-functional/ts/tests/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["jest"], 3 | "env": { 4 | "jest/globals": true 5 | } 6 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/achivements-functional/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "experimentalDecorators": true 11 | }, 12 | "include": ["src/**/*.ts"], 13 | "exclude": ["node_modules"] 14 | } 15 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: Kotlin basic skeleton CI 5 | 6 | on: 7 | push: 8 | branches: [ main ] 9 | pull_request: 10 | branches: [ main ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up JDK 11 20 | uses: actions/setup-java@v2 21 | with: 22 | java-version: '11' 23 | distribution: 'adopt' 24 | - name: Grant execute permission for gradlew 25 | run: chmod +x gradlew 26 | - name: Build with Gradle 27 | run: ./gradlew build 28 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | 8 | ### IntelliJ IDEA ### 9 | .idea 10 | *.iws 11 | *.iml 12 | *.ipr 13 | out/ 14 | !**/src/main/**/out/ 15 | !**/src/test/**/out/ 16 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | org.gradle.parallel=true 3 | org.gradle.caching=true 4 | org.gradle.daemon=true 5 | org.gradle.jvmargs=-Xmx1536M 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/courses-examples/behavioral-design-patterns-course/strategy/kotlin/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-basic-skeleton" 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/AchievementDealer.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | import java.util.* 4 | 5 | abstract class AchievementDealer(private val learnerAchievements: LearnerAchievementRepository) { 6 | abstract fun dealAchievements(learnerId: String, earnedPoints: LearnerEarnedPoints) 7 | 8 | protected fun dealAchievement(learnerId: String, type: AchievementType) { 9 | val achievement = LearnerAchievement( 10 | "id", 11 | learnerId, 12 | type, 13 | Date() 14 | ) 15 | learnerAchievements.save(achievement) 16 | println(type.description()) 17 | } 18 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/AchievementType.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | enum class AchievementType { 4 | PointsEarned100 { 5 | override fun description() = "100 Points earned" 6 | }, 7 | PointsEarned500 { 8 | override fun description() = "500 Points earned" 9 | }, 10 | PointsEarned2500 { 11 | override fun description() = "2500 Points earned" 12 | }, 13 | FrontendGuru { 14 | override fun description() = "Front-end guru" 15 | }, 16 | BackendGuru { 17 | override fun description() = "Back-end guru" 18 | }, 19 | FullStackGuru { 20 | override fun description() = "FullStack guru" 21 | }; 22 | 23 | abstract fun description(): String 24 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/ConstantLearnerRepository.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | class ConstantLearnerRepository(private val learner: Learner) : LearnerRepository { 4 | override fun find(learnerId: String): Learner { 5 | return learner 6 | } 7 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/DummyStepRepository.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | class DummyStepRepository : StepRepository { 4 | override fun find(stepId: String): Step { 5 | return Step(stepId, 100) 6 | } 7 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/EarnedPoints.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | data class EarnedPoints(val value: Int) { 4 | operator fun compareTo(other: EarnedPoints): Int { 5 | if (value == other.value) { 6 | return 0 7 | } 8 | 9 | return if (value > other.value) 1 else -1 10 | } 11 | 12 | operator fun plus(other: EarnedPoints): EarnedPoints { 13 | return EarnedPoints(value + other.value) 14 | } 15 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/InMemoryLearnerAchievementRepository.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | class InMemoryLearnerAchievementRepository : LearnerAchievementRepository { 4 | 5 | private val achievements: MutableList = mutableListOf() 6 | 7 | override fun save(learnerAchievement: LearnerAchievement) { 8 | achievements.add(learnerAchievement) 9 | } 10 | 11 | fun has(learnerId: String, achievementType: AchievementType): Boolean { 12 | val achievement = achievements.find { achievement -> achievement.learnerId == learnerId && achievement.type == achievementType } 13 | return achievement != null 14 | } 15 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/Learner.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | data class Learner(val learnerId: String, val earnedPoints: LearnerEarnedPoints) 4 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/LearnerAchievement.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | import java.util.Date 4 | 5 | data class LearnerAchievement( 6 | val id: String, 7 | val learnerId: String, 8 | val type: AchievementType, 9 | val wonOn: Date 10 | ) -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/LearnerAchievementDealer.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | import com.codely.achievement.factories.AchievementDealerFactory 4 | 5 | class LearnerAchievementDealer ( 6 | learnerAchievements: LearnerAchievementRepository, 7 | private val dealersFactory: AchievementDealerFactory 8 | ) : AchievementDealer(learnerAchievements) { 9 | override fun dealAchievements(learnerId: String, earnedPoints: LearnerEarnedPoints) { 10 | dealersFactory 11 | .build() 12 | .forEach { dealer -> dealer.dealAchievements(learnerId, earnedPoints) } 13 | } 14 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/LearnerAchievementRepository.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | interface LearnerAchievementRepository { 4 | fun save(learnerAchievement: LearnerAchievement) 5 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/LearnerEarnedPoints.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | data class LearnerEarnedPoints( 4 | val frontend: EarnedPoints, 5 | val backend: EarnedPoints 6 | ) { 7 | val total: EarnedPoints = frontend + backend 8 | } 9 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/LearnerRepository.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | interface LearnerRepository { 4 | fun find(learnerId: String): Learner 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/LearnerStep.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | import java.util.Date 4 | 5 | data class LearnerStep( 6 | val learnerId: String, 7 | val stepId: String, 8 | val earnedPoints: EarnedPoints, 9 | val completedOn: Date 10 | ) -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/LearnerStepRepository.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | interface LearnerStepRepository { 4 | fun save(learnerStep: LearnerStep) 5 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/Step.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | data class Step(val id: String, val totalPoints: Int) 4 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/StepCompleter.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | import java.util.Date 4 | 5 | class StepCompleter( 6 | private val learners: LearnerRepository, 7 | private val steps: StepRepository, 8 | private val learnerSteps: LearnerStepRepository, 9 | private val learnerAchievementDealer: AchievementDealer 10 | ) { 11 | 12 | fun completeStep(stepId: String, learnerId: String) { 13 | val step = steps.find(stepId) 14 | val learner = learners.find(learnerId) 15 | 16 | val learnerStep = LearnerStep( 17 | stepId, 18 | learnerId, 19 | EarnedPoints(step.totalPoints), 20 | Date()) 21 | learnerSteps.save(learnerStep) 22 | 23 | learnerAchievementDealer.dealAchievements(learnerId, learner.earnedPoints) 24 | } 25 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/StepRepository.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | interface StepRepository { 4 | fun find(stepId: String): Step 5 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/VoidLearnerStepsRepository.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement 2 | 3 | class VoidLearnerStepsRepository : LearnerStepRepository { 4 | override fun save(learnerStep: LearnerStep) { 5 | } 6 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/achievements/BackendGuru.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement.achievements 2 | 3 | import com.codely.achievement.* 4 | 5 | class BackendGuru(learnerAchievements: LearnerAchievementRepository) : AchievementDealer(learnerAchievements) { 6 | override fun dealAchievements(learnerId: String, earnedPoints: LearnerEarnedPoints) { 7 | if (earnedPoints.backend >= EarnedPoints(2000)) { 8 | dealAchievement(learnerId, AchievementType.BackendGuru) 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/achievements/FrontendGuru.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement.achievements 2 | 3 | import com.codely.achievement.* 4 | 5 | class FrontendGuru(learnerAchievements: LearnerAchievementRepository) : AchievementDealer(learnerAchievements) { 6 | override fun dealAchievements(learnerId: String, earnedPoints: LearnerEarnedPoints) { 7 | if (earnedPoints.frontend >= EarnedPoints(2000)) { 8 | dealAchievement(learnerId, AchievementType.FrontendGuru) 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/achievements/FullStackGuru.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement.achievements 2 | 3 | import com.codely.achievement.* 4 | 5 | class FullStackGuru(learnerAchievements: LearnerAchievementRepository) : AchievementDealer(learnerAchievements) { 6 | override fun dealAchievements(learnerId: String, earnedPoints: LearnerEarnedPoints) { 7 | if (earnedPoints.frontend >= EarnedPoints(1500) && 8 | earnedPoints.backend >= EarnedPoints(1750) 9 | ) { 10 | dealAchievement(learnerId, AchievementType.FullStackGuru) 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/achievements/PointsEarned100.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement.achievements 2 | 3 | import com.codely.achievement.* 4 | 5 | class PointsEarned100(learnerAchievements: LearnerAchievementRepository) : AchievementDealer(learnerAchievements) { 6 | override fun dealAchievements(learnerId: String, earnedPoints: LearnerEarnedPoints) { 7 | if (earnedPoints.total >= EarnedPoints(100)) { 8 | dealAchievement(learnerId, AchievementType.PointsEarned100) 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/achievements/PointsEarned2500.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement.achievements 2 | 3 | import com.codely.achievement.* 4 | 5 | class PointsEarned2500(learnerAchievements: LearnerAchievementRepository) : AchievementDealer(learnerAchievements) { 6 | override fun dealAchievements(learnerId: String, earnedPoints: LearnerEarnedPoints) { 7 | if (earnedPoints.total >= EarnedPoints(2500)) { 8 | dealAchievement(learnerId, AchievementType.PointsEarned2500) 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/achievements/PointsEarned500.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement.achievements 2 | 3 | import com.codely.achievement.* 4 | 5 | class PointsEarned500(learnerAchievements: LearnerAchievementRepository) : AchievementDealer(learnerAchievements) { 6 | override fun dealAchievements(learnerId: String, earnedPoints: LearnerEarnedPoints) { 7 | if (earnedPoints.total >= EarnedPoints(500)) { 8 | dealAchievement(learnerId, AchievementType.PointsEarned500) 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/factories/AchievementDealerFactory.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement.factories 2 | 3 | import com.codely.achievement.AchievementDealer 4 | 5 | interface AchievementDealerFactory { 6 | fun build(): List 7 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/strategy/kotlin/src/main/kotlin/com/codely/achievement/factories/LearnerAchievementDealerFactory.kt: -------------------------------------------------------------------------------- 1 | package com.codely.achievement.factories 2 | 3 | import com.codely.achievement.AchievementDealer 4 | import com.codely.achievement.LearnerAchievementRepository 5 | import com.codely.achievement.achievements.* 6 | 7 | class LearnerAchievementDealerFactory( 8 | private val learnerAchievements: LearnerAchievementRepository 9 | ) : AchievementDealerFactory { 10 | override fun build(): List { 11 | return listOf( 12 | PointsEarned100(learnerAchievements), 13 | PointsEarned500(learnerAchievements), 14 | PointsEarned2500(learnerAchievements), 15 | FrontendGuru(learnerAchievements), 16 | BackendGuru(learnerAchievements), 17 | FullStackGuru(learnerAchievements) 18 | ) 19 | } 20 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/README.md: -------------------------------------------------------------------------------- 1 | Visitor pattern example 2 | ======================= 3 | 4 | An example using Visitor design pattern. 5 | 6 | ## Languages 7 | 8 | - [TypeScript](typescript) 9 | 10 | ## Patterns used in this example 11 | 12 | - [Visitor](/design-patterns/behavioral/visitor) 13 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: "@typescript-eslint/parser", 3 | extends: [ 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:prettier/recommended", 6 | ], 7 | plugins: ["simple-import-sort", "import"], 8 | parserOptions: { 9 | ecmaVersion: 12, 10 | sourceType: "module", 11 | }, 12 | rules: { 13 | "simple-import-sort/imports": "error", 14 | "simple-import-sort/exports": "error", 15 | "import/first": "error", 16 | "import/newline-after-import": "error", 17 | "import/no-duplicates": "error", 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testMatch: ["**/tests/**/*.test.ts"], 3 | transform: { 4 | "\\.ts$": "@swc/jest", 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/src/ElementA.ts: -------------------------------------------------------------------------------- 1 | import { VisitingElement } from "./VisitingElement"; 2 | import { Visitor } from "./Visitor"; 3 | 4 | export class ElementA implements VisitingElement { 5 | constructor(public readonly name: string) {} 6 | 7 | accept(visitor: Visitor) { 8 | visitor.visitElementA(this); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/src/ElementB.ts: -------------------------------------------------------------------------------- 1 | import { VisitingElement } from "./VisitingElement"; 2 | import { Visitor } from "./Visitor"; 3 | 4 | export class ElementB implements VisitingElement { 5 | constructor(public readonly title: string) {} 6 | 7 | accept(visitor: Visitor) { 8 | visitor.visitElementB(this); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/src/ExportVisitor.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | 3 | import { ElementA } from "./ElementA"; 4 | import { ElementB } from "./ElementB"; 5 | import { Visitor } from "./Visitor"; 6 | 7 | export class ExportVisitor implements Visitor { 8 | private readonly _path = "test.txt"; 9 | 10 | visitElementA(element: ElementA): void { 11 | fs.writeFileSync(this._path, element.name, { flag: "a" }); 12 | } 13 | 14 | visitElementB(element: ElementB): void { 15 | fs.writeFileSync(this._path, element.title, { flag: "a" }); 16 | } 17 | 18 | readFile(): string { 19 | return fs.readFileSync(this._path, { flag: "r" }).toString(); 20 | } 21 | 22 | removeFile(): void { 23 | fs.unlinkSync(this._path); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/src/PrintVisitor.ts: -------------------------------------------------------------------------------- 1 | import { ElementA } from "./ElementA"; 2 | import { ElementB } from "./ElementB"; 3 | import { Visitor } from "./Visitor"; 4 | 5 | export class PrintVisitor implements Visitor { 6 | visitElementA(element: ElementA): void { 7 | console.log(element.name); 8 | } 9 | 10 | visitElementB(element: ElementB): void { 11 | console.log(element.title); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/src/ValidatorVisitor.ts: -------------------------------------------------------------------------------- 1 | import { ElementA } from "./ElementA"; 2 | import { ElementB } from "./ElementB"; 3 | import { Visitor } from "./Visitor"; 4 | 5 | export class ValidatorVisitor implements Visitor { 6 | visitElementA(element: ElementA): void { 7 | if (element.name.length === 0) { 8 | throw new Error("ElementA name can't be empty"); 9 | } 10 | } 11 | 12 | visitElementB(element: ElementB): void { 13 | if (element.title.length > 5) { 14 | throw new Error("ElementB title is too long"); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/src/VisitingElement.ts: -------------------------------------------------------------------------------- 1 | import { Visitor } from "./Visitor"; 2 | 3 | export interface VisitingElement { 4 | accept(visitor: Visitor): void; 5 | } 6 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/src/Visitor.ts: -------------------------------------------------------------------------------- 1 | import { ElementA } from "./ElementA"; 2 | import { ElementB } from "./ElementB"; 3 | 4 | export interface Visitor { 5 | visitElementA(element: ElementA): void; 6 | visitElementB(element: ElementB): void; 7 | } 8 | -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/tests/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["jest"], 3 | "env": { 4 | "jest/globals": true 5 | } 6 | } -------------------------------------------------------------------------------- /courses-examples/behavioral-design-patterns-course/visitor/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "experimentalDecorators": true 11 | }, 12 | "include": ["src/**/*.ts"], 13 | "exclude": ["node_modules"] 14 | } 15 | -------------------------------------------------------------------------------- /design-patterns/behavioral/chain-of-responsibility/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/chain-of-responsibility/.gitkeep -------------------------------------------------------------------------------- /design-patterns/behavioral/command/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/command/.gitkeep -------------------------------------------------------------------------------- /design-patterns/behavioral/iterator/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/iterator/.gitkeep -------------------------------------------------------------------------------- /design-patterns/behavioral/mediator/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/mediator/.gitkeep -------------------------------------------------------------------------------- /design-patterns/behavioral/memento/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/memento/.gitkeep -------------------------------------------------------------------------------- /design-patterns/behavioral/observer/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/observer/.gitkeep -------------------------------------------------------------------------------- /design-patterns/behavioral/state/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/state/.gitkeep -------------------------------------------------------------------------------- /design-patterns/behavioral/strategy/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/strategy/.gitkeep -------------------------------------------------------------------------------- /design-patterns/behavioral/template-method/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/template-method/.gitkeep -------------------------------------------------------------------------------- /design-patterns/behavioral/visitor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/behavioral/visitor/.gitkeep -------------------------------------------------------------------------------- /design-patterns/creational/abstract-factory/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/creational/abstract-factory/.gitkeep -------------------------------------------------------------------------------- /design-patterns/creational/builder/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/creational/builder/.gitkeep -------------------------------------------------------------------------------- /design-patterns/creational/factory-method/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/creational/factory-method/.gitkeep -------------------------------------------------------------------------------- /design-patterns/creational/prototype/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/creational/prototype/.gitkeep -------------------------------------------------------------------------------- /design-patterns/creational/singleton/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/creational/singleton/.gitkeep -------------------------------------------------------------------------------- /design-patterns/structural/adapter/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/structural/adapter/.gitkeep -------------------------------------------------------------------------------- /design-patterns/structural/bridge/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/structural/bridge/.gitkeep -------------------------------------------------------------------------------- /design-patterns/structural/composite/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/structural/composite/.gitkeep -------------------------------------------------------------------------------- /design-patterns/structural/decorator/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/structural/decorator/.gitkeep -------------------------------------------------------------------------------- /design-patterns/structural/facade/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/structural/facade/.gitkeep -------------------------------------------------------------------------------- /design-patterns/structural/flyweight/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/structural/flyweight/.gitkeep -------------------------------------------------------------------------------- /design-patterns/structural/proxy/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/design-patterns/structural/proxy/.gitkeep -------------------------------------------------------------------------------- /exercises/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodelyTV/design-patterns/45c671d989a8d49dc219eae4b9a820fb704d00cc/exercises/.gitkeep -------------------------------------------------------------------------------- /node_modules/.package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "design-patterns", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /node_modules/.yarn-integrity: -------------------------------------------------------------------------------- 1 | { 2 | "systemParams": "darwin-arm64-108", 3 | "modulesFolders": [], 4 | "flags": [], 5 | "linkedModules": [], 6 | "topLevelPatterns": [], 7 | "lockfileEntries": {}, 8 | "files": [], 9 | "artifacts": {} 10 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "design-patterns", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | --------------------------------------------------------------------------------