... we cannot construct a complex system in both ways simultaneously, for they are completely orthogonal views.
... the object-oriented approach is better at helping us organize the inherent complexity of software systems.
... we cannot construct a complex system in both ways simultaneously, for they are completely orthogonal views.
... the object-oriented approach is better at helping us organize the inherent complexity of software systems.
FACTORIES and REPOSITORIES have distinct responsibilities.
A FACTORY’S job is to instantiate a potentially complex object from data. If the product is a new object, the client will know this and can add it to the REPOSITORY, which will encapsulate the storage of the object in the database.
The desire for “find or create” functionality [...] This function should be avoided. It is a minor convenience at best.
Usually, the distinction between a new object and an existing object is important in the domain, and a framework that transparently combines them will actually muddle the situation.
class Repository { | |
/** | |
* Create | |
*/ | |
static async create(values) {} | |
static async createMany(records) {} | |
/** | |
* Read | |
*/ |
In a book rental app, to query a book that isn't returned yet (returnedAt
is either null
or undefined
):
const rented = await this.db.rental.findFirst({
where: {
book: {
uuid: params.id,
},
OR: [
{
abstract class Entity<T> { | |
public readonly id: T | |
protected abstract nextID(): T | |
constructor(id?: T) { | |
this.id = id || this.nextID() | |
} | |
} | |
class EntityWithUUID extends Entity<UUID> { | |
protected nextID(): UUID { |
Server.post( | |
'/example', | |
( | |
request: Request<{ [key: string]: string }, unknown, { name: string, amount: number }>, | |
response: Response | |
): void => { | |
response.json({ message: 'request.body.name' }) | |
} | |
) |
function run(opts) { | |
const result = {} | |
if (isPlainObject(opts?.tags) === false || isPlainEmptyObject(opts?.tags)) { | |
result.tags = {} | |
result.tags.latest = null | |
} else { | |
if (opts.tags.latest === undefined) { | |
result.tags = { | |
latest: null, |
class Registry { | |
private static instance: Registry | |
private constructor() {} | |
protected list = [] | |
private static getInstance() { | |
if (!Registry.instance) { | |
Registry.instance = new Registry() |
version: "3.8" | |
services: | |
postgres: | |
image: postgres:15.2-alpine | |
environment: | |
POSTGRES_USER: admin | |
POSTGRES_PASSWORD: secret | |
ports: | |
- 5432:5432 | |
pgadmin: |
const sum = (numbers = []) => { | |
if (numbers.length === 0) { | |
return 0 | |
} | |
return numbers[0] + sum(numbers.slice(1)) | |
} | |
const max = (numbers = []) => { | |
if (numbers.length === 0) { | |
return 0 |