Sunday 26 January 2014

OOP Design - Part 1 - Fundamentals

I hope, you have already read "Preface" of this post.  Also don't miss to refer corresponding example java code (not for production, illustrative purposes only) to understand each fundamental topic.

About Building Object Oriented System

  • Its all about Objects - Instantiating, Communicating, Managing, Extending, Monitoring…
  • In most of the cases, Everything is done by Developer.
  • What developers end up without knowledge of object oriented design principles and patterns? --- Answer is "Complex Code" – which is hard to maintain, extend and reuse. Because of,
    • Writing to much boilerplate
    • Duplication
    • Entangled interfaces
    • Complicated dependencies
    • Rigid, Fragile and Immobile code
ABC of Object Oriented Design and Responsibilities
  • OO Design
    • Identify classes and objects
    • Decide methods belong to what class/object and how they interact
  • Responsibilities
    • Assigned to classes/methods during design
    • Translation of responsibilities into classes/methods is influenced by the granularity of responsibility
    • Responsibilities are not same as methods, but methods fulfill responsibilities
    • Two Types of responsibilities - Doing & Knowing

Goal of a Object Oriented Design

  • Reusability, Flexibility, Extendibility, Maintainability...

Characteristics of Bad Design / Design Smell

Yes, designs or code can smell. They point to problems with the structure of code: class organization, relationships, collaborations/dependencies, responsibilities etc. Software OOP fundamentals and design principles represent a set of guidelines that helps us to avoid having a bad design.

Some of key characteristics of bad design are,
  • Rigidity = It is hard to change because every change affects too many other parts of the system. That means, difficult to add new features.
  • Fragility = When you make a change, unexpected parts of the system break. That means, unable to identify impact of the change.
  • Immobility = Code is hard to reuse in another application because it cannot be disentangled from the current application. That means, no reusability.
  • Viscosity = Going with the flow of bad practices already being present in the code.
  • Needless Complexity = the design adds additional structure that provides no direct benefit.
  • Opacity = It is hard to read and understand.  The code does not express its intent well.

OOP Fundamentals

Abstraction = Looking only at the information that is relevant at the time.
  • Abstraction is the process or result of generalization by reducing the information content of a concept or an observable phenomenon, typically in order to retain only information which is relevant for a particular purpose.
  • Functional abstraction - means that a function can be used without taking into account how the function is implemented.
  • Data Abstraction - means that data can be used without taking into account how the data are stored.

Encapsulation = Data hiding mechanism. (example code snippet)
  • The process of binding or wrapping the data and the codes that operates on the data into a single entity. This keeps the data safe from outside interface and misuse. One way to think about encapsulation is as a protective wrapper that prevents code and data from being arbitrarily accessed by other code defined outside the wrapper.
  • For example, if a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class.

Inheritance = IS-A relationship between a superclass and its subclasses. (example code snippet)
  • The process where one object acquires the members of another; plus can have its own.
  • For example, Dog (subclass) is-a of type Animal (superclass). So Dog can inherit (reuse) members of Animal class;  plus it can have its own new behavior and properties.

Polymorphism = single interface multiple implementations. (example code snippet)
  • How Polymorphism is supported in Java? - In terms of interface, inheritance, method overloading and method overriding. (Method overloading and method overriding uses concept of Polymorphism in Java where method name remains same in two classes but actual method called by JVM depends upon object at run time and done by dynamic binding in Java. In case of overloading method signature changes while in case of overriding method signature remains same and binding and invocation of method is decided on runtime based on actual object. This facility allows Java programmer to write very flexibly and maintainable code using interfaces without worrying about concrete implementation. One disadvantage of using Polymorphism in code is that while reading code you don't know the actual type which annoys while you are looking to find bugs or trying to debug program. But if you do Java debugging in IDE you will definitely be able to see the actual object and the method call and variable associated with it.)
  • Where to use Polymorphism in code? - You should use super type in method argument, variable name and return type of method.
  • Parameteric Polymorphism in Java - Java started to support parametric polymorphism with introduction of Generic in JDK1.5. Collection classes in JDK 1.5 are written using Generic Type which allows Collections to hold any type of object in run time without any change in code and this has been achieved by passing actual Type as parameter. 

Delegation = hand over the responsibility for a particular task to another class or method. (example code snippet)
  • If you need to use functionality in another class but you do not want to change that functionality then use delegation instead of inheritance.
  • Classical example of delegation design principle is equals() and hashCode() method in Java. In order to compare two object for equality we ask class itself to do comparison instead of Client class doing that check. Benefit of this design principle is no duplication of code and pretty easy to modify behavior.

Aggregation = HAS-A relationship. (example code snippet)
  • Aggregation is an association represents a part of a whole relationship where a part can exist without a whole. It has a weaker relationship.
  • For example, If line-item HAS-A product, then a line item is a whole and product is a part. If a line item is deleted, then corresponding product needs not to be deleted.

Composition = HAS-A relationship, but restricted form of Aggregation. (example code snippet)
  • Composition is an association represents a part of a whole relationship where a part cannot exist without a whole. If a whole is deleted then all parts are deleted. It has a stronger relationship.
  • Favor Composition over Inheritance.
  • For example, if order HAS-A line-items, then an order is a whole and line items are parts. If an order is deleted then all corresponding line items for that order should be deleted.

Loose Coupling = Low dependencies between “artifacts” (classes, modules, components). (example code snippet)
  • There shouldn’t be too much of dependency between the modules, even if there is a dependency it should be via the interfaces and should be minimal.
  • Avoid tight-coupling for collaboration between two classes (if one class wants to call the logic of a second class, then they first class needs an object of second class it means the first class creates an object of second class).
  • Strive for loosely coupled design between objects that interact.
  • Inversion Of Control (IoC) / Dependency Injection (DI) - With DI objects are given their dependencies at creation time by some third party (i.e. Java EE CDI, Spring DI…) that coordinates each object in the system. Objects aren’t expected to create or obtain their dependencies—dependencies are injected into the objects that need them. The key benefit of DI—loose coupling.

High Cohesion = The code has to be very specific in its operations. (example code snippet)
  • The responsibilities/methods are highly related to class/module.
  • The term cohesion is used to indicate the degree to which a class has a single, well-focused responsibilities. Cohesion is a measure of how the methods of a class or a module are meaningfully and strongly related and how focused they are in providing a well-defined purpose to the system.  The more focused a class is, the higher its cohesiveness - a good thing.
  • A class is identified as a low cohesive class, when it contains many unrelated functions within it. And that what we need to avoid, because big classes with unrelated functions hamper their maintaining. Always make your class small and with precise purpose and highly related functions.


Few principles, every developer should always keep in mind and apply when writing code.

Interface based design = Coding to an interface, not to an implementation
  • One of the best practices that object oriented programmers should try to strive for is to write java classes to interfaces instead of concrete classes.
  • Writing to interfaces reduces coupling and gives a great flexibility in running the unit and integration tests without having to modify the client code whenever the implementation of a service component is changed.
  • It can achieve code reuse with the help of object composition.

DRY principle = Don't repeat yourself
  • Software development principle to reduce repetition of information of all kinds.
  • Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
  • Avoid copy-paste of code. Otherwise change in the code would have to be made in all the places where its been copied.
  • Don't write duplicate code for "application logic", instead abstract common things in one place.
  • For example - If you use a hardcoded value more than one time consider making it public final constant. If you have block of code in more than two place consider making it a separate method.

KISS principle = Keep it simple, stupid / keep it simple and straightforward
  • Simplicity should be the a goal of design and unnecessary complexity should be avoided.
  • For example - If there is a need of grate manipulations on collections, then don't write your own complex custom implementation. If you like the "Function" style, maybe make use of the proven Guava library (which has the Function interface and many helper methods that work with them on collections). That is DRY (because you don't repeat yourself, and re-use code that already exists), and still KISS (because those are well understood patterns).

YAGNI principle = You aren't gonna need it
  • A principle of extreme programming (XP) that states a programmer should not add functionality until deemed necessary.
  • Don't be tempted to write code that is not necessary at the moment, but might be in the future.
  • Recommended to be used in combination with several other practices, such as continuous refactoring, continuous automated unit testing and continuous integration.
  • See also - Over-engineering

AOP = Aspect Oriented Programming
  • A programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns (e.g. logging, exceptional handling, caching…). Identify the aspects of your application that vary and separate them from what stays same.
  • AOP is a concept and as such it is not bound to a certain programming language or programming paradigm. The Java implementation of AOP is called AspectJ. Or Spring AOP can be used.


Also Refer:

Static Code Analyzers - Checkstyle, PMD, FindBugs - Are those alternatives or not?

I hope, you have already read "Preface" of my static code analyzers series.

Majority of programmers take shortcuts while writing code, because shortcuts save time and usually go unnoticed … until something breaks badly in production. To avoid such situations, on-going java source code review activity must be part of development life cycle.  To keep code quality consistent in a project, you should rely on using java code analyzers instead of just manual code review performed by self or peer.  But which tools can ensure quality accredited standards in project?

If using Eclipse IDE for development, then commonly known java code audit analyzer plug-ins are: Checkstyle, PMD and FindBugs. If you are 2-3 years experience java developer, you should be already using any of these or similar tools. I know, next question would be - should use all three or any one of Checkstyle, PMD and FindBugs plug-in? I would try to answer this question in this post and you can always refer tool's documentation for more detail such as demo screenshots, installation steps, user guide, etc.

My Personal Feedback
  • When to use?
    • Are you looking for a tool to enforce coding conventions and standards in code? Then you can use Checkstyle. --- Its main focus is ensuring the coding style adheres to a set of conventions. It would catch things like missing/improper javadoc, naming conventions, placement of braces and parentheses, whitespace, line length, etc.
    • Do you want a tool to detect bad practices in code? Then you can use PMD. --- It scans source code and looks for bad code such as empty try/catch blocks, using .equals() instead of ‘==’, over-complicated expressions, unused variables and imports, unnecessary loops and if statements, enforce naming conventions, etc.
    • Do you need a tool to find potential bugs in code for you? Then you can use FindBugs. --- It can find problems like improper use of .equals() and .hashCode(), unsafe casts, possible ignored exceptions, possible stackoverflows, when something will always be null, etc.
    • PMD vs. FindBugs --- There is a lot of overlap between FindBugs and PMD. But the biggest difference between PMD and FindBugs is that FindBugs works on byte code, whereas PMD works on source code. So some of potential problems FindBugs can find at byte code level, which PMD won't be able to report by scanning source code. Also sometimes based on what type of software artifact (source code or compiled classes or jar file) is available for analysis, you can select PMD vs. FindBugs.
  • Initial learning curve and ease-of-use, setup requirements?
    • Eclipse plug-in is available for each of three tools; as well as other known IDEs are supported. Just install Eclipse plug-in and start using it. Pretty simple to use with default settings. They  ( Checkstyle Eclipse Plug-in, PMD Eclipse Plug-in,FindBugs Eclipse Plug-in) are actively upgraded to support latest stable Eclipse (Eclipse Kepler - 4.3 version as on 18-Jan-2014).
    • Also these tools integrate with Maven, SonarQube, etc. Please check website of each tool to know all available options to run the tool and setup requirements.
    • Important note - If you run tool with default settings, then you would get long list of review findings. Obviously all can't be fixed always considering the time factor. Hence it demands to prioritize project specific quality standards and then customize tool's configuration to match those, which requires good knowledge of code quality standards as well as tool specific rules.
  • Cost?
    • All three are open-source projects, so don't worry about licensing costs.
  • Challenges?
    • One of challenge is that sometimes developer requires detailed knowledge or manual analysis to distinguish a false positive finding (a bug that's not really a bug) reported by tool.
Practical Shot
  • I ran all three tools (by installing plug-ins in Eclipse Kepler) with default settings on java code of one of open source project, which I used in past (MockMock: a cross-platform SMTP server built on Java which allows you to mock email sending functionality and to see how emails look like). I don't aim to improve code by analyzing all reported problems for real vs. false warnings. Instead I would quickly show, what kind of issues are reported by each tool on the same codebase. Here is a summary of reported findings by each tool and my feedback.

  • Checkstyle - Found total 2228 problems as per below screenshot. You can see reported problems are mainly related to java code conventions and standards, for example - missing javadoc, related to code beautification, declaring field as final, etc. If we work rigorously to fix those, then it would greatly improve maintainability of code.

  • PMD - Found total 1321 violations as per below screenshot. The key focus of the tool is finding programming bad practices or code smells such as extra imports, related to variable declaration, avoid catching generic exception, avoid too many methods in class, etc. Sometime it requires in-depth analysis against reported violation, for example here Google Guava library is used in the code where it shows potential violation of LawOfDemeter rule. Also it has "Copy/Paste Detector (CPD)" add-on to find duplicate code. So we should refactor code to fix violations reported by PMD to reduce potential problems and improve overall maintainability of the code.

  • FindBugs - FindBugs reported total 2 potential bugs as per screenshot. It works on concept of finding bug patterns. FindBugs works by analyzing Java bytecode (compiled class files), so you don't even need the program's source code to use it.  Sometimes FindBugs can report false warnings (not real errors).  FindBugs says - "In practice, the rate of false warnings reported by it is less than 50%". We can see here, reported bug by FindBugs in Line 85 is not found by PMD and vice-versa is in Line 87.

My Final Thoughts
  • If you use Eclipse, do take benefit of available code analyzer plug-ins (instead of standalone tools) to boost confidence on quality of your delivered java code. You should check each tool's supported integration options against project's ecosystem for getting best benefits. For example , in given situation you may benefit by integrating code audit tools with Maven, Jenkins, SonarQube, etc.
  • Checkstyle, PMD, FindBugs --- There is a good amount of overlap among them, but each provides a unique service. Keeping ROI in mind, I recommend to use PMD at minimum for projects having just 3-4 months development phase with less than 5 developers team. Otherwise for best results, developers should use all three "Checkstyle + PMD + FindBugs" for code review by doing necessary customizations (audit rules configuration  changes) as per project requisite.
  • The next question can be --- Is there any single packaged tool having ability of "Checkstyle + PMD + FindBugs + more..."? Well, personally I prefer either "Codepro Analytix" or "SonarQube".


Disclaimer
I don't aim to exploit code of any open source project or sample application, while I share my evaluation feedback of given tool on selected publicly available code. Also I am not biased to particular free or commercial tools, rather my objective is about sharing my own experience on set of tools.

Also Refer

Sunday 12 January 2014

OOP Design - Fundamentals and Principles - Preface

How to achieve effective design?
  1. Follow OOP (object oriented programming) fundamentals
  2. Avoid bad design characteristics (code smell)
  3. Embrace Design Principles
    • Class Design - SOLID & GRASP
    • Package Design
  4. Consider Design Patterns and Anti-patterns
In next series of articles,

I would explain below topics along with example java code.
  • OOP Fundamentals [Part-1]
  • Class design principles - SOLID [Part-2] & GRASP [Part-3 - coming soon]
  • Package design principles [Part-4 - coming soon]
      Note: This series is focused to cover OOP fundamentals and design principles. Design patterns and anti-patterns are not included as part of this series; instead I shall cover those separately

      A bird's-eye view of OOP fundamentals and design principles


      Design Principles vs. Design Patterns?

      • Design Principle – A set of guidelines that helps us to avoid having a bad design.
      • Design Pattern
        • Emphasize on principles to assign responsibilities.
        • General reusable solution for a problem.
        • Shows relationships and interactions between classes or object.
      • Example
        • Principle – Dependency Inversion Principle
        • Pattern – Factory, Abstract Factory (Object Creational)
        • Popular frameworks – Spring IoC, Guice, JavaEE CDI, etc.

      Saturday 11 January 2014

      Java power tools series - Static Code Analyzers - Preface

      I hope, you have already read "Preface" of my java power tools series.

      Does this sound familiar to you?
      At this stage - you don't perform code review at all / peer review is performed without using any tools. That means, you write the code and try to trust on knowledge of own/peer/team lead to ensure quality accredited standards.  Well, this can never produce consistent outcome. So now you are looking for better option or you got hints that you should use the tool to let you tell that what are problems in the code and may be how to fix/improve...

      What is static code analyzer tool?

      • The tool which can scrutinize the code artifacts (without executing program) for given purpose such as review for
        • coding conventions,
        • coding standards,
        • potential bugs,
        • performance issues,
        • security flaws,
        • concurrency issues,
        • cyclic dependencies...
      • Ideally, such tools would find the common problems in the code with a high degree of confidence that what is found is indeed a flaw. On top of that few tools would recommend the solutions too for the identified problems/flaws.
      • Most of Java code analyzer tools are designed to work by integrating into Eclipse IDE (as it is used widely), so the immediate feedback can be provided to the java developer during the development cycle itself.


      Few parameters to consider for the scoping of code analyzer tools
      All tool cannot fit in your project environment. So first of all you need to check features of selected tools against the parameters applicable to your project need. Then you should proceed to setup tool and try practically for envisioned benefits. You can consider some of below parameters for the scoping of code analyzer tools for the project.
      • Purpose -
        • Want to ensure overall code quality management?
        • Need to audit code for specific area such as security, performance, multi-threading?
      • Supported platform / language / developer's IDE -
        • Windows, Linux, other?
        • Java, .NET, other?
        • Does it only support Eclipse IDE or other also? Can it run in standalone mode?
      • Supported type of artifacts -
        • Does it work with source code?
        • Can it run against binaries (class files) instead of source?
        • Can it work with build files (jar, war, ear)?
      • Ease of setup / Learning curve -
        • Is it easy to setup or does it require complex manual configuration?
        • Can new user learn and use tool easily or is there a need of specialized training?
      • License cost -
        • Free or Open Source?
        • Commercial (are sold as perceptual, floating, per user, per application, per organization...)?


      My Favorite Tools for Java
      Below are some of my favorite static code analyzer tools and each of those I would cover in separate post.

      Tools
      When to use?
      • Are you looking for a tool to enforce coding conventions and standards in code? Then you can use Checkstyle.
      • Do you want a tool to detect bad practices in code? Then you can use PMD.
      • Now do you need a tool even to find potential bugs in code for you? Then you can use FindBugs.
      • For best results, you should use Checkstyle + PMD + FindBugs.
            • I know, you must be thinking - cannot be single Eclipse plug-in which can provide ability of "Checkstyle + PMD + FindBugs" and more such as code coverage, dependency analysis…? Well, you can consider Codepro Analytix.
            • Do you want to analyze dependencies at class, package or container level? Do you want to understand dependency (all/direct/indirect) paths using diagrams generated from code? Do you want to find cyclic dependencies? Then you can use Codepro Analytix tool - dependency analysis feature.
              • Are you looking for platform to help you on continuous overall code quality management? Then you can consider SonarQube and Jenkins integration to improve software quality to increase the efficiency of your development teams and the longevity of your application. Don't miss to read deal with developers' seven deadly sins using SonarQube.
              • Do you want to generate DSM (dependency structure matrix) from code artifacts to manage dependencies of complex java applications by  removing cycles between packages by cutting undesired dependencies? Then you can use SonarQube DSM.
                • Are you looking for easy-to-use tool to help you on managing complex Java code base, achieving high code quality and performingarchitecture evaluation of existing or legacy java software for refactoring / re-engineering / migration / modernization? Then JArchitect can provide you immense benefits by its interactive CQLinq (code query linq), visualized diagrams, comprehensive reports and other features. Don't miss to watch 3 minutes demo of JArchitect.
                    • You are working on web or J2EE application, in which security is most critical parameter. So are you thinking about a tool to audit for known security problems and help you to fix? Then you can consider Find Security Bugs or Eclipse LAPSE+ tools.
                      EclEmma (free), eCobertura (free)
                      • You write unit test code (i.e. jUnit) and want to audit quality of test coverage? Then perform code coverage (a         measure used to describe the degree to which the source code of a program is tested by a particular test suite) analysis directly into the Eclipse IDE using EclEmma or eCobertura plug-ins.


                      Few good to know
                      Below are some of interesting  code analyzer tools. In past I evaluated basic features of those, and hence I would not aim to cover in separate post for now. I recommend to try any of those based on my initial knowledge, if you get opportunity.
                      • Sonatype CLM (Commercial) - for component lifecycle management
                      • Code coverage tools
                        • Crap4j (free) - Java implementation of the CRAP (Change Risk Analysis and Predictions) software metric, which combines cyclomatic complexity and code coverage from junit tests. Integrated with Eclipse and Ant.
                        • Emma (free) - Supported coverage types are class, method, line, basic block. Can execute via Command line and Ant.
                        • Covertura (free) - Supports both line and branch coverage. Can execute via Command line, Ant and Maven.
                        • Clover (commercial) - Apart from Java, supports  Groovy too. Integrates with known IDEs, Build and CI tools.
                      • Miscellaneous
                        • Contemplate ThreadSafe (commercial) - java code audit tool for multi-threaded application, which helps to improve developers’ ability to detect data race errors, dead-locks and concurrency problems in Java source code.
                        • CheckThread (free) - java static code analysis tool for multi-threaded application, which helps to catch Java concurrency bugs at compile time.
                        • Checker Framework (free) - a pluggable java type checking tool that warns about certain errors or gives a guarantee that those errors do not occur such as null pointer exceptions, unintended side effects, SQL injections, concurrency errors, mistaken equality tests, and other run-time errors that appear during testing or in the field. Checker Eclipse plugin is also available.
                        • Class Dependency Analyzer (free) - a tool for dependency analysis among classes.
                        • BundleMaker (free) - an Eclipse plugin for Dependency Structure Matrix.
                        • CodeAnalyzer (free) - produces a software source file metrics includes ratio of total lines vs. code lines vs. comments vs. white spaces; and supports html, java, c, c++ file extensions.


                      Updates History

                      • 28/Dec/2014 - Added JArchitect in my favorite tools section.


                      Disclaimer
                      I don't aim to exploit code of any open source project or sample application, while I share my evaluation feedback of given tool on selected publicly available code. Also I am not biased to particular free or commercial tools, rather my objective is about sharing my own experience on set of tools.

                      Also Refer