Where to write code

Posted on 29 Jul 2025
Updated on 29 Jul 2025

Where to write code?

Maybe the seasoned programmers might instinctively know where a piece of logic belongs, but for many of us it it could be surprisingly tricky

Consider a realistic situation like below

A class UserDataModel which extends a base class DataModel. The UserDataModel already has a lot of code, and now there is a requirement to add a feature to it.

Before you start writing code, you need to decide where to write it? Below are the possible options you might choose from

  • As a member method to the given class UserDataModel
  • As a base method to the base class DataModel
  • As a static function to the class UserDataModel
  • As a static function to the base class DataModel
  • As a utility function outside of the class somewhere
  • As a private function in the class

This is a very basic questino that will affect the code maintainability, testability and architecture.

Member method/Instance Methods

When the code

  • operates on instance state
  • implements core object behaviour, what this object does

You may ask then we can easily pass the instance state to a function as parameter and externalize that logic which means that it will be operating on instance state. And by the way, every function will always be operating on instance state, if not directly. You can externalize the logic when

  • Logic is pure and stateless(means doesn’t use this)
  • Function works across multiple object types like function calculateCreditScore(user, transactions)
  • you are writing a utiltiy library

Static methods

Use when

  • doesn’t need instance state
  • logically belongs to the class(thats difficult to debate though)
  • creates or validates instances(factory methods/builder/validators)

e.g

class BankAccount {
    static fromJSON(data) {
        return new BankAccount(data.balance, data.accountType);
	}
    static isValidAccountNumber(number) {
        return /^\d{10}$/.test(number);
	}
}

Utility methods

Use when

  • has no class relationship - could work anywhere
  • is pure(same inputs always produce same output)
  • general purpose functionality(string manipulation, formatting, calculations)

Base class method

Use when

  • the needed behaviour is same across classes

Decision questionnaire

Ask these questions in order:

Does it need instance data? → Member method Is it related to the class concept but not instances? → Static method Could it be used anywhere in the codebase? → Utility function Is it shared behavior across subclasses? → Base class method

Flowchart

Here is a flowchart to make it easy for you

flowchart

Flowchart in mermaid code in case the above doesn’t render.

flowchart TD
    A[New Code to Write] --> B{Does it need access to<br/>instance data/state?}
    
    B -->|Yes| C{Is it core behavior<br/>of the object?}
    B -->|No| D{Is it conceptually related<br/>to a specific class?}
    
    C -->|Yes| E[Instance Method]
    C -->|No| F{Is it shared behavior<br/>across multiple subclasses?}
    
    F -->|Yes| G[Base Class Method]
    F -->|No| H{Can it be made pure<br/>by passing instance as param?}
    
    H -->|Yes| I[Consider Utility Function<br/>+ Instance Method Wrapper]
    H -->|No| E
    
    D -->|Yes| J{Does it create/validate<br/>instances of the class?}
    D -->|No| K{Is it general purpose<br/>and reusable?}
    
    J -->|Yes| L[Static Method]
    J -->|No| M{Does it operate on<br/>multiple instances?}
    
    M -->|Yes| L
    M -->|No| N{Is it a helper for<br/>the class but not instances?}
    
    N -->|Yes| L
    N -->|No| K
    
    K -->|Yes| O[Utility Function]
    K -->|No| P{Is it domain-specific<br/>business logic?}
    
    P -->|Yes| Q[Domain Service/Module]
    P -->|No| O
    
    %% Styling
    classDef decision fill:#e1f5fe,stroke:#01579b,stroke-width:2px
    classDef outcome fill:#e8f5e8,stroke:#2e7d32,stroke-width:2px
    classDef consideration fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
    
    class B,C,D,F,H,J,M,N,K,P decision
    class E,G,L,O,Q outcome
    class I consideration

Conclusion

The key is being intentional about the choice rather than defaulting to one pattern

Methods should live where they have the least coupling and highest cohesion with their surroundings

End