Programmatic configuration is feature in that list of issues Ralph
mentioned. I don't see any good way to do that without using the fluent
builder pattern as that's how programmatic configuration APIs are usually
done. The other ways are usually things like closures/lambdas, but that
would require Java 1.8+ to work. Groovy supports closures which is what
makes Gradle so much less verbose, so that, too, is an alternative way to
support builders.

I guess the important thing to consider here is that the builders aren't
for _plugins_, but are for plugin _configurations_. That makes me think
that the factory methods (whether they be private or public) should be far
more generic such as accepting a PluginConfiguration object (each specific
to the plugin) or a generic Map<String, Object> that also makes it a lot
simpler to pass in plugin attributes.


On 16 June 2014 10:05, Gary Gregory <garydgreg...@gmail.com> wrote:

> Right, so they are not part of the public API, unless we consider
> programmatic configuration (not from a file).
>
> Gary
>
>
> On Mon, Jun 16, 2014 at 10:56 AM, Remko Popma <remko.po...@gmail.com>
> wrote:
>
>> Paul this is about the plugin factory methods that are called by the
>> PluginManager to turn a configuration text file into an object hierarchy
>> with Loggers, Appenders, etc.
>> It would be very rare for client code to call these methods directly.
>> Which is why they are primarily called from JUnit tests.
>>
>>
>> On Mon, Jun 16, 2014 at 11:45 PM, Paul Benedict <pbened...@apache.org>
>> wrote:
>>
>>> If this API is primarily for unit tests, then I don't care as much. I
>>> thought this was Public API. When it comes to Public API, I prefer to make
>>> it as friendly-to-read and maintainable as possible.
>>>
>>>
>>> Cheers,
>>> Paul
>>>
>>>
>>> On Mon, Jun 16, 2014 at 9:42 AM, Remko Popma <remko.po...@gmail.com>
>>> wrote:
>>>
>>>> About the validation, wasn't the argument that some of the current
>>>> JUnit tests look like this?
>>>> FileAppender.createAppender("true", "true", "true", "true", "true",
>>>> "true", "true", "4096", null, null, "false", null, null);
>>>>
>>>> So, null is fine here for at least four arguments.
>>>> So it is definitely possible to forget to call the
>>>> builder.setValue(value) method for those arguments
>>>>  - which is fine if your intention was to set null, but not if you
>>>> forgot to set some non-null value.
>>>>
>>>> The compiler validates that you have the right number of arguments for
>>>> free.
>>>> It is not possible for builders to provide the same guarantee unless
>>>> all arguments must be non-null.
>>>>
>>>> About the readability - and as Ralph pointed out this is readability in
>>>> JUnit code primarily - there are a number of ways to accomplish that.
>>>>
>>>>
>>>>
>>>> On Mon, Jun 16, 2014 at 11:27 PM, Ralph Goers <
>>>> ralph.go...@dslextreme.com> wrote:
>>>>
>>>>> That is pretty much what Matt implemented.  See the other arguments
>>>>> around this, the primary one being that the factory methods are normally
>>>>> invoked dynamically so you wouldn’t be looking at the code that calls 
>>>>> them.
>>>>>  They are primarily called in the open in unit tests.
>>>>>
>>>>> Ralph
>>>>>
>>>>> On Jun 16, 2014, at 6:49 AM, Paul Benedict <pbened...@apache.org>
>>>>> wrote:
>>>>>
>>>>> I don't know why the Spring link isn't working (try later) but this is
>>>>> how I think you guys can make the builder pattern better. Honestly, it's
>>>>> impossible to comprehend what the parameters mean just by looking at the
>>>>> code in the current form.
>>>>>
>>>>> Example returning a custom builder interface:
>>>>> FileAppender.builder()
>>>>>   .setPropertyX(true)
>>>>>   .setPropertyY(true)
>>>>>   .setPropertyZ(4096)
>>>>>   .setPropertyA(null)
>>>>>   .create();
>>>>>
>>>>> Paul
>>>>>
>>>>>
>>>>>
>>>>> Cheers,
>>>>> Paul
>>>>>
>>>>>
>>>>> On Mon, Jun 16, 2014 at 8:41 AM, Remko Popma <remko.po...@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> Matt,
>>>>>>
>>>>>> Ralph's argument (and I agree) was that we want only one way to do
>>>>>> plugins, either with a factory method or with a builder.
>>>>>>
>>>>>> Currently only two plugins use the new builder: PatternLayout and
>>>>>> HtmlLayout.
>>>>>> So we can either revert these two back to use a factory method, or we
>>>>>> can convert the remaining 147 uses of the factory method to builders.
>>>>>> That last option would mean writing the builders for those plugins,
>>>>>> and modifying all JUnit tests that currently use the factory methods.
>>>>>>
>>>>>> I agree with Ralph that converting all remaining 147 places to use
>>>>>> builders would take up a lot of our time and energy for very little gain.
>>>>>>
>>>>>> Matt, you mentioned that you could live with factory methods if there
>>>>>> was a better way to write JUnit tests than
>>>>>>  FileAppender.createAppender("true", "true", "true", "true", "true",
>>>>>> "true", "true", "4096", null, null, "false", null, null);
>>>>>>
>>>>>> I believe I've demonstrated several ways in which such JUnit test
>>>>>> code can be improved.
>>>>>> Are you okay with removing the builders and reverting back to the
>>>>>> factory methods?
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Mon, Jun 16, 2014 at 10:23 PM, Matt Sicker <boa...@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> I'm unable to load that page for some reason, but yes, using a
>>>>>>> factory method as such is really not extensible. If the factory method 
>>>>>>> took
>>>>>>> a Map or some sort of configuration object (which itself could use the
>>>>>>> fluent builder pattern), that would be less tightly coupled.
>>>>>>>
>>>>>>> Wouldn't it also make sense for the factory methods to be private or
>>>>>>> similar? That way they're only accessible through reflection.
>>>>>>>
>>>>>>>
>>>>>>> On Sunday, 15 June 2014, Paul Benedict <pbened...@apache.org> wrote:
>>>>>>>
>>>>>>>> You don't want factory methods that take umpteen arguments. That's
>>>>>>>> no way to make your builder extensible for future enhancements. 
>>>>>>>> Instead,
>>>>>>>> you want a builder object that has a fluent API.
>>>>>>>>
>>>>>>>>
>>>>>>>> http://docs.spring.io/spring/docs/3.2.8.RELEASE/javadoc-api/org/springframework/beans/factory/support/BeanDefinitionBuilder.html
>>>>>>>>
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>> Paul
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sun, Jun 15, 2014 at 10:04 PM, Ralph Goers <
>>>>>>>> ralph.go...@dslextreme.com> wrote:
>>>>>>>>
>>>>>>>> Matt,
>>>>>>>>
>>>>>>>> The only objection I have to builders is that there should only be
>>>>>>>> one way to configure plugins and I have neither the time or energy to
>>>>>>>> convert all plugins from factories to builders. With 130+ open issues I
>>>>>>>> think our time is better focused there instead of fixing something that
>>>>>>>> already works.
>>>>>>>>
>>>>>>>> And, FWIW, the only place you will see createAppender coded like
>>>>>>>> that is in unit tests and there are a bunch of ways to make that 
>>>>>>>> clearer.
>>>>>>>>
>>>>>>>> Ralph
>>>>>>>>
>>>>>>>> On Jun 15, 2014, at 7:19 PM, Matt Sicker <boa...@gmail.com> wrote:
>>>>>>>>
>>>>>>>> I'm really against using factory methods due to language
>>>>>>>> limitations in Java. You can't specify default values, for one. Two, 
>>>>>>>> the
>>>>>>>> more parameters a factory takes, the crazier the method is. Seriously, 
>>>>>>>> tell
>>>>>>>> me what this method is specifying:
>>>>>>>>
>>>>>>>> FileAppender.createAppender("true", "true", "true", "true", "true",
>>>>>>>> "true", "true", "4096", null, null, "false", null, null);
>>>>>>>>
>>>>>>>>
>>>>>>>> On 15 June 2014 21:05, Remko Popma <remko.po...@gmail.com> wrote:
>>>>>>>>
>>>>>>>> I'm fine with just the factory methods too.
>>>>>>>>
>>>>>>>> Sent from my iPhone
>>>>>>>>
>>>>>>>> On 2014/06/16, at 9:44, Scott Deboy <scott.de...@gmail.com> wrote:
>>>>>>>>
>>>>>>>> +1
>>>>>>>> On Jun 15, 2014 4:05 PM, "Ralph Goers" <ralph.go...@dslextreme.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>> Do we need the builders?  As I said, I prefer only one way for
>>>>>>>> creating plugins.
>>>>>>>>
>>>>>>>> Ralph
>>>>>>>>
>>>>>>>> On Jun 15, 2014, at 2:49 PM, Remko Popma <remko.po...@gmail.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>> I see. I agree that the original format is much nicer.
>>>>>>>>
>>>>>>>> Matt, do you think you can achieve this with the builders?
>>>>>>>>
>>>>>>>> Sent from my iPhone
>>>>>>>>
>>>>>>>> On 2014/06/16, at 1:29, Ralph Goers <ralph.go...@dslextreme.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>> While you improved some of the existing messages, you really didm’t
>>>>>>>> address what I wanted fixed. The previous debug logs would have had
>>>>>>>> messages similar to:
>>>>>>>>
>>>>>>>> Calling createLayout on class
>>>>>>>> org.apache.logging.log4j.core.layout.PatternLayout for element
>>>>>>>> PatternLayout with params(pattern="%d{HH:mm:ss.SSS} [%t] %-5level
>>>>>>>> %logger{36} - %msg%n",
>>>>>>>> Configuration(D:\rista\eclipsekws\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\log4j2.0-test\WEB-INF\classes\test-log4j.xml),
>>>>>>>> null, charset="null", alwaysWriteExceptions="null")
>>>>>>>>
>>>>>>>> Calling createAppender on class
>>>>>>>> org.apache.logging.log4j.core.appender.ConsoleAppender for element 
>>>>>>>> Console
>>>>>>>> with params(PatternLayout(%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} -
>>>>>>>> %msg%n), null, target="SYSTEM_OUT", name="console", follow="null",
>>>>>>>> ignoreExceptions="null")
>>>>>>>>
>>>>>>>> Calling createAppenderRef on class
>>>>>>>> org.apache.logging.log4j.core.config.AppenderRef for element 
>>>>>>>> appender-ref
>>>>>>>> with params(ref="console", level="null", null)
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Matt Sicker <boa...@gmail.com>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>
>
> --
> E-Mail: garydgreg...@gmail.com | ggreg...@apache.org
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>



-- 
Matt Sicker <boa...@gmail.com>

Reply via email to