Ok, I'm hearing a lot of conflicting ideas here. So I'm going to shelve my 
changes for now (I'm just glad that I had only finished the code, and not the 
tests), stop progress on the issue, and mark it for a later version, unless 
someone things we should move forward with this.

I'm a smidge disappointed, mostly because I was really proud of how I designed 
it :-), but I won't be using it personally so I'm not that invested.

Nick

On Jul 29, 2013, at 8:14 PM, Gary Gregory wrote:

> I thought about this a little more in the context of avoiding Logger becoming 
> a kitchen sink.
> 
> This is today already a mini-leak in toward kitchen sink-ness due to the 
> (good IMO) addition of the printf APIs.
> 
> The way I see it, if I am a 'classic' programmer, I will not use the fluent 
> API, and vice-versa, if I am a fluent programmer, I'll use the fluent API and 
> not the standard API.
> 
> So why should both crowd the same interface. In fact why should all THREE 
> (fluent, standard, and printf) be in the same interface.
> 
> I like the LogManager.get<Style>Logger approach proposed earlier.
> 
> If I am a fluent programmer, then I call getFluentLogger() and I get a clean 
> fluent API sans extra stuff.
> 
> If I am a classic programmer, then I call getLogger() and I get a clean 
> standard API sans extra fluent stuff.
> 
> Whether or not we want a getPrintfLogger() I know not yet, but I think it 
> worth mentioning.
> 
> Logger can even implement toFluentLogger(), toLogger() and toPrintfLogger().
> 
> Having separate interfaces lets you have your fluent API without crowding the 
> standard API.
> 
> Thoughts,
> Gary
> 
> 
> 
> On Mon, Jul 29, 2013 at 7:57 PM, Remko Popma <[email protected]> wrote:
> It is unfortunate that you've already put a lot of work into this.
> For me, I am firmly in the "don't do this" camp. (Sorry Nick)
> 
> I think a fluent interface would add unnecessary complexity that does not add 
> any value. 
> We currently have a single method call that does a bunch of work.
> IMO, splitting up that work to make it "look fluent" is not what fluent is 
> about. Fluent is more than just a coding style, it should simplify and remove 
> clutter.
> 
> The canonical example uses fluent correctly, *to reduce complexity*:
> {code}
>     private void makeNormal(Customer customer) {
>         Order o1 = new Order();
>         customer.addOrder(o1);
>         OrderLine line1 = new OrderLine(6, Product.find("TAL"));
>         o1.addLine(line1);
>         OrderLine line2 = new OrderLine(5, Product.find("HPK"));
>         o1.addLine(line2);
>         OrderLine line3 = new OrderLine(3, Product.find("LGV"));
>         o1.addLine(line3);
>         line2.setSkippable(true);
>         o1.setRush(true);
>     }
> {code}
> 
> After:
> {code}
>    private void makeFluent(Customer customer) {
>         customer.newOrder()
>                 .with(6, "TAL")
>                 .with(5, "HPK").skippable()
>                 .with(3, "LGV")
>                 .priorityRush(); 
>     }
> 
> {code}
> 
> In the above example a fluent interface adds value because it allows many 
> objects to cooperate and it removes clutter.
> But I would argue that we don't have any clutter that needs removing.
> 
> Remko 
> 
> From: Nick Williams <[email protected]>
> 
> To: Log4J Developers List <[email protected]> 
> Sent: Tuesday, July 30, 2013 8:08 AM
> 
> Subject: Re: LOG4J2-242 (Fluent Logging)
> 
> Well that's unfortunate. I just finished it. :-( Haven't committed it yet...
> 
> I'm not sure what the advantage is to delaying it to 2.1. Is it just to study 
> it further? I understand "do it" and "don't do it," but I don't understand 
> "do it later."
> 
> I've heard a few "I don't like it fluent" and "I didn't understand how it's 
> better" assertions, and I think that's missing the point. I don't have a 
> particular fondness for fluent APIs, but some people use a different 
> programming style and prefer them. Just because person A doesn't like or 
> understand how fluent is better, doesn't mean that person B doesn't like or 
> understand how fluent is better. Person B might like fluent so much they 
> write their own logging API wrapper around ours. Person B might not be able 
> to wrap their head around non-fluent APIs for one reason or another.
> 
> Is there a major difference between these two lines of code?
> 
> logger.error("This is a message with {} arguments {}.", arg1, arg2, 
> throwable);
> logger.error().message("This is a message with {} 
> arguments{}.").arguments(arg1, arg2).exception(throwable);
> 
> No, no real difference. However, I /can/ see how it's more obvious that 
> throwable is an /exception/ and not an /argument to the message/. And while I 
> would probably, personally, use the first line, I can certainly understand 
> how someone might prefer the second line.
> 
> We're not talking about changing the existing API methods. We're talking 
> about adding API methods to support this different style of programming that 
> some people prefer. If, after all, our goal is to further adoption of Log4j, 
> wouldn't it make sense to offer something like this that many people use, 
> even if we ourselves aren't familiar with it or don't prefer it?
> 
> My $0.02.
> 
> N
> 
> On Jul 29, 2013, at 5:52 PM, Paul Benedict wrote:
> 
>> Whoever said this is a 2.1 feature, I concur.
>> 
>> 
>> On Mon, Jul 29, 2013 at 5:45 PM, Ralph Goers <[email protected]> 
>> wrote:
>> I actually started to work on this myself several weeks ago and came to the 
>> conclusion that I just couldn't grasp how it is better - with one exception. 
>> You can reuse the MessageBuilder and replace the message or arguments, etc. 
>> But that seems dangerous as it wouldn't be thread safe.
>> 
>> Ralph
>> 
>> On Jul 29, 2013, at 1:48 PM, Gary Gregory wrote:
>> 
>>> On Mon, Jul 29, 2013 at 4:39 PM, Nick Williams 
>>> <[email protected]> wrote:
>>> I'm working on LOG4J2-242 to add the ability to log fluently. It's going to 
>>> work something like this:
>>> 
>>> interface Logger:
>>>     + MessageBuilder trace();
>>>     + MessageBuilder debug();
>>>     + MessageBuilder info();
>>>     + MessageBuilder warn();
>>>     + MessageBuilder error();
>>>     + MessageBuilder fatal();
>>>     + MessageBuilder log(Level);
>>> 
>>> + interface MessageBuilder:
>>>     message(String);
>>>     message(Object);
>>>     message(String, Object...);
>>>     marker(Marker);
>>>     exception(Throwable);
>>>     argument(Object);
>>>     arguments(Object...);
>>>     log();
>>> 
>>> Bruce (the requester) had suggested adding the methods that return 
>>> MessageBuilder to a different interface (as opposed to Logger) to keep from 
>>> cluttering the Logger API. The way I see it our options are:
>>> 
>>> - Create a FluentLogger interface to house these methods. I don't like this 
>>> option because A) it complicates things significantly, B) it makes users 
>>> have to call a different method on LogManager (getFluentLogger) to get a 
>>> FluentLogger, and C) it means users have to have a Logger and a 
>>> FluentLogger if they want to use both APIs.
>>> 
>>> - Create a FluentLogger interface that extends Logger. This option is much 
>>> better. It avoids cluttering the Logger API if that's all someone wants to 
>>> use, it doesn't require someone to have a Logger and FluentLogger if they 
>>> want to use both APIs, and it doesn't complicate the implementation 
>>> significantly (all implementations can just implement FluentLogger). It 
>>> does still mean LogManager (and related classes/interfaces) need getLogger 
>>> and getFluentLogger methods, which I don't necessarily like.
>>> 
>>> - Just add these methods to Logger, which is what I intended to do from the 
>>> get-go and is what I still think is the best option.
>>> 
>>>  - and there's option 4: Don't do it.
>>> 
>>> At first glance, adding these methods to Logger looks confusing and 
>>> cluttered. The less messy solution seems to me FLogger extends Logger.
>>> 
>>> Gary
>>>  
>>> 
>>> I'm going to proceed with #3 for now, but if someone has a strong opinion 
>>> otherwise please voice it so that we can discuss before I complete this.
>>> 
>>> Nick
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [email protected]
>>> For additional commands, e-mail: [email protected]
>>> 
>>> 
>>> 
>>> 
>>> -- 
>>> E-Mail: [email protected] | [email protected] 
>>> Java Persistence with Hibernate, Second Edition
>>> JUnit in Action, Second Edition
>>> Spring Batch in Action
>>> Blog: http://garygregory.wordpress.com 
>>> Home: http://garygregory.com/
>>> Tweet! http://twitter.com/GaryGregory
>> 
>> 
>> 
>> 
>> -- 
>> Cheers,
>> Paul
> 
> 
> 
> 
> 
> 
> -- 
> E-Mail: [email protected] | [email protected] 
> Java Persistence with Hibernate, Second Edition
> JUnit in Action, Second Edition
> Spring Batch in Action
> Blog: http://garygregory.wordpress.com 
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory

Reply via email to