Skip to content

Instantly share code, notes, and snippets.

@andredublin
Last active December 10, 2015 04:48
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save andredublin/4383403 to your computer and use it in GitHub Desktop.
Save andredublin/4383403 to your computer and use it in GitHub Desktop.
Software development enlightenment that I have achieved over time.

#Testing

  • Isolate the object under test, don’t test multiple objects under one test case, this creates unneeded code and technical debt.
  • Unit test behavior, not methods. We need to know how to use the class to achieve a goal, not how to exercise all the paths through its code.
  • Don't test active record, it isn't a special behavior that the system is performing.
  • You don't need 100% test coverage all the time.
  • Don’t test query messages ( messages that do not modify another object ).
  • Do test command messages ( messages that do modify another object ).
  • Test the public interface of an object, private methods are always changing and add technical debt to the test and code.
  • Mock objects that are outside of the current object test scope (roles, interfaces, other objects)
  • Include roles, ducks and interfaces in a test so you only need to test it once.
  • Learn how to and try to write tests often, it will reveal code design.
  • Integration tests are tests that check how some of our code works with code from outside that we can’t change. Think of external apis for example. We would want to create a namespace for that interaction to live rather then muddy up existing code.
  • Acceptance tests are basically cucumber features, it is checking to see if the whole system works by using the BDD and TDD cycle.
  • Unit testing is testing if our objects work and if they work with each other.
  • How to mock
  • Create any required mock objects
  • Create any real objects
  • Specify how you expect the mock objects to be called by the target object
  • Call the triggering methods on the target object
  • Assert any values are valid and that all expected calls have been made
  • Read Growing Object-Oriented Software by Tests.

#Development

  • Don’t be afraid to make a mess, its sometimes “beneficial” to have many objects that are loosely coupled than few objects that are tightly coupled, this way the system is easy to change if needed without disturbing it’s neighbors.
  • Extract similar concretions ( abstractions/contracts ) from objects, these can become roles, interfaces or ducks.
  • Roles can be “modules” or “namespaces” or "traits" that hold other classes, methods and properties. These roles are then “included” or “used” by an objects that don’t explicitly have to take on the api of the role through inheritance.
  • Interfaces are public methods that are inherited by objects and have little change. This interfaces can be concrete ( abstract/honor the contract )
  • Don’t be afraid to break things.
  • Make your code readable, “function g_n()” will get you tarred and feathered, but “function get_names()” will get you many happy fun times. Naming should be intention-revealing, meaningful, and purpose-revealing.
  • Learn and embrace the two-step view
  • Design patterns are great, but testing first will reveal where and when they are needed. You can’t approach a problem all the time and say, I’m going to use the abstract factory pattern to solve this problem. This approach will pigeonhole you immediately.
  • For god sakes use a “OOP” compliant framework!
  • Establish a strong domain concept, rather than pulling out bags of methods into classes when you’re not sure if those methods may rely on other methods.
  • Read Clean Code.
  • Read Domain Driven Design.
  • If you want to teach yourself and don’t have any ideas, emulate unix programs, or build an app that interfaces with an api http://www.programmableweb.com/
  • Learn more than one language, better yet learn a language that is exotic and introduces different concepts, it will make you a better developer in the long run.
  • If theres no need to reinvent the wheel, then don't or make it better.
  • Value code that is easy to maintain over code that is easy to write.
  • Breaking out
  • When we find that the code in an object is becoming complex, that’s often a sign that it’s implementing multiple concerns and that we can break out coherent units of behavior into helper types.
  • Budding off
  • When we want to mark a new domain concept in the code, we often introduce a placeholder type that wraps a single field, or maybe has no fields at all. As the code grows, we fill in more detail in the new type by adding fields and methods. With each type that we add, we’re raising the level of abstraction of the code.
  • Bundling up
  • When we notice that a group of values are always used together, we take that as a suggestion that there’s a missing construct. A first step might be to create a new type with fixed public fields—just giving the group a name highlights the missing concept. Later we can migrate behavior to the new type, which might eventually allow us to hide its fields behind a clean interface, satisfying the “composite simpler than the sum of its parts” rule.

#Useful Stuff

Ruby

###Libraries

###Ruby MetaProgramming

  • Ghost methods - Overriding method_missing(:symbol, *args) and handling the message.
  • Dynamic methods - Defining methods at runtime with define_method(:symbol, method|{block}).
  • Dynamic dispatch - calling a method with .send(:symbol, *args) or .public_send(:symbol, *args).
  • Ruby objects find methods one to the right and up.

##PHP

###PHP Magic Methods

  • __consruct - Classes which have a constructor method call this method on each newly-created object.
  • __destruct - Classes which have a destructor will be called no matter what by an object.
  • __call - Invoked when calling inaccessible methods in an object context ($name, $arguments).
  • __callStatic - Invoked when calling inaccessible methods in a static context ($name, $arguments).
  • __get - Invoked when reading data from inaccessible properties.
  • __set - Invoked when writing data to inaccessible properties.
  • __isset - Is triggered by calling isset() or empty() on inaccessible properties.
  • __unset - Is invoked when unset() is used on inaccessible properties.
  • __sleep
  • __wakeup
  • __toString
  • __invoke
  • __set_state
  • __clone

###PHP Reflection To big to fit here, seriously its huge. For most projects I have yet to find a need for this, but its good to know. http://us2.php.net/manual/en/book.reflection.php

CSharp

  • Interfaces are your friends, use them to decouple classes. Classes that implement interfaces will take on the class signature and then you can pass them around as "anonymous" objects.

##Listen - Watch - Read

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment