Skip to content

Instantly share code, notes, and snippets.

@louismullie
Last active July 27, 2024 17:45
Show Gist options
  • Save louismullie/0228cb30b0822e11fb253aaade9cf46d to your computer and use it in GitHub Desktop.
Save louismullie/0228cb30b0822e11fb253aaade9cf46d to your computer and use it in GitHub Desktop.
Cell biology design patterns

Cell Biology Patterns

Summary

Pattern Cellular Biology Use Case
Singleton Cell Nucleus: Only one nucleus controls the cell's activities, maintaining a single source of genetic information.
Factory Method Ribosomes: Produce different proteins based on the mRNA template, acting as a factory for various protein products.
Abstract Factory Cell Differentiation: Stem cells differentiate into various types of specialized cells, each with its own set of organelles and functions.
Builder Protein Synthesis: Step-by-step assembly of proteins from amino acids, following the instructions in mRNA.
Prototype Cell Division: Creation of new cells by duplicating the contents of an existing cell, with slight modifications in daughter cells.
Adapter Enzyme-Substrate Interactions: Enzymes adapt to fit different substrates, allowing various molecules to be processed.
Bridge Signal Transduction: Separates the reception of external signals from the internal cellular response mechanisms.
Composite Multicellular Organisms: Individual cells form tissues, organs, and organ systems, creating a hierarchical structure.
Decorator Post-translational Modifications: Addition of functional groups to proteins after translation, modifying their function.
Facade Cell Membrane: Provides a simplified interface for complex cellular interactions with the external environment.
Flyweight tRNA Usage: Reuse of tRNA molecules for efficient translation of multiple mRNA codons.
Proxy Nuclear Pore Complex: Controls access to the cell nucleus, acting as a gateway for molecule transport.
Chain of Responsibility Signal Cascades: Series of protein interactions in signaling pathways, where each protein activates the next.
Command Hormones: Encapsulate instructions for cells to perform specific actions, triggered by receptor binding.
Iterator DNA Replication: Systematic traversal of the DNA strand during replication, processing each base pair sequentially.
Mediator Endocrine System: Hormones act as mediators, coordinating activities between different organs and tissues.
Memento Gene Silencing: Storage of epigenetic marks that can be restored to affect gene expression without changing DNA sequence.
Observer Gene Regulation: Transcription factors observe the presence of specific signals to regulate gene expression.
State Cell Cycle Phases: Cells exhibit different behaviors and characteristics as they progress through the stages of the cell cycle.
Strategy Alternative Splicing: Different exon combinations from the same pre-mRNA can create various protein isoforms.
Template Method DNA Replication: Defines the overall process with specific steps (unwinding, priming, elongation) that may vary between leading and lagging strands.
Visitor Immune System Recognition: Immune cells 'visit' other cells to check for antigens, applying different responses based on what they find.

Singleton (Cell Nucleus)

The Singleton pattern ensures that a class has only one instance and provides a global point of access to it. This mirrors the cell nucleus, which is the single control center for cellular activities. Just as a cell has only one nucleus coordinating its functions, the Singleton pattern maintains a single, centralized instance to manage critical resources or control points in a system.

class Nucleus {
  private static instance: Nucleus;
  private constructor() {}
  static getInstance(): Nucleus {
    if (!Nucleus.instance) {
      Nucleus.instance = new Nucleus();
    }
    return Nucleus.instance;
  }
  controlCell(): void {
    console.log("Controlling cell activities");
  }
}

Factory Method (Ribosomes)

The Factory Method pattern defines an interface for creating objects but lets subclasses decide which class to instantiate. This is analogous to ribosomes producing different proteins based on mRNA templates. Like ribosomes that can create various proteins following different mRNA instructions, the Factory Method allows for flexible object creation based on varying inputs or conditions.

abstract class Ribosome {
  abstract synthesizeProtein(mRNA: string): Protein;
}

class Protein {}

class EukaryoticRibosome extends Ribosome {
  synthesizeProtein(mRNA: string): Protein {
    return new Protein();
  }
}

Abstract Factory (Cell Differentiation)

The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. This is similar to how stem cells can differentiate into various specialized cell types, each with its own set of organelles and functions. The pattern allows for the creation of different "families" of objects, just as stem cells can give rise to different families of specialized cells.

interface CellFactory {
  createNucleus(): Nucleus;
  createMitochondria(): Mitochondria;
}

class StemCell implements CellFactory {
  createNucleus(): Nucleus { return new Nucleus(); }
  createMitochondria(): Mitochondria { return new Mitochondria(); }
}

class NeuronCell implements CellFactory {
  createNucleus(): Nucleus { return new NeuronNucleus(); }
  createMitochondria(): Mitochondria { return new NeuronMitochondria(); }
}

Builder (Protein Synthesis)

The Builder pattern separates the construction of a complex object from its representation, allowing the same construction process to create different representations. This mirrors protein synthesis, where amino acids are assembled step-by-step following mRNA instructions to create diverse proteins. The Builder pattern, like protein synthesis, allows for the gradual construction of complex objects with potentially different final forms.

class ProteinBuilder {
  private sequence: string = '';
  addAminoAcid(aa: string): this {
    this.sequence += aa;
    return this;
  }
  build(): Protein {
    return new Protein(this.sequence);
  }
}

Prototype (Cell Division)

The Prototype pattern creates new objects by copying an existing object, known as the prototype. This is akin to cell division, where a new cell is created by duplicating an existing cell's contents. Just as daughter cells may have slight modifications from the parent cell, the Prototype pattern allows for creating new objects that are similar but not identical to the original.

class Cell implements Cloneable {
  constructor(public dna: string) {}
  clone(): Cell {
    return new Cell(this.dna);
  }
  mutate(): void {
    // Implement mutation logic
  }
}

Adapter (Enzyme-Substrate Interactions)

The Adapter pattern allows incompatible interfaces to work together. This is similar to how enzymes adapt to fit different substrates, enabling various molecules to be processed. The Adapter pattern, like enzyme-substrate interactions, allows for flexibility in how different components interact, bridging incompatibilities.

interface Substrate { react(): void; }
class Glucose implements Substrate {
  react(): void { console.log("Glucose reacting"); }
}

class Enzyme {
  process(substrate: Substrate): void {
    substrate.react();
  }
}

Bridge (Signal Transduction)

The Bridge pattern separates an abstraction from its implementation, allowing them to vary independently. This is analogous to signal transduction in cells, where the reception of external signals is separated from the internal cellular response mechanisms. The pattern, like signal transduction, allows for flexibility in how external inputs are processed and responded to internally.

interface SignalReceiver {
  receiveSignal(signal: string): void;
}

class CellResponse {
  respond(): void {
    console.log("Cell responding to signal");
  }
}

class SignalTransducer implements SignalReceiver {
  constructor(private response: CellResponse) {}
  receiveSignal(signal: string): void {
    console.log(`Received signal: ${signal}`);
    this.response.respond();
  }
}

Composite (Multicellular Organisms)

The Composite pattern composes objects into tree structures to represent part-whole hierarchies, allowing clients to treat individual objects and compositions uniformly. This mirrors the structure of multicellular organisms, where individual cells form tissues, organs, and organ systems in a hierarchical manner. The pattern, like biological organization, allows for complex structures to be built from simpler components.

abstract class BiologicalUnit {
  abstract function(): void;
}

class Cell extends BiologicalUnit {
  function(): void {
    console.log("Cell functioning");
  }
}

class Organ extends BiologicalUnit {
  private parts: BiologicalUnit[] = [];
  add(part: BiologicalUnit): void {
    this.parts.push(part);
  }
  function(): void {
    this.parts.forEach(part => part.function());
  }
}

Decorator (Post-translational Modifications)

The Decorator pattern attaches additional responsibilities to an object dynamically. This is similar to post-translational modifications in biology, where proteins are modified after translation to alter their function. The Decorator pattern, like these modifications, allows for the flexible enhancement of objects without altering their core structure.

interface Protein {
  function(): void;
}

class BaseProtein implements Protein {
  function(): void {
    console.log("Base protein function");
  }
}

class Phosphorylation implements Protein {
  constructor(private protein: Protein) {}
  function(): void {
    this.protein.function();
    console.log("Added phosphate group");
  }
}

Facade (Cell Membrane)

The Facade pattern provides a unified interface to a set of interfaces in a subsystem, simplifying its use. This is analogous to the cell membrane, which provides a simplified interface for complex cellular interactions with the external environment. The Facade pattern, like the cell membrane, encapsulates complex internal workings and presents a simpler interface to the outside world.

class CellMembrane {
  transportNutrients(): void {
    console.log("Transporting nutrients");
  }
  signalReception(): void {
    console.log("Receiving signals");
  }
  wasteRemoval(): void {
    console.log("Removing waste");
  }
}

Flyweight (tRNA Usage)

The Flyweight pattern uses sharing to support a large number of fine-grained objects efficiently. This is similar to the reuse of tRNA molecules for efficient translation of multiple mRNA codons. The Flyweight pattern, like tRNA usage, allows for the efficient management of a large number of similar small objects by sharing common parts.

class tRNA {
  constructor(public anticodon: string) {}
}

class tRNAPool {
  private tRNAs: {[key: string]: tRNA} = {};
  gettRNA(anticodon: string): tRNA {
    if (!this.tRNAs[anticodon]) {
      this.tRNAs[anticodon] = new tRNA(anticodon);
    }
    return this.tRNAs[anticodon];
  }
}

Proxy (Nuclear Pore Complex)

The Proxy pattern provides a surrogate or placeholder for another object to control access to it. This is akin to the nuclear pore complex, which controls access to the cell nucleus. The Proxy pattern, like the nuclear pore complex, acts as a gatekeeper, managing access to a protected resource or object.

interface NuclearAccess {
  enterNucleus(molecule: Molecule): void;
}

class Nucleus implements NuclearAccess {
  enterNucleus(molecule: Molecule): void {
    console.log("Molecule entered nucleus");
  }
}

class NuclearPoreComplex implements NuclearAccess {
  constructor(private nucleus: Nucleus) {}
  enterNucleus(molecule: Molecule): void {
    if (this.checkMolecule(molecule)) {
      this.nucleus.enterNucleus(molecule);
    }
  }
  private checkMolecule(molecule: Molecule): boolean {
    return true; // Simplified check
  }
}

Chain of Responsibility (Signal Cascades)

The Chain of Responsibility pattern passes requests along a chain of handlers, with each deciding to process the request or pass it to the next handler. This mirrors signal cascades in cells, where a series of proteins interact, each activating the next in the pathway. The pattern, like cellular signaling cascades, allows for flexible and decoupled processing of requests or signals.

abstract class SignalProtein {
  protected next: SignalProtein | null = null;
  setNext(protein: SignalProtein): SignalProtein {
    this.next = protein;
    return protein;
  }
  abstract handle(signal: string): void;
}

class KinaseA extends SignalProtein {
  handle(signal: string): void {
    if (signal === "hormoneA") {
      console.log("KinaseA activated");
    } else if (this.next) {
      this.next.handle(signal);
    }
  }
}

Command (Hormones)

The Command pattern encapsulates a request as an object, allowing for parameterization of clients with queues, requests, and operations. This is analogous to hormones, which encapsulate instructions for cells to perform specific actions. The Command pattern, like hormones, allows for the encapsulation and transmission of actions or instructions.

interface CellCommand {
  execute(): void;
}

class InsulinCommand implements CellCommand {
  constructor(private cell: Cell) {}
  execute(): void {
    this.cell.absorbGlucose();
  }
}

class Hormone {
  constructor(private command: CellCommand) {}
  bind(): void {
    this.command.execute();
  }
}

Iterator (DNA Replication)

The Iterator pattern provides a way to access elements of a collection sequentially without exposing its underlying representation. This is similar to DNA replication, where the DNA strand is systematically traversed and each base pair is processed sequentially. The Iterator pattern, like DNA replication machinery, provides a standardized way to traverse a complex structure.

class DNA {
  constructor(private sequence: string) {}
  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        if (index < this.sequence.length) {
          return { value: this.sequence[index++], done: false };
        } else {
          return { done: true };
        }
      }
    };
  }
}

Mediator (Endocrine System)

The Mediator pattern defines an object that centralizes communication between other objects, reducing their dependencies on each other. This is akin to the endocrine system, where hormones act as mediators coordinating activities between different organs and tissues. The Mediator pattern, like the endocrine system, allows for decoupled communication between components through a central coordinator.

class Hormone {
  constructor(public name: string) {}
}

class EndocrineSystem {
  notify(organ: Organ, hormone: Hormone): void {
    console.log(`${organ.name} notified of ${hormone.name}`);
  }
}

class Organ {
  constructor(public name: string, private system: EndocrineSystem) {}
  receiveSignal(hormone: Hormone): void {
    this.system.notify(this, hormone);
  }
}

Memento (Gene Silencing)

The Memento pattern captures and restores an object's internal state without violating encapsulation. This is similar to gene silencing mechanisms, where epigenetic marks can be stored and restored to affect gene expression without changing the DNA sequence. The Memento pattern, like epigenetic modifications, allows for the preservation and restoration of state information.

class GeneExpression {
  constructor(private state: boolean = true) {}
  silence(): void { this.state = false; }
  express(): void { this.state = true; }
  saveState(): GeneMemento {
    return new GeneMemento(this.state);
  }
  restoreState(memento: GeneMemento): void {
    this.state = memento.getState();
  }
}

class GeneMemento {
  constructor(private state: boolean) {}
  getState(): boolean { return this.state; }
}

Observer (Gene Regulation)

The Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified automatically. This mirrors gene regulation, where transcription factors observe the presence of specific signals to regulate gene expression. The Observer pattern, like gene regulatory networks, allows for responsive and coordinated behavior based on state changes.

interface GeneObserver {
  update(signal: string): void;
}

class Gene implements GeneObserver {
  update(signal: string): void {
    console.log(`Gene expression changed due to ${signal}`);
  }
}

class TranscriptionFactor {
  private observers: GeneObserver[] = [];
  addObserver(observer: GeneObserver): void {
    this.observers.push(observer);
  }
  notifyObservers(signal: string): void {
    this.observers.forEach(observer => observer.update(signal));
  }
}

State (Cell Cycle Phases)

The State pattern allows an object to alter its behavior when its internal state changes, appearing to change its class. This is analogous to the cell cycle, where cells exhibit different behaviors and characteristics as they progress through various phases. The State pattern, like the cell cycle, allows for objects to change their behavior based on internal state transitions.

interface CellState {
  performAction(cell: Cell): void;
}

class G1Phase implements CellState {
  performAction(cell: Cell): void {
    console.log("Cell growing");
  }
}

class SPhase implements CellState {
  performAction(cell: Cell): void {
    console.log("DNA replicating");
  }
}

class Cell {
  private state: CellState;
  constructor() {
    this.state = new G1Phase();
  }
  setState(state: CellState): void {
    this.state = state;
  }
  performAction(): void {
    this.state.performAction(this);
  }
}

Strategy (Alternative Splicing)

The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. This is similar to alternative splicing, where different exon combinations from the same pre-mRNA can create various protein isoforms. The Strategy pattern, like alternative splicing, allows for flexibility in choosing between different implementations or outcomes based on context.

interface SplicingStrategy {
  splice(preRNA: string): string;
}

class ExonSkipping implements SplicingStrategy {
  splice(preRNA: string): string {
    return "Skipped exon version";
  }
}

class IntronRetention implements SplicingStrategy {
  splice(preRNA: string): string {
    return "Retained intron version";
  }
}

class Spliceosome {
  constructor(private strategy: SplicingStrategy) {}
  performSplicing(preRNA: string): string {
    return this.strategy.splice(preRNA);
  }
}

Template Method (DNA Replication):

The Template Method pattern defines the skeleton of an algorithm in a method, deferring some steps to subclasses. This mirrors DNA replication, which has a defined overall process with specific steps that may vary between leading and lagging strands. The Template Method pattern, like DNA replication, provides a structured framework while allowing for variations in specific steps.

abstract class DNAReplication {
  replicate(): void {
    this.unwind();
    this.primeSynthesis();
    this.elongate();
    this.terminateAndLigate();
  }
  protected unwind(): void {
    console.log("Unwinding DNA");
  }
  protected abstract primeSynthesis(): void;
  protected abstract elongate(): void;
  protected terminateAndLigate(): void {
    console.log("Terminating and ligating");
  }
}

class LeadingStrandReplication extends DNAReplication {
  protected primeSynthesis(): void {
    console.log("Single primer synthesis");
  }
  protected elongate(): void {
    console.log("Continuous elongation");
  }
}

Visitor (Immune System Recognition)

The Visitor pattern represents an operation to be performed on elements of an object structure, allowing for new operations to be defined without changing the classes of the elements. This is analogous to how immune cells 'visit' other cells to check for antigens, applying different responses based on what they find. The Visitor pattern, like immune system recognition, allows for flexible operations on a set of objects without modifying their core structure.

interface Cell {
  accept(visitor: ImmuneCell): void;
}

class BodyCell implements Cell {
  accept(visitor: ImmuneCell): void {
    visitor.visit(this);
  }
}

interface ImmuneCell {
  visit(cell: BodyCell): void;
}

class TCell implements ImmuneCell {
  visit(cell: BodyCell): void {
    console.log("T Cell checking for antigens");
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment