+1 for ConfigurationBuilder

-- Denis.
  Original Message  
From: Daniel Dekany
Sent: Wednesday, 15 February 2017 10:49
To: Woonsan Ko
Reply To: dev@freemarker.incubator.apache.org
Subject: [FM3] Configuration mutability (Was: [FM3] Configuration API 
simplification)

Wednesday, February 15, 2017, 12:16:12 AM, Woonsan Ko wrote:

> Also, if possible, I would like to have an immutable object or
> representation than the Configuration itself. For example,
> template#getConfiguration doesn't have to return a mutable object, for
> instance. But it requires a bigger change, I guess.

A good point, that's the totally correct way of doing things. So we
could have a mutable Configuration.Builder, which yields an immutable
Configuration. We also have some ObjectWrapper, which is a bean in
itself, but is also part of the Configuration. We certainly will have
another such "injected bean", the TemplateResolver, and maybe some
more on long term. Those also could follow this pattern (i.e, being
immutable and only offer a builder).

Question is, what extra pain that means for the average user. Like
then in Spring XML you have to create a factory bean from Xxx.Builder,
and then create yet another bean with factory-bean and factory-method
attribute (because for some reason javax.annotation doesn't have
anything like Spring FactoryBean, and freemarker-core can't depend on
Spring obviously). Or, we can subclass all builders in something like
freemarker-spring, to create a FactoryBean version of them, and then
tell people to (a) pull in the depednecy and (b) use those classes
instead of those shown in the core JavaDoc and in the Manual
examples... So it's not very streamlined. If you have traditional
beans, it's simpler for the users (especially if they don't have a
PostConstruct either). Note sure which compromise is the winner.

If Configuration (and the others) remains a bean, I want to throw an
IllegalStateException if a the object were already "used" (like
template processing was already invoked), and then someone calls
cfg.setXxx(value). In FM2 we say that if you do that from multiple
threads, then it won't work correctly, but we allow changing the
Configuration at any time if you are only using it from the same
thread. That's a possibility I want to remove, even if we don't switch
to builders.

Oh, and yet another complication with builders... If Configuration is
immutable, then it only will have getters, no setters. But,
Environment is mutable with setters, and it should be. Both
Configuration and Environment extends Configurable. So it seems now we
should split that class into a getters-only class and a subclass that
adds setters... (That might will be necessary because that Template is
mutable with setters is not all right either. Or we can just throw
IllegalStateException there too.)

-- 
Thanks,
Daniel Dekany

Reply via email to