instanceof

Usually, when you check for an object being instance of a class, you can implement the scenario with polymorphism.

The Template Method and the Strategy patterns are all about this replacement, which comes handy also in the case of switches and if statements.

goto (jumps)

Should I say anything? Even Java, the most-diffused object-oriented language in the world, has Goto as a reserved keyword (I hope it is not implemented).

break and continue (disguised jumps)

They are really gotos which have put on camouflage, and any professor of computer science would keep an eye on you if you used them (mine did, and I was too young to recognize the value of clean code).

extends (subclassing)

Subclassing is very often abused, with classes extending other ones only to gain access to their methods, in spit of is-a relationships; maybe we can prohibit them altogether. We'll gain almost automatic conformance to the Liskov Substitution Principle, since it would involve only interface and their implementations. The main reason for its infringements, sharing methods code, would go away.

Since eliminating subclassing is a bit extreme, an idea that stroke me while re-reading Uncle Bob's explanation of SOLID principles is to eliminate subclassing of concrete classes. This way, we'll never introduce a dependency towards an implementation detail, but we can still make use of abstract classes, very valuable in an API.

protected (subclassing scope)

Of course, if we eliminate subclassing, we can throw away the intermediate protected scope altogether. Also if we choose a single level of subclassing towards an abstract one, this scope would do less harm than it does today.

For example, in Zend Framework almost always is protected instead of private, and the user is free to subclass and access any internal part of the framework's components. The scenarios that happen then are two: either the framework developers cannot modify code anymore to avoid breaking backward compatibility (so why they bothered restricting the scope in the first place), or the user has to revise his classes when upgrading from 1.6.1 to 1.6.2 because of sudden changes.

public (for fields)

Public fields are the death of encapsulation, and I can't remember the last time I introduced a public field long time ago. Let's just throw them away.

private (for methods)

How do you test private methods? Often we arrive to a situation where we have complex private methods we want to test independently. This is often a smell of a class that does more than one thing (Single Responsibility Principle), and should be ripped up. In this case, we can move the private methods away and transform them in public methods on a private collaborator, safeguarding encapsulation but simplifying the picture and being able to test them due to the new contract established between the main class and the extracted one.

switch (conditional chain) Switch chains, especially if duplicated in different places, can be replaced with polymorphism. The idea is to push the switch up to che choice of the object, and push the particular operations in each of the switch branches into the chosen object.

if (conditional) If we can replace switches, we can also replace ifs, that are a special case of switch with only two branches. The reasoning is the same and the advantages are clear: you would have only one execution path to test for each method, and you'll be sure of which lines are executed: all of them. Misko Hevery says that often most of the ifs can be replaced with polymorphism, but you should be pragmatic about it and not try to kill them all.

S.O.L.I.D.

S: SRP Single responsibility principle the notion that an object should have only a single responsibility. established set of Object Role Stereotypes

  • Information holder – an object designed to know certain information and provide that information to other objects.
  • Structurer – an object that maintains relationships between objects and information about those relationships.
  • Service provider – an object that performs specific work and offers services to others on demand.
  • Controller – an object designed to make decisions and control a complex task.
  • Coordinator – an object that doesn't make many decisions but, in a rote or mechanical way, delegates work to other objects.
  • Interfacer – an object that transforms information or requests between distinct parts of a system.

O: OCP Open/closed principle the notion that "software entities … should be open for extension, but closed for modification". L: LSP Liskov substitution principle the notion that "objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program". See also design by contract. I: ISP Interface segregation principle the notion that "many client specific interfaces are better than one general purpose interface."[5] D: DIP Dependency inversion principle the notion that one should "Depend upon Abstractions. Do not depend upon concretions."[5] Dependency injection is one method of following this principle. "let's rewrite this function so it obtains all its state from the caller"

Law of Demeter

  • Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
  • Each unit should only talk to its friends; don't talk to strangers.
  • Only talk to your immediate friends.