Ask Google

Custom Search

Monday, October 17, 2011

What is Java inheritence and composition

Composition vs. Inheritance in Java.

When Introduced to Object Orientation I was very excited about inheritance and class hierarchies and what I could do with them. Over time, I've come to focus more on interfaces and (in general) use composition rather than inheritance.

Inheritance in java is super easy. If we want to build, for instance, a case-insensitive HashMap how would we do it? (I chose HashMap because it shows the good, the bad, and the ugly of each approach, while remaining trivial). With Inheritance it's pretty easy. We simply extend HashMap and override the methods dealing with keys:

import java.util.HashMap;

public class NoCaseHashMap extends HashMap {

    private String toKey(Object key) {
        if (key == null) {
            return null;
        }
        return key.toString().toLowerCase();
    }

    public Object get(Object key) {
        return super.get(toKey(key));
    }

    public Object put(Object key, Object value) {
        return super.put(toKey(key), value);
    }

    public boolean containsKey(Object key) {
        return super.containsKey(toKey(key));
    }

    public Object remove(Object key) {
        return super.remove(toKey(key));
    }

}

Ta-da! Done.

But, the first downside to this approach is that, in Java, we may only inherit implementation (extend) from one superclass. There are times when that seems constrictive. In this simple case that is no big deal.

The less obvious downside of Inheritance is that we've locked this into a particular Map implementation. What happens when we want a LinkedHashMap or a WeakHashMap or even a TreeMap? Early binding to a particular implementation is Inheritance's biggest shortcoming.

Enter Composition.

With Composition we can late bind to the implementation. Rather than extend HashMap, we could, for instance, take a Map object as a construction parameter and leave the implementation choice open.

The first obvious down-side to Composition is that it is not as light-weight in Java. Every method must be added, not just the ones that change.

The second, less obvious, downside is that with inheritance super classes can call the methods of the sub-class, but this is not so with composition.

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class NoCaseMap implements Map {

    private Map map;

    public NoCaseMap(Map map) {
        this.map = map;
    }

    private String toKey(Object key) {
        if (key == null) {
            return null;
        }
        return key.toString().toLowerCase();
    }

    public Object get(Object key) {
        return map.get(toKey(key));
    }

    public Object put(Object key, Object value) {
        return map.put(toKey(key), value);
    }

    public boolean containsKey(Object key) {
        return map.containsKey(toKey(key));
    }

    public Object remove(Object key) {
        return map.remove(toKey(key));
    }

    /* Note the need to implement putAll(map) with composition */
    public void putAll(Map t) {
        for (Iterator it = t.entrySet().iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            put(entry.getKey(), entry.getValue());
        }
    }

    // --------------------------------------
    // The rest of these are just the standard cruft of composition:
    // --------------------------------------
    public void clear() {
        map.clear();
    }

    public boolean containsValue(Object value) {
        return map.containsValue(value);
    }

    public Set entrySet() {
        return map.entrySet();
    }

    public boolean isEmpty() {
        return map.isEmpty();
    }

    public Set keySet() {
        return map.keySet();
    }

    public int size() {
        return map.size();
    }

    public Collection values() {
        return map.values();
    }
}

More code (even if it was auto-generated) obviously, but also plug-able and flexible.
When to use Inheritance and when to use Composition?

Traditionally, we are told to use inhertance when one class has an "is a" relationship with another, and composition when one class has a "has a" relationship with another. While I do not dispute this in the slightest, I will warn that this is trickier than it sounds. We've pobably all seen the bad textbook example of something like "Programmer" and "Manager" as extending "Employee" ... well, maybe ... but perhaps it is more useful to think of "Programmer" as a set of duties that an "Employee" may have, and this same employee may later change duties for "Manager" duties. Often "is a" and "has a" relationships are more arbitrary than they might first appear. If "is a" and "has a" relationsips are just a matter of perspective, what should we do?

As a rule of thumb:

    * Use composition (not inheritance) to get code re-use and/or polymorphism. as Bill Venners suggests (JavaWorld.com, 11/01/98)
    * Use inheritance when super-classes must significantly interact with their sub-classes. (But consider Strategy pattern instead.)
    * Use inheritance when we are forced to.

If the "parent" must call back to "child" methods, then Inheritance is usually the only good answer. However, in general, the late-binding aspect of Composition tends to be better, even with the added irritation of the the pass-through methods. What are the relationships between the classes? Is one the abstract "brains" and the other provided a strategy for some internal functionality? Or is one a "Decorator" of another where composition is obvious? Like:

    new BASE64EncoderStream(new BufferedOutputStream(new FileOutputStream(file)))

I used to see problems mostly in terms of super and sub-classes. These days most problems look better solved with composition. And if it weren't for the heavier weight of composition, I'd probably use it nearly exclusively, except for when inheritance was the really obvious winner.

If intermediate classes get introduced into the heirarchy that are hard to name, it may be a good idea to consider composition; if the names don't make a lot of sense, that's probably a hint that we should be thinking harder about our design, anyway. Usually I see this happening as we try to push common code into some super-class, but that superclass doesn't actually represent any particular general concept.

There are also times when we are forced to use inheritance becuase some method expects a concrete class as a parameter, not an interface. The core java language is full of examples where implementations are expected which could be interfaces: java.io.Writer and java.io.File jump to mind.

When I see that I am forcing extenders to use inheritance, I take this as a sign that I should think hard about the architecture; in general it has turned out to be symptom of inferior design. As a rule of thumb, I try to design for interfaces and plug-ability, not sub-classing.

There are many ways of re-thinking towards plugability. Sometimes it is just a matter of using interfaces and having a default implementation. Sometimes it is a matter of thinking about the problem from the other direction: for instance, rather than having an abstract super-class which expects a concrete sub-class to implement a function or two, we can create a concrete class which expects a collaborator object to implement those functions (the "Strategy" pattern ). With understanding of just the "Strategy" and "Decorator" patterns it becomes possible to imagine completely designing for plugability without using inheritance at all.

When in doubt, I try to let testing be my guide, because testing tends to be the first place where I find myself wanting plug-ability. For instance, if a "base class" requires a lot of set-up and tear-down to instantiate and test, and a "sub-class" is adding something which doesn't directly interact with the elements that require set-up and tear-down, this may be a hint that we could restructure to use composition and test the add-on behavior in isolation more easily.

Sunday, October 16, 2011

What is Store Procedure?

Stored routines (procedures and functions) are supported in any SQL programming. A stored routine is a set of SQL statements that can be stored in the server. Once this has been done, clients don't need to keep reissuing the individual statements but can refer to the stored routine instead.

Stored routines require the proc table in the sql database. This table is created using procedure. I
Stored routines can be particularly useful in certain situations:

    *      When multiple client applications are written in different languages or work on different platforms, but need to perform the same database operations.
    *      When security is paramount. Banks, for example, use stored procedures and functions for all common operations. This provides a consistent and secure environment, and routines can ensure that each operation is properly logged. In such a setup, applications and users would have no access to the database tables directly, but can only execute specific stored routines.

Stored routines can provide improved performance because less information needs to be sent between the server and the client. The tradeoff is that this does increase the load on the database server because more of the work is done on the server side and less is done on the client (application) side. Consider this if many client machines (such as Web servers) are serviced by only one or a few database servers.

Stored routines also enable you to have libraries of functions in the database server. This is a feature shared by modern application languages that enable such design internally (for example, by using classes). Using these client application language features is beneficial for the programmer even outside the scope of database use.

The SQL implementation of stored routines is still in progress. All syntax described here is supported and any limitations and extensions are documented where appropriate.

5L15K

  © Blogger template The Beach by Ourblogtemplates.com 2009

Back to TOP