Search

Primitive Obsession with Example


Primitive Obsession is the name of a code smell that occurs when we use primitive data types to represent domain ideas. For example, we use a string to represent a message or an integer to represent an amount of money.
For Example: Code with Primitive Obsession
// primitiveObsession.java

public
class primitiveObsession {

    public static void main(String args[]) {

           Integer[] cityPopulations = {

           13000000, // London

           21903623, // New York

           12570000, // Tokyo

           1932763, // Stockholm

           1605602, // Barcelona

           4119190 // Sydney

           };

 
           for (Integer cityPopulation:cityPopulations)

           {

              System.out.println(cityPopulation);
           }

   }

}


 

Example: Code without Primitive Obsession
//City.java

 

public class City {


private final String name;


private final int  population;


private final Continent continent;


public String getName() {
return name;

}


public int getPopulation() {


return  population;

}


public Continent getContinent() {


return continent;

}




public City(String name, int population, Continent continent) {


this.name = name;


this.population = population;


this.continent = continent;

}




public String toString() {


return String.format( "%s has a popluation of %s and is located in %s",


name, population, continent);

}


public static final City[] ALL_CITIES={


new City("London",13000000,Continent.EUROPE),


new City("New York",21903623,Continent.AMERICA),


new City("Tokyo",12570000,Continent.ASIA),


new City("Stockholm",1932763,Continent.EUROPE),


new City("Barcelona",1605602,Continent.EUROPE),


new City("Sydney",4119190,Continent.AUSTRALIA)

};

}



//Continent.java


public
enum Continent {


AMERICA,


EUROPE,


AFRICA,


ASIA,


AUSTRALIA

}

// withOutPrimitiveObsession.java

public class withOutPrimitiveObsession {

    public static void main(String args[]) {



        for (City city:City.ALL_CITIES) {

          System.out.println(city.toString());

        }

    }

}

Factory Pattern


  • This pattern is used when it must be decided at run time which one of several compatible classes is to be instantiated.
  • For example, the abstract Collator class's getInstance() method returns a collation object that is appropriate for the default locale, as determined by java.util.Locale.getDefault():
  • Like other locale-sensitive classes, you can use the static factory method, getInstance, to obtain the appropriate Collator object for a given locale. 
  • The following example shows how to compare two strings using the Collator for the default locale.
  • Compare two strings in the default locale
    • Collator myCollator = Collator.getInstance();
    • if( myCollator.compare("abc", "ABC") < 0 )
    • System.out.println("abc is less than ABC");
    • else
    • System.out.println("abc is greater than or equal to ABC");

Singleton Pattern

Lazy Initialization:-The instantiation of an object can be delayed until it is actually needed.

Usage: This especially beneficial when the constructor is doing a costly job like, accessing a remote database.

Example:

This code demonstrates how the Singleton pattern can be used to create a counter to provide unique sequential numbers, such as might be required for use as primary keys in a

Database:


 

Sequence.java


 

public class Sequence {

private static Sequence instance;

private static int counter;

private Sequence()

{

counter = 0; // May be necessary to obtain

// starting value elsewhere...

}

public static synchronized Sequence getInstance()

{

if(instance==null) // Lazy instantiation

{

instance = new Sequence();

}

return instance;

}

public static synchronized int getNext()

{

return ++counter;

}

}


 

Some things to note about this implementation:

  • Synchronized methods are used to ensure that the class is thread-safe.
  • This class cannot be subclassed because the constructor is private. This may or may not be a good thing depending on the resource being protected. To allow subclassing, the visibility of the constructor should be changed to protected.
  • Object serialization can cause problems; if a Singleton is serialized and then deserialized more than once, there will be multiple objects and not a singleton

Design Patterns (TID)


  • The pattern is an organised way of solving some specific class of problems.
  • These patterns come in to the picture at analysis and high-level-design phase.
  • The first step of applying one pattern to the code base is first to understand the find the vector of change in the code base.
  • Next step is to isolate the things that are subject to change form the things that are not.
  • That is adding a layer of abstraction to the code.
  • The goal of design patterns is isolating the changes in your code.
  • Understand Inheritance and Composition as a solution to a specific class of problems.
    • Inheritance: - It allows you to express differences in behavior (that's the thing that changes) in objects that all have the same interface (that's what stays the same).
    • Composition: - Composition can also be considered a pattern, since it allows you to change—dynamically or statically—the objects that implement your class, and thus the way that class works.
  • Some principles of designing the code:
    • Principle of least astonishment
    • Make common things easy and rare things possible
    • Consistency: -
      the more random rules you pile onto the programmer, rules that have nothing to do with solving the problem at hand, the slower the programmer can produce.
    • Law of Demeter: - "Don't talk to strangers." An object should only reference itself, its attributes, and the arguments of its methods.
    • Make the solution to be the most Simple.
    • One abstraction per class, one class per abstraction. Might also be called Isomorphism.
    • Independence or Orthogonality. Express independent ideas independently. This complements Separation, Encapsulation and Variation, and is part of the Low-Coupling-High-Cohesion message.
    • Once and once only: Avoid duplication of logic and structure where the duplication is not accidental, ie where both pieces of code express the same intent for the same reason.
  • Classifying Patterns
    • Creational: - how an object can be created. This often involves isolating the details of object creation so your code isn't dependent on what types of objects there are and thus doesn't have to be changed when you add a new type of object. The aforementioned Singleton is classified as a creational pattern, and later in this book you'll see examples of Factory Method and Prototype.
    • Structural: designing objects to satisfy particular project constraints. These works with the way objects are connected with other objects to ensure that changes in the system don't require changes to those connections.
    • Behavioral: objects that handle particular types of actions within a program. These encapsulate processes that you want to perform, such as interpreting a language, fulfilling a request, moving through a sequence (as in an iterator), or implementing an algorithm. This book contains examples of the Observer and the Visitor patterns.
  • It is required to classify the patterns in those categories so that we come across a specific type of problem then they help us to provide a solution.
  • Some basics to be kept in mind during coding.
    • Use a Class as messenger so that u can pass the bunch as a package. Make it public so that all can access.
    • Still to understand…
      Collecting Parameter
  • Object Pool pattern: -
    • An object pool is a set of initialised objects that are kept ready to use rather than allocated or 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. It is a specific type of factory object.
    • The case where it should be used: - Object pooling can offer a significant performance boost in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high, and the number of instances in use at any one time is low.
  • Singleton Pattern : -
    • Possibly the simplest design pattern is the singleton, which is a way to provide one and only one object of a particular type.  An important aspect of Singleton is that you provide a global access point, so singletons are often a solution for what you would have used a global variable for in C.
    • Singletons can be found in java library.
    • The Code Example:
      //: singleton: SingletonPattern.java
      // The Singleton design pattern: you can
      // never instantiate more than one.
      package singleton;
      import junit.framework.*;


      // Since this isn't inherited from a Cloneable
      // base class and cloneability isn't added,
      // making it final prevents cloneability from
      // being added through inheritance:


      final class Singleton {
        private static Singleton s = new Singleton(47);
      //Static as no duplicates are allowed for static methods and vars
        private int i;
        private Singleton(int x) { i = x; }


      //The method is static because it is accessing the static parameter so it has to be static to access it.
        public static Singleton getReference() {
          return s;
        }
        public int getValue() { return i; }
        public void setValue(int x) { i = x; }
      }


      public class SingletonPattern extends TestCase {
        public void test() {
      //This is possible because static methods can be called even without
      //object references
          Singleton s = Singleton.getReference();
          String result = "" + s.getValue();
          System.out.println(result);
          assertEquals(result, "47");
          Singleton s2 = Singleton.getReference();
          s2.setValue(9);
          result = "" + s.getValue();
          System.out.println(result);
          assertEquals(result, "9");
          try {
            // Can't do this: compile-time error.
            // Singleton s3 = (Singleton)s2.clone();
          } catch(Exception e) {
            throw new RuntimeException(e);
          }
        }
        public static void main(String[] args) {
          junit.textui.TestRunner.run(SingletonPattern.class);
        }
      } ///:~