Alex Rivera | Logout

Java inheritance, using builder pattern

Asked 2011-03-18T00:02:54.700
10

I have 3 classes:

  1. Error
  2. ShellError
  3. WebError

where

ShellError extends Error 

and

WebError extends Error

In ShellError there are fields some of which are optional and others are required. I am building the object in the following manner:

shellError = new ShellError.Builder().setFile(filePattern)
.setHost(host).setPath(path).setSource(file.isSource())
.setJobName(p.getJobName()).build();

Since ShellError extends Error, I further:

shellError.setDescription(msg.toString());
shellError.setExceptionClass("MyEvilException");
shellError.setExceptionMessage("Some clever error message");
shellError.setStacktrace(stack);

So ... why bother with Builder? I like the fact that my build() amongst other things conveniently validates that all fields are set appropriately etc.

I would love it if I could .. build() ShellError and add to it the fields from the Error class.

What i did works.

  • The question is:

Is there a better way, or does it make sense what I did?

-- EDIT

I updated Builder() to accept some of the parameters which were in Error class before. Now I have

shellError = new ShellError.Builder(exception, "Some description").setFile(filePattern).setHost(host)
.setPath(path).setSource(file.isSource()).
setJobName(p.getJobName()).build();

What do you say? Better? Worse?

Edit
Report

1 Answer

0

As it was already said, the builder pattern is not something that could organically fit into the existing Java object initialization politics. There are several approaches to achieve the required result. Though, of course, it is always better to avoid any ambiguous practices, it's not always possible. My hack is based on Java reflection API with generics:

abstract public class AbstractClass {

    public static class Builder {

        public <T extends AbstractClass> T build(Class<T> implementingClass) {
            try {
                Constructor<T> constructor = implementingClass
                        .getConstructor(new Class[]{Builder.class});
                return constructor.newInstance(this);
            } catch (NoSuchMethodException e) {
                // TODO handle the exception
            } catch (InvocationTargetException | InstantiationException |
                     IllegalAccessException  e) {
                // TODO handle the exception
            }
        }
    }

    protected AbstractClass(Builder builder) {

    }
}

public class ImplementingClass extends AbstractClass {

    public ImplementingClass (Builder builder) {
        super(builder);
    }
}

The initialization:

ImplementingClass instance = new AbstractClass.Builder()
                    .build(ImplementingClass.class);
answered 2013-06-13T20:35:35.963

Your Answer