On Tue, Jan 7, 2014 at 4:26 PM, John Hendrikx <hj...@xs4all.nl> wrote:

> On 7/01/2014 14:50, Tomas Mikula wrote:
>
>> Interesting ideas. I'm wondering, do you switch skins often enough that
>> you are worried about performance (and thus care about reusability of
>> skins)? Because I don't see how reusability of skins saves you lines of
>> code - whether the code is in the constructor or in the initialize()
>> method, it is there somewhere. In my opinion, reusing objects is more
>> complicated than creating fresh instances and the only justification for it
>> is performance.
>>
>
> To address your last point first, if you already are required to write a
> proper dispose method, then fresh instances should be just as easy/hard to
> write as reusable ones.  Everything is already in place, just rename the
> constructor.  Of course, if you did not write a proper dispose method, then
> your object will stick around or cause other trouble.  With fresh instances
> you won't notice this so readily -- in JavaFX for example, the problem of
> having objects that are no longer actively reachable through the
> SceneGraph, but are still participating in Event handling (because they
> registered non-weak listeners) can be a nice source of surprises.  With
> reusable objects, you'll notice the bugs in your cleanup code likely the
> first time you reuse it.
>

With a non-reusable skin, dispose is pretty much just removing the
listeners. With a reusable instance, I suspect there is more work to reset
the state of the instance (e.g. removing children, or, if you were
concerned about performance, returning them to a pool of objects). So I
would argue fresh instances are never more complicated than reusable ones,
while the opposite is true only in simple cases.


> Anyway, for me, making Skins reusable makes them easier to use with
> bindings,


 My understanding of skins is that they are the view of the MVC pattern and
that the rest of the application should not depend on the particular
implementation.


> and it ofcourse saves creating a factory.  I see the "skin" of an object
> as the same as say its background color.  There is no reason (anymore I
> think) that one should be treated so differently from the other.
>

One outstanding difference is that a skin is stateful, while a background
color is stateless (immutable). Thus you can use the same instance of
background color for many controls, but you cannot do that with skin
instances. In this respect, a skin provider is a better analogy to
background color (you can use the same skin provider with many controls).


>
>    private final Skin someExistingSkin = new SkinA();
>    private final Skin someExistingSkin2 = new SkinB();
>
>    void changeToSquareLook() {
>       myControl.setSkin(someExistingSkin);
>    }
>
>    void changeToRoundLook() {
>       myControl.setSkin(someExistingSkin2);
>    }
>
> vs.
>
>   private final SkinFactory skinFactory = new SkinFactory() {
>      public Skin createSkin(Control control) {
>          return new SkinA(control);
>      }
>   };
>
>   private final SkinFactory skinFactory2 = new SkinFactory() {
>      public Skin createSkin(Control control) {
>          return new SkinB(control);
>      }
>   };
>
>   void changeToSquareLook() {
>      myControl.setSkin(skinFactory.createSkin(myControl));
>   }
>
>    void changeToRoundLook() {
>      myControl.setSkin(skinFactory2.createSkin(myControl));
>    }
>

With lambdas, the skin factories become one-liners, yielding the same total
number of lines.


>
> It's not really about performance, but ease of use.  The binding case
> requires a ChangeListener instead of just bind().
>
>
>  I agree with you on the problem of separation of skin initialization from
>> setSkin(). Another way to address this could be deprecating the original
>> setSkin() method and introducing
>>
>>     setSkin(SkinProvider<C> skinProvider);
>>
>> where SkinProvider is a SAM interface and thus the above method could be
>> called like this:
>>
>>     setSkin(control -> new MySkin(control));
>>
>> I know this defeats reusability of skins altogether, so you (and others)
>> may disagree.
>>
> Maybe if there was a "skinProviderProperty"... then I could bind to that
> atleast.  Still introduces lots of factories (or functions).
>
> --John
>
>
Furthermore, neither the current state nor your proposal prevents you from
doing this:

Skin<MyControl> skin = new MySkin();
myControl1.setSkin(skin);
myControl2.setSkin(skin);

My proposal does not allow you to write such code.

Best,
Tomas

Reply via email to