{"id":50840063,"url":"https://github.com/vimalyad/pen","last_synced_at":"2026-06-14T06:06:36.161Z","repository":{"id":346552236,"uuid":"1189569450","full_name":"vimalyad/pen","owner":"vimalyad","description":null,"archived":false,"fork":false,"pushed_at":"2026-03-24T10:41:41.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-25T13:16:53.583Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vimalyad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2026-03-23T13:03:59.000Z","updated_at":"2026-03-24T10:41:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vimalyad/pen","commit_stats":null,"previous_names":["vimalyad/pen"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/vimalyad/pen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vimalyad%2Fpen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vimalyad%2Fpen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vimalyad%2Fpen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vimalyad%2Fpen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vimalyad","download_url":"https://codeload.github.com/vimalyad/pen/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vimalyad%2Fpen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34310812,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"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":[],"created_at":"2026-06-14T06:06:35.460Z","updated_at":"2026-06-14T06:06:36.149Z","avatar_url":"https://github.com/vimalyad.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🖊️ Pen LLD — Low Level Design\n\nA clean, extensible Java implementation of a Pen system demonstrating key OOP and SOLID principles.\n\n---\n\n## 📦 Package Structure\n\n```\npen/src/\n├── inksource/\n│   ├── InkSource.java         ← Interface (common abstraction)\n│   ├── Refill.java            ← Abstract class for cartridge-based refills\n│   ├── BallPenRefill.java\n│   ├── GelPenRefill.java\n│   └── InkReservoir.java      ← Direct InkSource impl (not a Refill)\n├── mechanism/\n│   ├── Mechanism.java         ← Interface\n│   ├── ClickMechanism.java\n│   └── CapMechanism.java\n├── pen/\n│   ├── Pen.java               ← Abstract class (Template Method)\n│   ├── BallPen.java\n│   ├── GelPen.java\n│   └── InkPen.java\n├── factory/\n│   └── PenFactory.java        ← Factory with Supplier + BiFunction\n└── Main.java\n```\n\n---\n\n## 🗂️ UML Class Diagram\n\n```mermaid\nclassDiagram\n\n    %% ─── InkSource hierarchy ───────────────────────────────\n    class InkSource {\n        \u003c\u003cinterface\u003e\u003e\n        +getColor() String\n        +hasInk() boolean\n        +write() void\n    }\n\n    class Refill {\n        \u003c\u003cabstract\u003e\u003e\n        #color : String\n        #inkLevel : int\n        +getColor() String\n        +hasInk() boolean\n        +write() void\n    }\n\n    class BallPenRefill {\n        +BallPenRefill(color)\n    }\n\n    class GelPenRefill {\n        +GelPenRefill(color)\n    }\n\n    class InkReservoir {\n        -color : String\n        -inkLevel : int\n        +getColor() String\n        +hasInk() boolean\n        +write() void\n        +refillInk(color) void\n    }\n\n    InkSource       \u003c|..    Refill\n    InkSource       \u003c|..    InkReservoir\n    Refill          \u003c|--    BallPenRefill\n    Refill          \u003c|--    GelPenRefill\n\n\n    %% ─── Mechanism hierarchy ────────────────────────────────\n    class Mechanism {\n        \u003c\u003cinterface\u003e\u003e\n        +open() void\n        +close() void\n        +isOpen() boolean\n    }\n\n    class ClickMechanism {\n        -open : boolean\n        +open() void\n        +close() void\n        +isOpen() boolean\n    }\n\n    class CapMechanism {\n        -open : boolean\n        +open() void\n        +close() void\n        +isOpen() boolean\n    }\n\n    Mechanism       \u003c|..    ClickMechanism\n    Mechanism       \u003c|..    CapMechanism\n\n\n    %% ─── Pen hierarchy ──────────────────────────────────────\n    class Pen {\n        \u003c\u003cabstract\u003e\u003e\n        #inkSource : InkSource\n        #mechanism : Mechanism\n        +write(text) void\n        +getColor() String\n        +open() void\n        +close() void\n        +changeInkSource(color) void*\n    }\n\n    class BallPen {\n        +BallPen(BallPenRefill, Mechanism)\n        +changeInkSource(color) void\n    }\n\n    class GelPen {\n        +GelPen(GelPenRefill, Mechanism)\n        +changeInkSource(color) void\n    }\n\n    class InkPen {\n        +InkPen(InkReservoir, Mechanism)\n        +changeInkSource(color) void\n    }\n\n    Pen             \u003c|--    BallPen\n    Pen             \u003c|--    GelPen\n    Pen             \u003c|--    InkPen\n\n    Pen             o--\u003e    InkSource   : inkSource\n    Pen             o--\u003e    Mechanism   : mechanism\n\n    BallPen         ..\u003e     BallPenRefill   : creates\n    GelPen          ..\u003e     GelPenRefill    : creates\n    InkPen          ..\u003e     InkReservoir    : creates\n\n\n    %% ─── Factory ─────────────────────────────────────────────\n    class PenFactory {\n        \u003c\u003cutility\u003e\u003e\n        -mechanismMap : Map~String, Supplier~Mechanism~~\n        -penCreatorMap : Map~String, BiFunction~String,Mechanism,Pen~~\n        +createPen(penType, color, mechanismType) Pen$\n    }\n\n    PenFactory      ..\u003e     Pen             : produces\n    PenFactory      ..\u003e     Mechanism       : produces\n```\n\n---\n\n## 🎯 Design Patterns Used\n\n| Pattern             | Where                 | Why                                                           |\n|---------------------|-----------------------|---------------------------------------------------------------|\n| **Template Method** | `Pen.write(text)`     | Same write flow for all pens; only `changeInkSource()` varies |\n| **Strategy**        | `Mechanism` interface | ClickMechanism / CapMechanism are interchangeable behaviors   |\n| **Factory**         | `PenFactory`          | Centralized creation; client never calls `new` directly       |\n\n---\n\n## 🔑 Key Design Decisions\n\n### 1. `InkSource` as a unified abstraction\n\nInstead of forcing `InkPen` to use a `Refill`, an `InkSource` interface acts as the common contract. `Refill` and\n`InkReservoir` are separate implementations — one replaceable, one refillable in place.\n\n```\nInkSource (interface)\n    ├── Refill (abstract)          → BallPenRefill, GelPenRefill\n    └── InkReservoir               → used by InkPen directly\n```\n\n### 2. `Refill` as intermediate abstraction\n\n`BallPenRefill` and `GelPenRefill` share common cartridge behavior (replaceable, has ink level). Rather than duplicating\nthis, `Refill` abstract class captures it. `InkReservoir` doesn't extend `Refill` since it's not replaceable — it\ndirectly implements `InkSource`.\n\n### 3. `changeInkSource()` is abstract in `Pen`\n\nEach pen subclass knows exactly what `InkSource` to create:\n\n- `BallPen` → new `BallPenRefill(color)`\n- `GelPen`  → new `GelPenRefill(color)`\n- `InkPen`  → calls `reservoir.refillInk(color)` in place\n\n### 4. `PenFactory` uses `Supplier\u003cMechanism\u003e`\n\nMechanisms hold state (`open`/`closed`). A shared instance would cause all pens of the same mechanism type to share\nstate — a subtle but serious bug. `Supplier::get` produces a fresh instance per pen.\n\n---\n\n## ⚙️ How to Run\n\n```bash\n# Compile\njavac -d out $(find . -name \"*.java\")\n\n# Run\njava -cp out src.Main\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvimalyad%2Fpen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvimalyad%2Fpen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvimalyad%2Fpen/lists"}