{"id":27696549,"url":"https://github.com/jferrl/ecommerce-kata","last_synced_at":"2025-04-25T15:11:24.191Z","repository":{"id":286824003,"uuid":"962676308","full_name":"jferrl/ecommerce-kata","owner":"jferrl","description":"Tell dont ask kata","archived":false,"fork":false,"pushed_at":"2025-04-08T14:14:30.000Z","size":7,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-08T15:24:42.846Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","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/jferrl.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}},"created_at":"2025-04-08T14:05:56.000Z","updated_at":"2025-04-08T14:14:33.000Z","dependencies_parsed_at":"2025-04-08T15:34:55.088Z","dependency_job_id":null,"html_url":"https://github.com/jferrl/ecommerce-kata","commit_stats":null,"previous_names":["jferrl/order-system-kata"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jferrl%2Fecommerce-kata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jferrl%2Fecommerce-kata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jferrl%2Fecommerce-kata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jferrl%2Fecommerce-kata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jferrl","download_url":"https://codeload.github.com/jferrl/ecommerce-kata/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250840608,"owners_count":21495910,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":"2025-04-25T15:11:23.687Z","updated_at":"2025-04-25T15:11:24.183Z","avatar_url":"https://github.com/jferrl.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go Refactoring Workshop: Tell Don't Ask, Rich Domain Models \u0026 Deep Modules\n\nThis repository demonstrates the application of key software design principles through a practical refactoring exercise of a Go e-commerce application.\n\n## 🎯 Learning Goals\n\nThis workshop focuses on three important software design principles:\n\n1. **Tell, Don't Ask**  \n   A principle that encourages telling objects what to do rather than asking them for data and making decisions outside. This reduces coupling and improves encapsulation.\n\n2. **Rich Domain Models (vs. Anemic Domain Models)**  \n   Moving beyond data-only objects toward entities that encapsulate both data and behavior, enforcing their own business rules and invariants.\n\n3. **Deep Modules**  \n   As described in \"A Philosophy of Software Design\" by John Ousterhout, deep modules provide powerful functionality while hiding implementation complexity behind simple interfaces.\n\n## 🔍 The Example: E-commerce Order System\n\nThe repository contains a simplified e-commerce order processing system with:\n\n- Products with inventory management\n- Users with payment information\n- Order creation and processing\n- Payment handling\n\n## 💡 Key Refactorings Demonstrated\n\n### Tell, Don't Ask\n\n**Before:**\n```go\n// Checking conditions outside the object\nif product.StockQuantity \u003c quantity {\n    return errors.New(\"insufficient stock\")\n}\nproduct.StockQuantity -= quantity\n```\n\n**After:**\n```go\n// Telling the object what to do\nerr := product.DecreaseStock(quantity)\nif err != nil {\n    return err\n}\n```\n\n### Rich Domain Model\n\n**Before:**\n```go\n// Anemic domain model - just data\ntype Order struct {\n    ID            string\n    UserID        string\n    Items         []OrderItem\n    TotalAmount   float64\n    Status        string\n    PaymentStatus string\n    CreatedAt     time.Time\n}\n\n// Business logic in services\nfunc (os *OrderService) ProcessOrder(orderID string) error {\n    // ... logic for processing order\n}\n```\n\n**After:**\n```go\n// Rich domain model with behavior\ntype Order struct {\n    // Same fields as before\n}\n\n// Business logic in domain objects\nfunc (o *Order) Process() error {\n    if o.Status != \"PENDING\" {\n        return errors.New(\"order already processed\")\n    }\n    if o.PaymentStatus != \"PAID\" {\n        return errors.New(\"cannot process unpaid order\")\n    }\n    o.Status = \"PROCESSED\"\n    return nil\n}\n```\n\n### Deep Modules\n\n**Before:**\n- Shallow services with minimal functionality\n- High coupling between services\n- Implementation details exposed\n\n**After:**\n- Domain repositories that abstract storage concerns\n- Meaningful interfaces that hide complexity\n- Clear separation of domain and infrastructure concerns\n\n## 🚀 How to Use This Repository\n\n1. Start by examining the code in `before/main.go` to identify issues\n2. Study the refactored implementation in the `after/` directory\n3. Complete the exercises in the `exercises/` directory\n4. Refer to the documentation for deeper understanding\n\n## 📚 Further Reading\n\n- \"A Philosophy of Software Design\" by John Ousterhout\n- \"Domain-Driven Design\" by Eric Evans\n- \"Clean Architecture\" by Robert C. Martin\n\n## 🔗 Additional Resources\n\n- [Tell Don't Ask Principle](https://martinfowler.com/bliki/TellDontAsk.html)\n- [Anemic Domain Model](https://martinfowler.com/bliki/AnemicDomainModel.html)\n- [John Ousterhout's lectures on software design](https://milkov.tech/assets/psd.pdf)\n\n## 📋 Contributing\n\nFeel free to submit pull requests with additional examples, exercises, or documentation improvements!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjferrl%2Fecommerce-kata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjferrl%2Fecommerce-kata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjferrl%2Fecommerce-kata/lists"}