Guru on Rails

if you don’t sacrifice for your dream then your dream becomes your sacrifice.
Will Nguyen
Four Meta-Design Patterns in ruby
Mon 20 Aug 2018

    1. Separating out the things that change from those that stay the same.

    Obviously, we do it to avoid the tight coupled code, get it easy to make changes with less cost. At first time when we put down your fingers to write methods, we should recognise what change from what stay the same. For example:

    class Animal
       def make_sound
       end
    end

    As you can see, the make_sound method here will be changed regularly. It relies on what kind of animal. The animal could be dog or cat or bird. They have different sounds. So, at first we notice that make_sound is changeable. Hence, we pull out this method to isolate it from the certain code.

    2. Program to an interface, not an implementation

    If we have the tree of inheritances like this A -> B -> C -> D -> E -> F -> ... Z. If A can do the same things, we shouldn't involve methods of B ... Z (A is superclass).

    • Carefully abstract out all the important functionality into many separate interfaces.
    • Program to the most general type you can
      • Reason ruby doesn't have interfaces -> encourage to program to interfaces. If B inherits A, if A can do things for B so involve methods of A instead of B.
    • Reduce the amount of coupling in our code.
    # challence
    car = Car.new
    car.drive(100)
    
    plane = Plane.new
    plane.fly(1000)
    
    # solution
    vehicle1 = Vehicle.new
    vehicle1.traval(100)
    
    vehicle2 = Vehicle.new
    vehicle2.traval(100)

    3. Prefer composition over inheritance

    • Inheritance tends to marry the subclass to the superclass, leading to bound the common implementation core (x)
    • Superclass is shown in subclass, leading to tight coupled (x) 

    Solutions:

    • Is kind of (x) => has (o)
    • Abstracting common methods at base class and refer to #2 if we couldn't avoid to use inheritance
    # Challenge
    class Vehicle
    	# All sorts of vehicle-related code...
    	def start_engine
    		# Start the engine
    	end
    	def stop_engine
    		# Stop the engine
    	end
    end
    
    class Car < Vehicle
    	def sunday_drive
    		start_engine
    			# Cruise out into the country and return
    		stop_engine
    	end
    end
    
    # Solution
    class Engine
    	# All sorts of engine-related code...
    	def start
    		# Start the engine
    	end
    	def stop
    		# Stop the engine
    	end
    end
    
    class Car
    	def initialize
    		@engine = Engine.new
    	end
    	def sunday_drive
    		@engine.start
    		# Cruise out into the country and return...
    		@engine.stop
    	end
    end

    4. Delegation

    Handing problems off to other objects. Take a look on code at #3, we can see that Car delegates object @engine to do things.