Re: Res: Best way to extend a component?
very good roundup! Everton Agner wrote: If component classes were not meant to be subclassed, wouldn't it be nice to make them as "final classes"? It would not let people lose some time on it, since it would be seen at compilation time, and it's kinda logical. - Everton Agner Ramos De: Alex Kotchnev Para: Tapestry users Enviadas: Quinta-feira, 13 de Maio de 2010 17:20:41 Assunto: Re: Best way to extend a component? I think it is fair to say that T5 has indeed gone to great lengths to try to isolate the user from changes in the framework. Thus, if T5 decides to change the internal implementation of how a Select works, there wouldn't be 100 people screaming "See, we told you that Tapestry has never been and will never will be backwards compatible". That is great and all, except that you run into the infamous T5 learning curve. Most developers that start with T5 already know a thing or two about Java, object orientation, and server side / web programming . Thus, if you give them some objects / classes, most people know how to extend a class and try to inject some custom behavior that way. There certainly are "alternative" ways of using the existing components (e.g. wrapping them in others, mixins, whatever) that in the general sense provide the needed extensibility. However, getting your head around those approaches (e.g. mixins), seems to require a big mountain of knowledge before being able to do some simple things that seem like they should be easily achievable through subclassing. So, the "next best option" (and I really use "best" in a very loose way, as in the least evil) is to go out and copy the source (I think I've seen a few recommendations on the list to do that "if you don't like not being able to subclass") of the existing components ( which most people can understand), and make their tweaks in the user's copy of the component. Thus, if the framework moves on, it can technically say "See, we did all of this in a backwards compatible way, everyone who was using our public API is still in a good shape" . Now, the problem is that when the user copied the source from the T5 components, there is a pretty good chance that the copied source relies on a whole bunch of "internal services" (which give no guarantees of backward compatibility), and when the internal services move on, all the breakage will occur in the "copied" code. Thus, technically, although the public APIs did remain consistent and pristine, the end result is that by encouraging this approach the breakage becomes a lot bigger and seemingly harder to fix ('cause we all know that when you copy the source of a T5 component you might not understand ALL that's inside). Anyway, I don't really have a solution - both sides have valid points. Certainly, the framework authors should be able to evolve the framework as they see fit w/o having people screaming in their ear about backward compatibility. At the same point, the combination of not being able to subclass plus the plethora of new (and sometimes not easy to grasp) concepts makes it way too difficult when you just want to do "this little tweak" (even with the understanding that you're tying yourself to the implementation). T5 prides itself on how easy it is to create new components - create a class, a template, and boom - you can start using it just like any other component. Maybe there are things that can be done in limited ways to open up the most common components in ways that don't break their encapsulation (e.g. maybe events) but allow for easier extension. Back to the issue of documentation (which the wiki might help with), maybe as a community we can do a better job of explaining and giving examples of these new concepts . Anyway, my 2c. Regards, Alex K On Thu, May 13, 2010 at 3:43 PM, Benny Law wrote: On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo< thiag...@gmail.com> wrote: On Thu, 13 May 2010 15:44:50 -0300, Benny Law wrote: I want the user to consciously choose a value. does the trick, no? No, because I don't want the blank option if there is only one valid option in the model, or if there is a valid initial value (if the bound property is not null to begin with and is one of the valid options). Again, this logic depends on the number of options available (as well as the current value), and I don't know the option list size if it is a dynamic list. I want this logic in the Select component across the board because it is generic and not specific to special cases. I don't want to incur extra code per usage. The simplest solution is just to override the spot in Select where it decides what to do when BlankOption is AUTO. It's a very simple case where inheritance + override would be very effective. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da I
Res: Best way to extend a component?
If component classes were not meant to be subclassed, wouldn't it be nice to make them as "final classes"? It would not let people lose some time on it, since it would be seen at compilation time, and it's kinda logical. - Everton Agner Ramos De: Alex Kotchnev Para: Tapestry users Enviadas: Quinta-feira, 13 de Maio de 2010 17:20:41 Assunto: Re: Best way to extend a component? I think it is fair to say that T5 has indeed gone to great lengths to try to isolate the user from changes in the framework. Thus, if T5 decides to change the internal implementation of how a Select works, there wouldn't be 100 people screaming "See, we told you that Tapestry has never been and will never will be backwards compatible". That is great and all, except that you run into the infamous T5 learning curve. Most developers that start with T5 already know a thing or two about Java, object orientation, and server side / web programming . Thus, if you give them some objects / classes, most people know how to extend a class and try to inject some custom behavior that way. There certainly are "alternative" ways of using the existing components (e.g. wrapping them in others, mixins, whatever) that in the general sense provide the needed extensibility. However, getting your head around those approaches (e.g. mixins), seems to require a big mountain of knowledge before being able to do some simple things that seem like they should be easily achievable through subclassing. So, the "next best option" (and I really use "best" in a very loose way, as in the least evil) is to go out and copy the source (I think I've seen a few recommendations on the list to do that "if you don't like not being able to subclass") of the existing components ( which most people can understand), and make their tweaks in the user's copy of the component. Thus, if the framework moves on, it can technically say "See, we did all of this in a backwards compatible way, everyone who was using our public API is still in a good shape" . Now, the problem is that when the user copied the source from the T5 components, there is a pretty good chance that the copied source relies on a whole bunch of "internal services" (which give no guarantees of backward compatibility), and when the internal services move on, all the breakage will occur in the "copied" code. Thus, technically, although the public APIs did remain consistent and pristine, the end result is that by encouraging this approach the breakage becomes a lot bigger and seemingly harder to fix ('cause we all know that when you copy the source of a T5 component you might not understand ALL that's inside). Anyway, I don't really have a solution - both sides have valid points. Certainly, the framework authors should be able to evolve the framework as they see fit w/o having people screaming in their ear about backward compatibility. At the same point, the combination of not being able to subclass plus the plethora of new (and sometimes not easy to grasp) concepts makes it way too difficult when you just want to do "this little tweak" (even with the understanding that you're tying yourself to the implementation). T5 prides itself on how easy it is to create new components - create a class, a template, and boom - you can start using it just like any other component. Maybe there are things that can be done in limited ways to open up the most common components in ways that don't break their encapsulation (e.g. maybe events) but allow for easier extension. Back to the issue of documentation (which the wiki might help with), maybe as a community we can do a better job of explaining and giving examples of these new concepts . Anyway, my 2c. Regards, Alex K On Thu, May 13, 2010 at 3:43 PM, Benny Law wrote: > On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo < > thiag...@gmail.com> wrote: > > > On Thu, 13 May 2010 15:44:50 -0300, Benny Law > > wrote: > > > > I want the user to consciously choose a value. > >> > > > > > does > > the trick, no? > > > > No, because I don't want the blank option if there is only one valid option > in the model, or if there is a valid initial value (if the bound property > is > not null to begin with and is one of the valid options). Again, this logic > depends on the number of options available (as well as the current value), > and I don't know the option list size if it is a dynamic list. > > I want this logic in the Select component across the board because it is > generic and not specific to special cases. I don't want to incur extra code > per usage. The simplest solution is just to override the spot in Select > where it decides what to do when BlankOption is AUTO. It's a very simple > case where inheritance + override would be very effective. > > > > > > -- > > Thiago H. de Paula Figueiredo > > Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, > > and instructor > > Owner, Ars Machina Tecnologia da I