On 3/1/06, Emmanuel Bourg <[EMAIL PROTECTED]> wrote:
>
> Boris Unckel wrote:
> > Hello,
> >
> > Simon Kitching wrote:
> >> == LogFactory as factory for Log instances
> >>
> >> Currently, JCL uses a LogFactory to create Log instances:
> >>   Log log = LogFactory.getLog("fff");
> >>
> >> By contrast, Log4j has the factory method on the Log class:
> >>   Logger log = Logger.getLog("fff");
> >>
> >> Having one less class is a *little* nicer for users I think. However it
> >> does reduce the flexibility of the system a little and changing this is
> >> a major difference from JCL 1.x.
> >>
> >> My choice would be: keep LogFactory and LogFactory.getLog as the
> >> mechanism for obtaining Log instances.
> > There is one really big advantage of the current API in this case:
> > If you want to have Logger.getLog("fff") Logger must be a class,
> > currently it is an interface.
> > Please do not switch from an interface to an class, since it is
> > impossible to provide a native
> > implementation of JCL2 without an interface.
>
> It's possible to keep a Log interface and having one less class to
> import by adding a static class in the Log interface. It would look like
> this:
>
>      Log log = Log.Factory.getLog("foo");
>
> I don't expect everyone to like it ;) I personally prefer the
> Log4j/JDK1.4 syntax.


I presume this would be implemented by making "Factory" a static variable?
That doesn't offer much protection against malicious applications trying to
replace it and potentially messing up other users.

The place where we botched LogFactory most in 1.0 was that there's too much
logic in the static method, and you cannot easily provide your own factory
implementation that might operate differently.  In Commons Chain, which has
a similar need for a pluggable factory, we followed a pattern like this:

    public abstract class CatalogFactory {

        // Return the configured instance of the factory to use for this app
        public static CatalogFactory getInstance();

    }

where the actual instance returned by getInstance() is configured by some
suitable discovery mechanism.

Translating this to LogFactory terminology, it might look like:

    public abstract class LogFactory {

        public static LogFactory getInstance();

    }

and you would want users to call:

    Log log = LogFactory.getInstance().getLog("...");

but to maintain reasonable backwards compatibility, you could also implement
getLog() in LogFactory like this:

    public static Log getLog(String name) {
        return getInstance().getLog(name);
    }

(and similarly for the version that takes a Class).

The tricky bit is still in how you configure the instance to be returned by
LogFactory.getInstance(), but at least we could provide a pluggability point
for containers that wanted to do something special.

Craig

Emmanuel Bourg
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>

Reply via email to