{"id":32868552,"url":"https://github.com/ercansormaz/template-method-pattern","last_synced_at":"2026-04-30T12:33:15.908Z","repository":{"id":319669693,"uuid":"1079265191","full_name":"ercansormaz/template-method-pattern","owner":"ercansormaz","description":"Spring Boot project demonstrating the Template Method Pattern","archived":false,"fork":false,"pushed_at":"2026-01-31T10:24:23.000Z","size":10,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-30T12:33:09.088Z","etag":null,"topics":["design-patterns","spring","spring-boot","template-method-design-pattern","template-method-pattern"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ercansormaz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-19T13:12:55.000Z","updated_at":"2026-01-31T10:24:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"ae493acd-e2bf-4f8b-a588-297619448eb0","html_url":"https://github.com/ercansormaz/template-method-pattern","commit_stats":null,"previous_names":["ercansormaz/template-method-pattern"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ercansormaz/template-method-pattern","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ercansormaz%2Ftemplate-method-pattern","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ercansormaz%2Ftemplate-method-pattern/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ercansormaz%2Ftemplate-method-pattern/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ercansormaz%2Ftemplate-method-pattern/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ercansormaz","download_url":"https://codeload.github.com/ercansormaz/template-method-pattern/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ercansormaz%2Ftemplate-method-pattern/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32465009,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T22:27:22.272Z","status":"online","status_checked_at":"2026-04-30T02:00:05.929Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["design-patterns","spring","spring-boot","template-method-design-pattern","template-method-pattern"],"created_at":"2025-11-09T08:01:28.677Z","updated_at":"2026-04-30T12:33:15.900Z","avatar_url":"https://github.com/ercansormaz.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring Boot Template Method Pattern Example: Email Template API\n\nThis project demonstrates the use of the **Template Method Pattern** in a **Spring Boot** application. \nIt provides an API to build email content dynamically based on a given category and body. \nThe project illustrates how **fixing the algorithm structure in an abstract class while allowing subclasses to customize certain steps** can be implemented in a real-world scenario using Spring DI.\n\n---\n\n## 📌 Overview\n\nThe system generates emails in the following structure:\n\n```bash\nHeader\nBody (from request)\nFooter\n```\n\nDifferent **email categories** (family, work, friend) have their own **header** and **footer**, while the **algorithm to build the email remains consistent**.\n\n- The **Template Method Pattern** ensures that:\n- The skeleton of the algorithm is defined once in an abstract class.\n- Subclasses override only the variable parts (header/footer).\n- The core algorithm (`buildEmail`) is **final**, preventing subclasses from altering the concatenation logic.\n\n---\n\n## 📂 Project Structure\n```bash\ndev.ercan.poc.template\n│\n├─ controller\n│   └─ EmailController.java         # Handles HTTP requests\n│\n├─ service\n│   └─ EmailService.java            # Business logic, selects template based on category\n│\n├─ template\n│   ├─ EmailTemplate.java           # Abstract class with final template method\n│   ├─ FamilyEmailTemplate.java     # Concrete implementation for family emails\n│   ├─ WorkEmailTemplate.java       # Concrete implementation for work emails\n│   └─ FriendEmailTemplate.java     # Concrete implementation for friend emails\n```\n\n**Key Points:**\n- `EmailTemplate` (**abstract class**) defines the **final template method** `buildEmail(String body)`.\n  - ✅ This ensures the algorithm skeleton is **fixed** and cannot be overridden by subclasses.\n- Concrete classes (`FamilyEmailTemplate`, `WorkEmailTemplate`, `FriendEmailTemplate`) implement only the **variable parts**: `getHeader()` and `getFooter()`.\n- `EmailService` uses **Spring DI** to inject all template components as a `Map\u003cString, EmailTemplate\u003e` and selects the appropriate template at runtime.\n- `EmailController` handles requests and delegates email building to the service.\n\n---\n\n## 🚀 API Usage\n\n**Endpoint:** `POST /email/build`\n\n**Request Body:**\n```json\n{\n  \"category\": \"work\",\n  \"body\": \"Test email body\"\n}\n```\n\n**Example cURL:**\n```bash\ncurl --location 'http://localhost:8080/email/build' \\\n--header 'Content-Type: application/json' \\\n--data '{\n  \"category\": \"work\",\n  \"body\": \"Test email body\"\n}'\n```\n\n**Response:**\n```json\n{\n  \"content\": \"Dear Colleague,\\n\\nTest email body\\n\\nBest regards, Your Company\"\n}\n```\n\n---\n\n## 🛠 How Template Method Pattern is Used\n\n**1. Algorithm Skeleton in Abstract Class**\n\n`EmailTemplate` defines the **final template method** `buildEmail(String body)`, which orchestrates email creation: concatenating header, body, and footer.\n\n**2. Concrete Variations**\n\nEach category (`FamilyEmailTemplate`, `WorkEmailTemplate`, `FriendEmailTemplate`) implements the variable steps (`getHeader()` and `getFooter()`) **without changing the core algorithm**.\n\n**3. Spring Integration**\n\nSpring automatically injects all concrete templates into `EmailService` as a `Map\u003cString, EmailTemplate\u003e`. The service selects the correct template at runtime based on the category.\n\n**4. Separation of Concerns**\n- Controller → HTTP request/response\n- Service → Business logic (select template, build email)\n- Templates → Category-specific formatting\n\nThis demonstrates the key principle of the Template Method Pattern: **fixing the algorithm structure while letting subclasses override specific steps**.\n\n---\n\n## 🌟 Benefits\n- Clear separation between **algorithm structure** and **customizable parts**.\n- Easy to **extend**: adding a new email category only requires a new concrete template class.\n- **Spring DI** simplifies component management and promotes cleaner architecture.\n- Ensures **algorithm consistency** by marking the template method as `final`.\n\n---\n\n## 📌 Example Categories\n\n| Category | Header          | Footer                     |\n|:---------|:----------------|:---------------------------|\n| family   | Dear Family,    | Love, Your Family App      |\n| work     | Dear Colleague, | Best regards, Your Company |\n| friend   | Hey Friend!     | Cheers, Your Buddy App     |\n\n---\n\n## 🛠️ How to Run\n#### 1. Clone this repository:\n```bash\ngit clone https://github.com/ercansormaz/template-method-pattern.git\n```\n\n#### 2. Navigate to the project folder and build:\n```bash\nmvn clean install\n```\n\n#### 3. Run the application:\n```bash\nmvn spring-boot:run\n```\n\n#### 4. Access the APIs at:\n```bash\nhttp://localhost:8080/email/build\n```\n\n---\n\n## 📚 Further Reading\nYou can read a detailed explanation of this project and the Template Method Pattern in the blog post here:  \n👉 [Read the Blog Post](https://ercan.dev/blog/notes/spring-boot-template-method-pattern-example)\n\n---\n\n## 🤝 Contributing\nContributions are welcome! Feel free to fork the repo, submit pull requests or open issues.\n\n---\n\n## 📜 License\nThis project is licensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fercansormaz%2Ftemplate-method-pattern","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fercansormaz%2Ftemplate-method-pattern","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fercansormaz%2Ftemplate-method-pattern/lists"}