Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/hzblj-objects-and-data
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: documents, design, data, legal
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/objects-and-data
What's inside
- Skill name
objects-and-data- Description
- Clean-code objects vs. data structures — Tell Don't Ask, object/data anti-symmetry, Law of Demeter, contract-first design. Use when designing types, classes, and module boundaries. Triggers on: encapsulation, Tell Don't Ask, Law of Demeter, train wreck, DTO vs class, interface first.
- License
- MIT
- Instructions
- 292 lines in SKILL.md · view on GitHub
Files (2)
- SKILL.md
- openai.yaml · agents/
SKILL.md (first lines)
# Objects & Data Structures
The single most useful question you can ask about a type is: *does this thing hide its data behind behavior, or does it expose data for others to work with?* Get that decision wrong and every call site pays for it. This file is about drawing that line cleanly — telling objects what to do instead of interrogating them, keeping data structures and objects apart, refusing to chain through strangers, and nailing the contract before the logic.
For splitting the logic itself into small honest functions, see [functions](../functions/SKILL.md); for what to call any of these types, see [meaningful-names](../meaningful-names/SKILL.md). Types in every example follow the strict typing rules in [type-safety](../../type-safety/SKILL.md) — `type` over `interface`, no `any`, narrow unions.
## Expose behavior, not data (Tell, Don't Ask)
An object's job is to hide its data behind operations. When a caller reaches in, pulls out fields, computes something, and writes the result back, the object has become a dumb bag of state and the *rule* now lives at the call site — usually copy-pasted across three of them. Don't ask an object for its data and act on its behalf. **Tell it to do the work.**
```ts
// Bad — the caller reaches into the house and enforces the rule itself
const awardHousePoints = (wizard: Wizard, amount: number): void => {
wizard.house.points += amount
if (wizard.house.points > 500) {
wizard.house.leadsHouseCup = true
}
}
// Every place that adjusts points must remember the 500 rule. They won't.
```
```ts
// Good — tell the wizard; the rule lives in one place, behind the operation
class Wizard {
constructor(private readonly house: House) {}
awardPoints(amount: number): void {
this.house.credit(amount) // House owns its own invariant
}
}
class House {
private points = 0
private leadsHouseCup = false
credit(amount: number): void {
this.points += amount
this.leadsHouseCup = this.points > 500
}
}
```
The data (`points`, `leadsHouseCup`) is now private and the only way to change it is through `credit`. There is exactly one place the House Cup rule can be wrong, and exactly one place to fix it.
## Objects vs. data structures — pick the right tool
Not everything needs to be an object. The two shapes are mirror images:
- A **data structure** exposes its data and has no meaningful behavior — a plain typed record / DTO. An owl-post payload, a row from Gringotts, a spell definition read from a config file.
- An **object** hides its data and exposes behavior. `Wizard`, `House`, `Vault`.
Choose by asking one question: **are you more likely to add new data types, or new behaviors?**
- Expecting new **behaviors** on a fixed set of types → **objects**. Adding a method touches one class and nothing else.
- Expecting new **data variants** that a fixed set of operations must handle → **data structures + functions**. Adding a variant means one new record shape and one new `case`; the existing functions are the fixed set.
This is the data/object anti-symmetry: objects make new behaviors cheap and new types expensive; data structures + functions make new types cheap and new behaviors expensive. Neither is "cleaner" — they trade in opposite directions.
```ts
// Data structure — a spell definition loaded from config. Pure data, no behavior.
type SpellRecord = {
readonly kind: 'charm' | 'curse' | 'hex' | 'transfiguration'
readonly incantation: string
readonly wandMovement: string
}
// Functions operate over the fixed set of kinds. Adding a new *kind* is cheap:
// add a variant to the union and one branch here.
const spellDifficulty = (spell: SpellRecord): number => {
switch (spell.kind) {
case 'charm':
return 1
case 'hex':
return 2
case 'curse':
return 4
case 'transfiguration':
return 5
}
}
```
```ts
// Object — a Vault at Gringotts. Hides its data; you add *behaviors*, not variants.
class Vault {
private galleons: number
constructor(galleons: number) {
this.galleons = galleons
}
withdraw(amount: number): void {
if (amount > this.galleons) throw new Error('Insufficient galleons')
this.galleons -= amount
}
deposit(amount: number): void {
this.galleons += amount
}
// Adding `transferTo(other: Vault, amount)` touches only this class.
}
```
If you keep adding `case` branches to functions, you wanted an object. If you keep adding methods to a class that every subclass must override, you wanted a data structure. See the decision table at the bottom.
## Data/Object anti-symmetry — pick a side, your class can't be both
The hybrid is the worst of both worlds: a type that half-exposes its fields *and* half-exposes behavior. You get the fragility of a data structure (callers reach into public fields) plus the ceremony of an object (methods that pretend to protect invariants the public fields let anyone break). It's neither easy to add types to nor easy to add behaviors to.
```ts
// Bad — hybrid. Public mutable fields AND behavior methods that "guard" the same data.
class Potion {
name = ''
ingredients: string[] = [] // anyone can push/splice this from outside
brewed = false
brew(): void {
if (this.ingredients.length === 0) throw new Error('Empty cauldron')
this.brewed = trueFrom hzblj/skills, MIT.
More from hzblj/skills
- 0.547score
formatting
hzblj
Clean-code formatting — vertical ordering (stepdown/newspaper), declaring near use, team-enforced tooling.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
functions
hzblj
Clean-code functions — small, do one thing, one abstraction level, few arguments, no side effects, command-query separation, plus DRY and refactor discipline.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
meaningful-names
hzblj
Clean-code naming — intention-revealing, honest, distinct, pronounceable, searchable names with no type encoding.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
orchestration
hzblj
Tiered multi-agent orchestration — an expensive model plans and synthesizes while specialized subagents do the work in their own isolated contexts.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
project
hzblj
Monorepo project structure — Turborepo layout with packages/core-*, packages/platform-*, packages/feature-*, and deployable apps (mobile, web, backend, e2e)…
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
skia
hzblj
Opinionated rules for @shopify/react-native-skia in Expo + TypeScript — the declarative <Canvas> API (Circle/Rect/Path/Group/Paint/gradients/Blur), driving…
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
react-navigation
hzblj
React Navigation setup, typed routes, navigator structure, deep linking, and navigation actions.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
native-feel
hzblj
Opinionated rules for making an Expo + TypeScript app feel genuinely native on both platforms — a strict spacing/design-token system…
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
lists
hzblj
Strict performance rules for lists — FlashList, stable renderItem, extracted item components, and naming patterns.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
comments
hzblj
Clean-code comments — explain why not how, delete redundant and dead comments, prefer self-explaining code.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
error-handling
hzblj
Clean-code error handling — exceptions over error codes, wrap third-party APIs at a boundary, don't use catch as an if, don't return or pass null.
SkillBFreshness: B★ 1Claude Code +9 - 0.543score
reanimated-core
hzblj
Reanimated core — useSharedValue, useAnimatedStyle, useDerivedValue, useAnimatedReaction, useAnimatedProps, worklet rules, UI vs JS thread, runOnUI/runOnJS…
SkillBFreshness: B★ 1Claude Code +9
Signals
- Stars
- 1
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Jul 15, 2026 (3 months ago)
- Last release
- Aug 19, 2026 (2 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/hzblj/skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from hzblj
- 0.547score
lists
hzblj
Strict performance rules for lists — FlashList, stable renderItem, extracted item components, and naming patterns.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
comments
hzblj
Clean-code comments — explain why not how, delete redundant and dead comments, prefer self-explaining code.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
react-navigation
hzblj
React Navigation setup, typed routes, navigator structure, deep linking, and navigation actions.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
native-feel
hzblj
Opinionated rules for making an Expo + TypeScript app feel genuinely native on both platforms — a strict spacing/design-token system…
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
skia
hzblj
Opinionated rules for @shopify/react-native-skia in Expo + TypeScript — the declarative <Canvas> API (Circle/Rect/Path/Group/Paint/gradients/Blur), driving…
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
error-handling
hzblj
Clean-code error handling — exceptions over error codes, wrap third-party APIs at a boundary, don't use catch as an if, don't return or pass null.
SkillBFreshness: B★ 1Claude Code +9
Cite this page
objects-and-data skill. Agent Mart. https://agentmart.dev/skills/hzblj-objects-and-data (last updated 2026-10-24)