software craftsmanship rsingla@ford.com Code Smells Object Orientation Abusers
Object-Orientation Abusers 4 5 Change Preventers Couplers 3 2 Bloaters 1 Dispensables CODE SMELLS!!!
Object-Orientation Abusers Abuse = Treat with cruelty or violence, especially regularly or repeatedly. STOP! Abusing is a CRIME. 4 Refused Bequest Alternative Classes with Different Interfaces Switch Statements Temporary Field OBJECT
SWITCH STATEMENTS Your code contains lots of switch statements Increased code duplication Unorganized and large code base Tendency to grow with time No IF, No Else? Let’s SWITCH Switch is a big nested IF! Most prominent object-orientation abuser
Use polymorphism my Child! Isolate switch case using  Extract Method And then put it into the right class using  Move Method After specifying the inheritance structure, use  Replace Conditional with Polymorphism If one of the conditional options is null, use  Introduce Null Object OO has a better way to deal with actions based on types
TEMPORARY FIELDS Instance variable(s) of your object are used only in certain circumstances Object’s fields should have meaning across its entire lifetime Class becomes difficult to understand Unorganized and large code base Class size grows with time as new variables are added Cause: “My method requires large inputs. Too many parameters to pass!” Action: “Let me create some fields!” Result: Orphan variables. A variable which has no use for the object. Such a variable does not belong to the object! ORPHAN VARIABLE
Create a home for these orphan variables.  Extract Class Put all the code operating on these variables into this class.
REFUSED BEQUEST Child doesn’t use most of its parent’s methods and attributes NO! = ? ? There are legs in “Animal”. Let me inherit this class for my “Chair”! Code Reuse….You know! Unclear and Unorganized code Improper inheritance hierarchy (grows with time)
Inheritance makes no sense?  Replace Inheritance with Delegation Inheritance makes sense?  Extract Superclass Replace Inheritance with Delegation Use superclass object as a field in subclass and remove inheritance. Delegate methods to this object. 1 Put fields and methods used by the subclass into a separate class and let both superclass and subclass refer to this class Extract Superclass2
ALTERNATIVE CLASSES WITH DIFFERENT INTERFACES Two classes perform identical functions but have different methods Just create a class! Do not bother if there is an equivalent class performing a similar functionality - Lazy Programming Code duplication Increased complexity of code Unorganized and large code base Increased software cost (due to additional classes)
Make the interface of the classes blatantly duplicate: Identical behavior, but different methods?  Rename Method(s)  Add Parameter(s)  Parameterize Method(s) Only a part of both classes identical?  Extract Superclass Once classes are identical  Delete one of the classes
I WILL NEVER WRITE BAD CODE rsingla@ford.com

Software Craftsmanship - Code Smells - Object Orientation Abusers

  • 1.
  • 2.
  • 3.
    Object-Orientation Abusers Abuse =Treat with cruelty or violence, especially regularly or repeatedly. STOP! Abusing is a CRIME. 4 Refused Bequest Alternative Classes with Different Interfaces Switch Statements Temporary Field OBJECT
  • 4.
    SWITCH STATEMENTS Your codecontains lots of switch statements Increased code duplication Unorganized and large code base Tendency to grow with time No IF, No Else? Let’s SWITCH Switch is a big nested IF! Most prominent object-orientation abuser
  • 5.
    Use polymorphism myChild! Isolate switch case using  Extract Method And then put it into the right class using  Move Method After specifying the inheritance structure, use  Replace Conditional with Polymorphism If one of the conditional options is null, use  Introduce Null Object OO has a better way to deal with actions based on types
  • 6.
    TEMPORARY FIELDS Instance variable(s)of your object are used only in certain circumstances Object’s fields should have meaning across its entire lifetime Class becomes difficult to understand Unorganized and large code base Class size grows with time as new variables are added Cause: “My method requires large inputs. Too many parameters to pass!” Action: “Let me create some fields!” Result: Orphan variables. A variable which has no use for the object. Such a variable does not belong to the object! ORPHAN VARIABLE
  • 7.
    Create a homefor these orphan variables.  Extract Class Put all the code operating on these variables into this class.
  • 8.
    REFUSED BEQUEST Child doesn’tuse most of its parent’s methods and attributes NO! = ? ? There are legs in “Animal”. Let me inherit this class for my “Chair”! Code Reuse….You know! Unclear and Unorganized code Improper inheritance hierarchy (grows with time)
  • 9.
    Inheritance makes nosense?  Replace Inheritance with Delegation Inheritance makes sense?  Extract Superclass Replace Inheritance with Delegation Use superclass object as a field in subclass and remove inheritance. Delegate methods to this object. 1 Put fields and methods used by the subclass into a separate class and let both superclass and subclass refer to this class Extract Superclass2
  • 10.
    ALTERNATIVE CLASSES WITHDIFFERENT INTERFACES Two classes perform identical functions but have different methods Just create a class! Do not bother if there is an equivalent class performing a similar functionality - Lazy Programming Code duplication Increased complexity of code Unorganized and large code base Increased software cost (due to additional classes)
  • 11.
    Make the interfaceof the classes blatantly duplicate: Identical behavior, but different methods?  Rename Method(s)  Add Parameter(s)  Parameterize Method(s) Only a part of both classes identical?  Extract Superclass Once classes are identical  Delete one of the classes
  • 12.
    I WILL NEVERWRITE BAD CODE rsingla@ford.com

Editor's Notes

  • #2 This presentation is continuation to “Software Craftsmanship – Code Smells_3_Couplers”. Here we will cover the fourth category of code smells – “Object Orientation Abusers”.
  • #3 How do we know that code we have written is good or bad? Is it a subjective opinion or is there any metrics to determine whether it is readable/extensible/maintainable? Luckily for us, there IS A METRIC! When you go past a garbage can, you tend to block your nose, as the foul smell is almost unbearable. When there is something wrong with the code, we say there are certain elements in it which stink, making the whole code stink as well! These stinky elements are referred to as code smells. Now, when it comes to real life objects, the sense of foul smell is an innate human tendency. But when it comes to code, we need to teach ourselves to identify these code smells. In other words, we need to develop a nose to identify foul smells in the code. And this ability can only be developed when you are relatively young (new to development). As soon as a hatchling starts flying, its mother teaches it to hunt, for it won’t survive in its adulthood without the ability. The same goes with the ability to smell stink inside the code. It becomes harder and harder to develop this ability as we grow further into software development without it. For it is easier to learn than to unlearn. Writing a code with wrong practices is more dangerous than not writing the code at all! IT IS VERY IMPORTANT FOR ANY YOUNG DEVELOPER TO DEVELOP A NOSE FOR THESE CODE SMELLS! There are broadly 5 categories code smells are divided into. We are covering the fourth category here: Object Orientation Abusers
  • #4 Object oriented programming was introduced for a reason. It solved complex problems that procedural programming was incapable of solving. But just the tool is not enough. Mindset is very important. Refer to the example we discussed some slides back. How much sense does it make to rub two stones for generating fire while keeping a box of matchsticks in your pocket? Using stones instead is nothing less than an abuse for the matchstick. Its an even bigger abuse to all the people who spent their precious lives inventing things and evolving the world around us! All the elements that abuse the nature of object oriented programming fall under the category of code smells - Object-Orientation Abusers. We’ll see these elements in detail and try to get rid of them in subsequent slides.
  • #5 If you are using switch statements (or any other conditional constructs) in your code, you are primarily abusing the notion of object oriented programming. Object oriented programming aims at simulating the real world through software. If your think about it, the real world is nothing but a collection different objects exhibiting unique behaviors and interacting with each other through some interfaces (humans for example use sensory organs). For a living object (organism), a child inherits some traits of its parents while having some unique traits of its own. All of the scenarios in the real world can be simulated using objects in a program. (there are even few theories which claim that the real world is actually a computer simulation created by species of higher intelligence we refer to as Gods) Ask yourself this question - What is the purpose that the switch statements fulfill in my code? I can challenge that your answer will always be – ”Based on input value, I want to perform some action” Input value here is always an object (and if it is not, make it one – stop using primitives!). Based on the object type, you want to perform some action related to the object. Right? What happens as a result is that in each of the switch cases, you end up doing almost the same action, with a slight difference in respect to other actions. You end up writing duplicate code! Yes, the duplication here is subtle. But subtle duplication is duplication too! And every time, you want to add another action, you end up adding another case at all the places where you are switching on the object!
  • #6 Object oriented programming offers a much better way of dealing with actions based on the object types. It offers POLLYMORPHISM! A rule of thumb – “whenever you see switch statements in your code, think of polymorphism!” Treatment (read the slide)
  • #7 This code smell mostly occurs when the programmer tries to incorrectly remove another code smell – Long Parameter List. Carrying a procedural mindset, in order to avoid long list of parameters in the method, the programmer decides to use global variables instead. What happens as a result is that certain group of variables of the object almost always appear to be free - never populated, unless the method that uses these variables is called. A programmer going through the class, or debugging the code spends most of his time wondering why and where these variables get used. These variables are know as Orphan Variables. In context of the object, these are of no use and do not belong to the object. They do not have any home of their own and are not used most of the time, hence spend most of their lives chilling out. And as the number of methods in a class gets increased, such a practice results into huge number of temporary variables present in the class, cluttering it, making the code difficult to understand and to maintain. Most importantly, they abuse the object oriented nature of the code which states: the variables of an object should always represent the state of the object.
  • #8 You should create a home for these orphan variables. A home that gives a purpose to their lives. Treatment Temporary fields and all code operating on them can be put in a separate class via Extract Class. In other words, you are creating a method object, achieving the same result as if you would perform Replace Method with Method Object.
  • #9 This code smell occurs due to programmer’s inability to understand the inheritance chain and thus introducing a child that does not really belong to the parent. The major reason for doing so is to reuse some of the functionalities of the parent instead of duplicating them in a new class. What happens as a result is, while the child may use some of the parent’s functionalities, most of the parent’s functionalities remain unused. Child refuses its parent’s bequest. Consider the example of Animal class in the slide. Just because an Animal has 4 legs, does it make sense for the Chair class to inherit this class? Most of the traits of Animal will not be exhibited by the Chair and as a result, these traits will have an empty overridden implementations in the Chair class. You are abusing the nature of the Animal object itself by saying that a chair “is an” animal (this is how we read an inheritance chain. Child is said to have “is a” relationship with the parent)
  • #10 Extract the traits used by the unrelated classes (Animal and Chair) to a separate class (Leg) and let both the classes refer to an instance of this new class. (Replace Inheritance with Delegation) So, from Chair ‘is a’ Animal, change the relationships to: Chair ‘has a’ Leg and Animal ‘has a’ Leg. Treatment (read the slide)
  • #11 A truck has 4 tires and ‘moves’ on road. It is said to fall under a category of vehicles called “four wheeled vehicles”. Any object that has 4 tires and ‘moves’ on road falls under this category. Now, consider a car that ‘runs’ on four wheels. It is NOT CATEGORIZED as a four wheeler like truck because it ‘runs’ while a truck ‘moves’. Is it a good enough reason to not categorize it as four wheeled vehicle? Isn’t ‘run’ and ‘move’ just a different way of representing the same function – ‘motion’? When there are two different classes which are ideally performing the same function but have different method signatures (names, parameters etc), and as a result are not put into a common hierarchy, there is smell lurking around in your code known as - ALTERNATIVE CLASSES WITH DIFFERENT INTERFACES
  • #12 Treatment (read the slide)