Tuesday, November 22, 2011

Object Oriented Design - Anti-Patterns

Anemic Domain Model: The use of domain model without any business logic. The domain model's objects cannot guarantee their correctness at any moment, because their validation and mutation logic is placed somewhere outside (most likely in multiple places).
BaseBean: Inheriting functionality from a utility class rather than delegating to it
Call super: Requiring subclasses to call a superclass's overridden method
Suppose there is a class for generating a report about the inventory of a video rental store. Each particular store has a different way of tabulating the videos currently available, but the algorithm for generating the final report is the same for all stores. A framework that uses the call super anti-pattern may provide the following abstract class (in C#)
abstract class ReportGenerator {
    public virtual Report CreateReport() {
        // Generate the general report object
        // ...
        return new Report(...);
    }
}
A user of the class is expected to implement a subclass like this:
class ConcreteReportGenerator : ReportGenerator {
    public override Report CreateReport() {
        // Tabulate data in the store-specific way
        // ...
        // Design of this class requires the parent CreateReport() function to be called at the
        // end of the overridden function. But note this line could easily be left out, or the
        // returned report could be further modified after the call, violating the class design
        // and possibly also the company-wide report format.
        return base.CreateReport();
    }
}
A preferable interface looks like this:
abstract class ReportGenerator {
    public Report CreateReport() {
        Tabulate();

        // Generate the general report object
        // ...
        return new Report(...);
    }

    protected abstract void Tabulate();
}
An implementation would override this class like this:
class ConcreteReportGenerator : ReportGenerator {
    protected override void Tabulate() {
        // Tabulate data in the store-specific way
        // ...
    }
}
Circular dependency: Introducing unnecessary direct or indirect mutual dependencies between objects or software modules
Constant interface: Using interfaces to define constants
public interface Constants {
         public static final double PI = 3.14159;
        public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
 public class Calculations implements Constants {
         public double getReducedPlanckConstant() {
                return PLANCK_CONSTANT / (2 * PI);
        }
}

God object: Concentrating too many functions in a single part of the design (class)
Object cesspool: An object pool is a set of initialized objects that are kept ready to use, rather than allocated and destroyed on demand. A client of the pool will request an object from the pool and perform operations on the returned object. When the client has finished with an object, it returns it to the pool, rather than destroying it
Object orgy: Failing to properly encapsulate objects permitting unrestricted access to their internals. Unrestricted access makes it hard for the reader to reason about the behavior of an object. This is because direct access to its internal state means any other part of the system can manipulate it, increasing the amount of code to be examined, and opening the door to future abuse.
Poltergeists: Objects whose sole purpose is to pass information to another object
Sequential coupling: A class that requires its methods to be called in a particular order
Yo-yo problem: A structure (e.g., of inheritance) that is hard to understand due to excessive fragmentation. Most practices of object-oriented programming recommend keeping the inheritance graph as shallow as possible, in part to avoid this problem. The use of composition instead of inheritance is also strongly preferred, although this still requires that a programmer keep multiple class definitions in mind at once. More generally, the yo-yo problem can also refer to any situation where a person must keep flipping between different sources of information in order to understand a concept.

No comments:

Post a Comment