Whimusical
Whimusical

Reputation: 6649

Dependency Injection and IoC practices in a inherently tight coupling design

What's the best practice when dealing with a situation like the following (simplified symbolic analogous case, not asking for a particular implementation solution):

Imagine I want to create a custom class that represents my physical Calendar at my office desktop. It can be translated in Java as a GregorianCalendar(myCustomZone).

So, I create a class such as:

 class MyOfficeCalendar extends GregorianCalendar{
   public MyOfficeCalendar(){
        super(new SimpleTimeZone(...));
   }
 }

In these cases, code reviewers would say that instantiation in the constructor is a bad idea. But if I inject the SimpleTimeZone dependency into the constructor this seems to me like error prone, since my dependency only should be instantiated in a desired way. I want the control at that scope, not exposing the possibility of erroneous injection. I mean, that certain instantiation is part of my caller class behaviour or paradigm. The definition of MyOfficeCalendar is precisely a GregorianCalendar working with this particular custom TimeZone instance.

So what is the best design usually in those cases?

Upvotes: 1

Views: 114

Answers (1)

René Link
René Link

Reputation: 51483

Introduce a builder to encapsulate the construction behavior. E.g.

public class MyOfficeCalendar extends GregorianCalendar{

    public static class Builder {

        private Integer rawOffset;


        public void setRawOffset(int rawOffset) {
            this.rawOffset = rawOffset;
        }

        public MyOfficeCalendar build(){
            TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");

            int effectiveRawOffset = tz.getRawOffset();
            if(rawOffset != null){
                effectiveRawOffset = rawOffset;
            }
            SimpleTimeZone simpleTimeZone = new SimpleTimeZone(effectiveRawOffset, tz.getID());
            return new MyOfficeCalendar(simpleTimeZone);
        }
    }

   private MyOfficeCalendar(SimpleTimeZone simpleTimeZone){
        super(simpleTimeZone);
   }
 }

Client code can only set a few SimpleTimeZone properties. How much it can set depends on your builder implementation.

The builder can be used as a factory bean in IoC Frameworks.

Upvotes: 1

Related Questions