Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> If you know from day one that you need to support two databases rather than one, that would be enough to cause design choices that you wouldn't otherwise make.

I disagree (strongly in favour of of DI / ports-and-adapters / hexagonal).

I don't want my tax-calculation logic to know about one database, let alone two!

Bad design:

  class TaxCalculator {
    PGConnection conn;
    TaxResult calculate(UserId userId) {..}
  }
Hypothetical straw-man "future-proof" design:

  class TaxCalculator {
    MagicalAbstractAnyDatabaseInterface conn;
    TaxResult calculate(UserId userId) {..}
  }
Actual better design:

  class TaxCalculator {
    UserFetcher userFetcher;
    PurchasesFetcher purchasesFetcher;
    TaxResult calculate(UserId userId) {..}
  }
I think a lot of commenters are looking at this interface stuff as writing more code paths to support more possible databases, per the middle example above. But I do the work to keep the database out of the TaxCalculator.


That sounds like a codebase that doesn't contain a single JOIN..


And that's fine.

If it's really big data I imagine I'd be in some kind of scalable no-SQL situation.

If it's not so big, Postgres will comfortably handle my access patterns even without joins.

If it's in the sweet spot where I need Postgres JOINS but I don't need no-SQL, well then, refactoring will be a breeze. I'll turn:

  class TaxCalculator {
    UserFetcher userFetcher;
    PurchasesFetcher purchasesFetcher;
    TaxResult calculate(UserId userId) {..}
  }
into:

  class TaxCalculator {
    UserPurchasesFetcher userPurchasesFetcher;
    TaxResult calculate(UserId userId) {..}
  }
which is backed by JOINS inside. And I can do this refactoring in two mutually-independent steps. I can make my Postgres class implement UserPurchasesFetcher without thinking about TaxCalculator, and vice versa.

And if it's about the data integrity that JOINs could notionally provide, I no longer believe in doing things that way. The universe doesn't begin and end within my Postgres instance. I need to be transacting across boundaries, using event sourcing, idempotency, eventual consistency and so forth.


Not advocating for or against, but having worked on systems like this, the joins here would happen in the Fetchers.

That is, User is the domain object, which could be built from one or more database tables inside the Fetcher.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: