Sunday, November 18, 2012

UML Class Diagram Relationships, Aggregation, Composition

There are five key relationships between classes in a UML class diagram : dependency, aggregation, composition, inheritance and realization. These five relationships are depicted in the following diagram:

UML Class Relationships
The above relationships are read as follows:
  • Dependency : class A uses class B
  • Aggregation : class A has a class B
  • Composition : class A owns a class B
  • Inheritance : class B is a Class A  (or class A is extended by class B)
  • Realization : class B realizes Class A (or class A is realized by class B)
What I hope to show here is how these relationships would manifest themselves in Java so we can better understand what these relationships mean and how/when to use each one.

Dependency is represented when a reference to one class is passed in as a method parameter to another class. For example, an instance of class B is passed in to a method of class A:  
public class A {

    public void doSomething(B b) {

Now, if class A stored the reference to class B for later use we would have a different relationship called Aggregation. A more common and more obvious example of Aggregation would be via setter injection:
public class A {

    private B _b;

    public void setB(B b) { _b = b; }

Aggregation is the weaker form of object containment (one object contains other objects). The stronger form is called Composition. In Composition the containing object is responsible for the creation and life cycle of the contained object (either directly or indirectly). Following are a few examples of Composition. First, via member initialization:
public class A {

    private B _b = new B();

Second, via constructor initialization:

public class A {

    private B _b;

    public A() {
        _b = new B();
    } // default constructor

Third, via lazy init (example revised 02 Mar 2014 to completely hide reference to B):

public class A {

    private B _b;

    public void doSomethingUniqueToB() {
        if (null == _b) {
            _b = new B();
        }
        return _b.doSomething();
    } // doSomethingUniqueToB()

Inheritance is a fairly straightforward relationship to depict in Java:

public class A {

    ...

} // class A

public class B extends A {

    ....

} // class B


Realization is also straighforward in Java and deals with implementing an interface:

public interface A {

    ...

} // interface A

public class B implements A {

    ...

} // class B

Note: (added 3/2/14 in response to comments) Let me point out that in the above composition examples 'new' could be replaced with a factory pattern as long as the factory does not return the exact same instance to any two different containing/calling objects, which would violate the key tenet of composition which is that the aggregated objects do not participate in a shared aggregation (two different container objects sharing the same component part object). The builder pattern could also be used as long as the distinct 'parts' are not injected into more than one containing object.

6/29/2014 - here's a good article on class diagrams and answers Ivan's question below in the comments:

http://www.ibm.com/developerworks/rational/library/content/RationalEdge/sep04/bell/

Tuesday, October 9, 2012

ActiveMQ Producer Flow Control Send Timeout

ActiveMQ has a feature called Producer Flow Control that throttles back message producers when it detects that broker resources are running low.  In fact, it will block threads sending messages until resources become available.

You can configure the broker to timeout the message send so that it does not block when producer flow control is in effect, but this is a global setting and you cannot configure it per queue.

However, the ActiveMQConnection class has a setSendTimeout() method, but it is not exposed via the JMS connection interface.  There are a couple of ways to handle this.

First, you could simply cast your connection object to an ActiveMQConnection and then call the setSendTimeout method directly.  This works fine if you know for sure your implementation is ActiveMQ and you have access to the ActiveMQ libraries at compile time (in other words, you don't mind having this dependency in your messaging client).

try {
    // Create a ConnectionFactory
    ActiveMQConnectionFactory connectionFactory
        = new ActiveMQConnectionFactory("tcp://localhost:61616");

    QueueConnection connection = connectionFactory.createQueueConnection();
    ((ActiveMQConnection)connection).setSendTimeout(5000);
    ...

A second way to handle this would be to use Java reflection to dynamically invoke the setSendTimeout() method if it is available, like so:

try {
    ...

    QueueConnection connection = connectionFactory.createQueueConnection();

    try {
        Method setSendTimeout = connection.getClass().getMethod(
            "setSendTimeout",
            int.class
        );
        if (null != setSendTimeout) {
            setSendTimeout.invoke(connection, 5000);
        }
    } catch (Exception e) {
        System.out.println("could not invoke the setSendTimeoutMethod"); 
    }
    ...

With this approach, you can configure send timeouts per connection and you can be somewhat JMS provider agnostic in your client. Keep in mind that if you use a container to provide your JMS connection factory the connections you get back may not be ActiveMQ connections, but rather proxy objects that wrap an ActiveMQ connection.

Friday, September 28, 2012

Project Management, Agile and the Replacement Refs

An article I read this morning mentioned that now that the regular NFL refs are back on the job the referees have faded into the background and the game itself has taken center stage again.  Relative calm and order have been restored and fans, players and coaches can focus on the product (football) and not the administration of it.

I got to thinking about it and I realized how much that applied to project management on agile projects (I'm referring to organizations, like mine, that are project management centric, rooted in waterfall methodologies, and trying to implement scrum in a move toward agile).

Traditional project management on agile projects, where the focus is primarily on schedules, timelines, budgets, status meetings, resources, timekeeping, etc. etc. is akin to replacement refs in a professional football game - the management of the project is too visible and steals center stage.

So, bring back the regular refs and restore the integrity of agile by making the product itself the center of attention, surrounded by the team member collaborations and customer interactions that comprise the real game of agile and let project management quietly fade into the background where it can unobtrusively maintain calm and order.

Disclaimer: I think the replacement refs were put in a tough position where limited training, high expectations and the speed of the game made their ability to succeed a tough proposition from the very outset. I think the same can be said of traditional project managers on agile projects.

Friday, August 31, 2012

slf4j5 - Java logging even faster

In my previous posting where I introduced slf4j5 I reported that, to my surprise, performance was better than when using slf4j by itself - probably due to the usage of the Java 5 String formatter.

Inspired by this I took a closer look at performance and ended up creating a dedicated thread in each logger for doing the actual logging work (i/o). This resulted in more than a 50% improvement over slf4j5 without the dedicated thread. This has the added benefit of providing for non-blocking logging in a multi-threaded environment.

Get the code here: http://code.google.com/p/slf4j5/

Tuesday, August 21, 2012

Introducing slf4j5 - logging, varargs, String.format, faster

I was recently investigating some of the Java logging frameworks out there and really like the flexibility/abstraction layer that slf4j provides and decided to give it a try with the logback logging implementation, which is apparently the successor to log4j.

I noticed that slf4j has its own formatter built into the logging api calls for assembling parameterized strings. However, what I didn't realize is that it only accepted a maximum of 2 parameters.  Bummer.  What happened to varargs?  Turns out slf4j doesn't support Java 5 yet and it didn't sound like it was going to anytime soon.

So, I wrote a simple Java 5 wrapper around slf4j and, except for the Java 5 string formatting, you use it just like you would slf4j.  You can find it here (I'm hoping the slf4j folks will take it on as a subproject - if so, I'll update the link):

http://code.google.com/p/slf4j5/

I figured since I was adding a small layer on top of slf4j that there would be a performance penalty.  It would stand to reason, but I wanted to know how much overhead I was adding to slf4j so I wrote some tests to measure it.   I was so surprised by the results that I ran the tests over and over and reviewed the code and tweaked the tests until I convinced myself what I was seeing was actually true - the slf4j5 wrapper was actually faster than using slf4j by itself (with logback, of course).

But, how could that be? My guess is that it's primarily due to the use of String.format() rather than the custom formatter used in slf4j.

Here were the results:
In addition, I also enhanced the context-awareness to automatically log the class, method and line from which the logging call originated.

On a similar note, using this auto-detection strategy, you don't need to specify a class or a name when obtaining your logger.  For example:

LoggerFactory.getLogger() will obtain a logger for the class wherein this statement is contained.

So, varargs, advanced formatting, faster performance, auto-context detection - several good reasons to take it out for a test drive.

I will be working on the wiki, but here's an example:

public class MyClass { 

    private final Logger _log = LoggerFactory.getLogger();

    public void doSomething(int param1, String param2, double param3) { 
        _log.debug(“entering, params = %d, %s, %8.2f”, param1, param2, param3);
        
        // some useful business logic here
      
        _log.debug(“leaving”);
    } // doSomething()

    ...

The above logging statements would result in something like the following in the log file:

2012-08-22 07:33:22.543 DEBUG [main] [MyClass.doSomething():6] entering, params = 100, hello, 500.00
2012-08-22 07:33:23.618 DEBUG [main] [MyClass.doSomething():10] leaving

Let me know how it goes.

Saturday, January 7, 2012