← Back to overview

how to build software

~ delay decisions until the decisions would be made for you by inaction

— 📖 97 Principles for Software Architects

beware premature abstraction

~ locality of behavior over separation of concerns

and:

~ inline the invocation, but don't inline the implementation

A common objection to locality of behaviour is that it is inlining implementation details within a code unit, making the code unit less abstract and more brittle. However, it is important to make the distinction between inlining the implementation of some behaviour and inlining the invocation (or declaration) of some behaviour.

Locality of Behaviour (LoB)

dependency injection

if a class needs another class to work, pass an instance of that class into the constructor instead of importing the dependency from the class itself

~ people discussing programming languages are not shipping products

The people discussing what programming language is best are not shipping products. The people who don't care what programming language they're using are shipping products.

— 📖 Make﹕ Bootstrapper's Handbook

~ always have a simple feedback box on your site

You can set this up with a lot of services like Olark or Intercom. What they do is they add a small chat box on the bottom left or bottom right of your web page. People can simply enter like, "Hey, there's a bug here" or "I want this feature."

— 📖 Make

occasionally re-read *Principles of Design*

~ trying to mirror software's function in prose is a violation of SSoT doomed to fail

— The Mythical Man Month

Big Design Up Front

paradigm where the entire design is done upfront

antifragility

  • how much something goes stronger due to time passed, mishaps, attacks

~ if a function must have a side effect, make it affect its parent object

— Clean Code

lead magnet

Sometimes, though, people want to know more about your offer before they buy. This is common for businesses that sell more expensive stuff. If that’s you, then you’ll often get more leads to engage by advertising with a lead magnet first. A lead magnet is a complete solution to a narrow problem. It’s typically a lower-cost or free offer to see who is interested in your stuff. And, once solved, it reveals another problem solved by your core offer.

— 📖 $100M Leads

~ goal of refactoring is pace, not sparkly best practice conforming

But I think the most dangerous way that people get trapped is when they try to justify refactoring in terms of “clean code,” “good engineering practice,” or similar moral reasons. The point of refactoring isn’t to show how sparkly a code base is—it is purely economic. We refactor because it makes us faster—faster to add features, faster to fix bugs. It’s important to keep that in front of your mind and in front of communication with others.

— 📖 Refactoring

AM⧸FM dilemma

  • The tension that exists between the world of actual machines and the world of fucking magic (or: fictional machines)

~ point of TDD is to force you design your code to be testable

~ every comment is a code design failure

— 📖 Clean Code

  • or: celebrate every expression in pure code, cringe at any use of comments

~ code only needs to be refactored if it needs to be changed

Let me stress that it’s these changes that drive the need to perform refactoring. If the code works and doesn’t ever need to change, it’s perfectly fine to leave it alone. It would be nice to improve it, but unless someone needs to understand it, it isn’t causing any real harm.

— 📖 Refactoring

approval test

With an approval test, you automate the test setup and teardown, but the assertion (or “approval”) is left to human input.

— 📖 Refactoring Javascript

> "extremely unsafe" and whatever, but works

~ SQLite is an excellent db, even deployed

SQLite specifically is great because it doesn't require you to install a lot, and when you make a database, it's just a file. It's very transportable. You can literally copy the database file from and to your server. There's misconceptions about SQLite that it'd be slow or not scalable enough. That's bullshit.

— 📖 Make﹕ Bootstrapper's Handbook

  • this isn't really about SQLite for me, but in a larger sense: Don't shun tech just because it isn't cool or corporate wouldn't use it (c.f. innovation tokens)

Command Query Separation

  • means:
    • do not have getters that also set something
    • do not have setters that also get something

I keep underestimating how long it takes to write stuff like a README

Block Element Modifier

....and the other CSS stuff

~ functions should only operate on one abstraction layer

— 📖 Clean Code

event-driven programming

Every time the user interacts with your program — clicks a button, pulls down a menu, or presses a key — the operating system generates an event. It throws this object at your app, and your job is to grab it and hook it up to some interesting behavior. This application style is so common, it’s considered a paradigm: event-driven programming.

— 📖 Game Programming Patterns

Demo or Die

Once outside the lab, they brought with them a mantra that would go on to influence Scrum deeply. They called it “Demo or Die.”

~ test on bad network conditions

feature-sliced design

  • structure your project according to the layers: app, pages, widgets, features, entities, shared
  • never import from a layer that's above, never import from a neighboring slice.
  • think about — and seek — coherence: within a slice, things may criss-cross import each other. Build these strongly coherent blocks.
  • the framework really leans itself to first building a fat block of code, and refactoring later ("moving things into the basement") if needed.
    • "not everything needs to be a feature"
  • keep the shared components dumb. No business logic there.
  • I have not really used standardized segment folders, rather just doing what I want within slice folders. Will possibly bite me later?
  • It seems weird (and unnecessary) at times to define all exports via an index.ts file, especially Vue components

fast, slow, slower

Continuous under-engineering leads to the “fast, slow, slower” rhythm of software development

— 📖 Refactoring to Patterns