Skip to content

Instantly share code, notes, and snippets.

@freqn
Created October 26, 2018 15:13
Show Gist options
  • Save freqn/2e2c1e83a88d4f84baf7e4bd648aea6d to your computer and use it in GitHub Desktop.
Save freqn/2e2c1e83a88d4f84baf7e4bd648aea6d to your computer and use it in GitHub Desktop.
design_pattern_notes

Architecture/Design Notes

First Points to Consider

  • Separate out the things that change from those that stay the same

    • Build systems that allow you to contain the damage
    • Build to avoid combing through code whenever a change or new functionality is needed
  • Program to an interface, not to implementation

    • Write code that is less tightly coupled to itself in the first place.
    • Program to the most general type that you can. For example, if you need need a Car class, but will also need a train, plane or boat, why not try to get away with a Vehicle class. Ruby is designed to help you program to the most general types. This also reduces the total amount of coupling in our code. In other words, design to alter the least amount of classes when a change or feature is required, making code less likely to break in the face of change.
  • Prefer composition over inheritance

    • Inheritance might not always be a good idea. In the case of adding a subclass to an exisiting class, is it always a good idea to marry two classes? In other words, avoid ripples through code where unnecessary. The alternative to this is composition, assembling functionality from the bottom up. Equipping objects with references to other objects that supply the functionality needed. Avoid saying that an object is a kind of something and instead say that it has something. Example, inheriting start_engine from a vehicle class might post problems for engine-less vehicles. Instead consider a separate Engine class vs a superclass of boat, car, etc. Giving each engine-powered vehicle a reference to it's own Engine class untangles the engine code from the vehicle class makes that type of vehicle ready for a drive. This also increases encapsulation, avoiding uncessary exposure of engine behavior to engine-less vehicles such as bicycles, canoes, etc. This also provides room to keep Engine abstract, helping to implement various types of engines.

      class Car
        ...
        def switch_to_diesel
          @engine = DieselEngine.new
        end
      
        def engine_start
          @engine.start
        end
        ..
      end
  • Delegate, delegate, delegate

    • Example - Car class delegating responsibility of start_engine to the Engine class
    • The cost of delegation is the boilerplate code that one might need to write
  • You ain't gonna need it

    • YAGNI principle - One should not implement features or design in flexibility that's not needed right now. Why? Because chances are, you ain't gonna need it later. Instead invest energy in only building the flexibility needed right now. Code will be much better only if it focuses on the job it needs to accomplish right now.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment