object-oriented-programming/SKILL.md
Enforces object-oriented programming principles including encapsulation, composition over inheritance, GRASP patterns, message passing, and CRC-driven design. Use when designing class hierarchies, assigning responsibilities to objects, evaluating cohesion and coupling, refactoring toward better OO design, or reviewing code for OOP anti-patterns like God Objects and Anemic Domain Models.
npx skillsauth add kayaman/skills object-oriented-programmingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Reference: Practical Object-Oriented Design (Metz), Object Thinking (West), Applying UML and Patterns (Larman)
Objects are autonomous agents communicating via messages. Design starts with what messages are sent, not what data is stored. Alan Kay's definition: "OOP means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things."
| Pillar | Design Rule | Violation Signal |
|--------|-------------|-----------------|
| Abstraction | Hide complexity behind intention-revealing interfaces | Callers need to understand implementation to use the object |
| Encapsulation | Bundle data and behavior; restrict direct access to state | Public getters/setters exposing internal structure |
| Inheritance | Use ONLY for stable "is-a" where Liskov Substitution holds | Subclass overrides methods to do nothing, or breaks parent contracts |
| Polymorphism | Vary behavior through interchangeable objects sharing an interface | if/else or switch chains checking object type |
When deciding which object should handle a responsibility, apply these patterns in order of priority (Larman):
| Pattern | Rule | Apply When |
|---------|------|------------|
| Information Expert | Assign to the class that has the data needed | Default starting point for any responsibility |
| Creator | Assign creation to the class that aggregates, contains, or closely uses the target | Deciding where to put new/factory calls |
| Low Coupling | Among alternatives, choose the design that reduces dependencies | Comparing two valid designs |
| High Cohesion | Keep classes focused on a single purpose | A class is growing responsibilities beyond its core concern |
| Controller | A non-UI object receives and coordinates system events | Handling user actions or external triggers |
| Polymorphism | Use polymorphic dispatch instead of conditionals on type | if/switch testing object type to decide behavior |
| Pure Fabrication | Create a non-domain service class when Expert leads to poor cohesion | Expert assignment would bloat a domain object |
| Indirection | Introduce a mediating object to decouple two others | Two objects are too tightly coupled but need to collaborate |
| Protected Variations | Wrap predicted variation points behind stable interfaces | A known requirement may change in the future |
Default to composition. Use inheritance only when ALL of these hold:
Composition advantages:
| Technique | Use For | Example |
|-----------|---------|---------|
| Delegation | Forwarding behavior to a collaborator | class Order { private pricing: PricingPolicy } |
| Traits / Mixins | Sharing behavior across unrelated types without inheritance | Rust traits, Kotlin interfaces with default methods, PHP traits |
| Strategy / Policy | Varying one algorithm dimension | Interchangeable ShippingCalculator implementations |
| Decorator | Adding behavior dynamically | Wrapping a Logger around a Repository |
| Type | Quality | Description | |------|---------|-------------| | Functional | Best | All elements serve a single, well-defined task | | Sequential | Good | Output of one element feeds the next | | Communicational | Acceptable | Elements operate on the same data | | Procedural | Weak | Elements follow a sequence but share no data | | Temporal | Weak | Elements run at the same time (e.g., initialization) | | Logical | Poor | Elements are grouped by category, not purpose | | Coincidental | Worst | Random grouping — utility grab-bags |
| Type | Quality | Description | |------|---------|-------------| | Content | Worst | One module modifies another's internals directly | | Common | Poor | Modules share global mutable state | | External | Weak | Modules depend on the same external format or protocol | | Control | Weak | One module passes a flag controlling another's behavior | | Stamp | Acceptable | Modules share a composite data structure but use different parts | | Data | Best | Modules exchange only the parameters they need |
Design objects as autonomous virtual persons (West). Command them to act rather than querying their state and deciding externally.
Tell, Don't Ask:
# BAD — Ask: querying state, deciding externally
if order.status == "paid" and order.items_in_stock():
warehouse.ship(order)
# GOOD — Tell: the object decides internally
order.fulfill() # Order knows its own rules
Law of Demeter — only talk to immediate collaborators:
a.getB().getC().doSomething()self, parameters, instance variables, objects you create, or direct collaboratorsCRC Cards (Class-Responsibility-Collaboration):
Use when discovering object roles in design sessions. Each card lists:
Walk through use cases, role-playing objects. Missing responsibilities reveal missing objects.
| Anti-Pattern | Signal | Remedy |
|-------------|--------|--------|
| God Object | One class knows and does too much; most other classes are data holders | Extract responsibilities using Information Expert; apply SRP |
| Anemic Domain Model | Objects are data bags with getters/setters; all logic in service classes | Move behavior into domain objects — Tell, Don't Ask |
| Deep Hierarchy | 4+ inheritance levels; changes at the top cascade unpredictably | Flatten to max 2–3 levels; replace inheritance with composition |
| Getter/Setter Proliferation | Every field has public get/set; encapsulation is broken | Remove getters; ask the object to perform the operation instead |
| Primitive Obsession | Using raw strings, ints for domain concepts (email, money, ID) | Introduce Value Objects: EmailAddress, Money, OrderId |
| Feature Envy | A method uses more data from another class than its own | Move the method to the class whose data it uses |
| Refused Bequest | Subclass overrides inherited methods to do nothing or throw | Replace inheritance with composition; the relationship isn't "is-a" |
Pure OO dogma has given way to blending OO encapsulation with FP immutability and higher-order functions. Apply these guidelines:
Before finalizing an object-oriented design, verify:
| Book | Author(s) | Publisher | Year | |------|-----------|-----------|------| | Practical Object-Oriented Design (2nd ed.) | Sandi Metz | Addison-Wesley | 2018 | | Head First Object-Oriented Analysis and Design | McLaughlin, Pollice, West | O'Reilly | 2006 | | Growing Object-Oriented Software, Guided by Tests | Freeman & Pryce | Addison-Wesley | 2009 | | Design Patterns: Elements of Reusable OO Software | Gamma, Helm, Johnson, Vlissides | Addison-Wesley | 1994 | | Object Thinking | David West | Microsoft Press | 2004 | | Elegant Objects Vol 1 & 2 | Yegor Bugayenko | Self-published | 2016–2017 | | Applying UML and Patterns (3rd ed.) | Craig Larman | Prentice Hall | 2004 | | Object-Oriented Software Construction | Bertrand Meyer | Prentice Hall | 1997 | | Balancing Coupling in Software Design | Vlad Khononov | Addison-Wesley | 2024 | | A Philosophy of Software Design (2nd ed.) | John Ousterhout | Stanford | 2021 |
tools
Guidance for designing charts, graphs, plots, dashboards, and data visualizations that communicate clearly and persuade. Use when creating or reviewing a visualization, choosing a chart type, picking a color palette, decluttering a busy graphic, fixing misleading axes or proportions, building a dashboard, annotating a figure, or turning data into a presentation, report, or data-driven story. Grounded in the standard data-visualization literature (Knaflic, Tufte, Cleveland & McGill, Cairo, Wilke, Munzner, Few, Berinato). Covers chart selection, graphical perception and encoding, color and accessibility, decluttering, graphical integrity, dashboards, and narrative. Does NOT cover building data pipelines or ETL, statistical modeling or analysis methods, BI tool/vendor selection, or general UI/UX layout (see ux-design-principles). Tool-agnostic, with optional Python recipes.
development
Architect and implement production-grade microservices systems in TypeScript (NestJS) and Python (FastAPI), including resilience, observability, testing, deployment, and migration guidance.
development
--- name: databricks-genie-spaces-best-practices description: Design, configure, curate, govern, monitor, and integrate Databricks AI/BI Genie Spaces — the natural-language-to-SQL surface over Unity Catalog. Covers space scoping, general instructions, parameterized example SQL, SQL functions, trusted assets, JOIN configuration, knowledge store, certified queries, benchmarks, monitoring tab, feedback loops, the Genie Conversation API, governance via Unity Catalog (row filters, column masks, embed
tools
Implement OTP and passwordless authentication on AWS for TypeScript projects using Cognito CUSTOM_AUTH triggers (default) or a custom DynamoDB-backed flow, with SES (email) and SNS (SMS) delivery. Use when the user mentions OTP, one-time password, passwordless login, magic link, Cognito custom auth, DefineAuthChallenge, CreateAuthChallenge, VerifyAuthChallengeResponse, SES verification email, SNS SMS code, or MFA over email/SMS. Covers architecture decision (Cognito vs custom), Lambda trigger handlers, SES/SNS notifiers, DynamoDB schema with TTL, rate limiting, constant-time comparison, threat model (enumeration, replay, brute force), and aws-sdk-client-mock testing.