Hi Carlos, I've said this before: I feel bad sometimes that Flex taught folks some questionable programming practices.
The short answer: -Don't reference concrete classes -Choose composition patterns over inheritance The long answer: Yishay and Andrew are headed in the right direction. A good goal for Royale is to try to avoid references to concrete classes (other than what your class subclasses). Referencing concrete classes essentially breaks PAYG by creating an unreplaceable chain of dependencies. Flex referenced too many concrete classes and we all paid for it. But addition to using interfaces, we should try to remember that Royale is more about composition than inheritance. Beads are composed into instances to implement functionality. Hopefully, many beads can be re-used on other instances with different base class ancestry if the API surfaces are designed correctly. And, not only are beads best referenced via their interfaces, you can also ask "has" instead of "is". IOW, you can ask if an instance "has" a bead instead of just testing if the instance "is" (implements) an interface. The first word in PAYG is Pay. PAYG is not Free-AYG. Somebody has to pay. The more features you use, the more you pay in download size and performance, especially at startup. The point of PAYG and beads is to enable optimization. If you want to make cookies and you buy each ingredient separately it will take up more space and weight because of the packaging as opposed to buying one bag of ready-to-bake cookie mix. But the point of having separate ingredients is so you can replace white flour with whole wheat or rye or gluten-free easily. If it turns out there is significant overhead in some set of beads, you can choose to inline them, just like any other inlining optimization. That is a manual process today. Inlining is effectively copying code, so it sounds like that is what you are doing today. But the copying of code should only be a last resort after proving that the composition patterns have too much overhead. The inlining will have its own overhead, usually in download size, as you mentioned. I explained the "exploded component" concept a while back. It attempts to illustrate composition by showing how, in MXML, a component can really be declared as its beads. For example: <js:Button> Could be written more verbosely as: <js:UIBase> <js:beads> <js:TextModel /> <js:ButtonView /> <js:ButtonController /> </js:beads> </js:UIBase> Then a ToggleButton could be implemented by simply replacing the controller (and probably the view). <js:UIBase> <js:beads> <js:TextModel /> <js:ToggleButtonView /> <js:ToggleButtonController /> </js:beads> </js:UIBase> So it is only for convenience, so you don't have to type all of these tags, that we create a top-level component (TLC) called Button that pre-packages some set of beads and write glue code that proxies some of the bead APIs to the TLC's API such as: public class Button extends UIBase { public function set label(value:String):void { model.label = value; } } The point, relative to this topic, is there is a cost to this convenience, which is the line or two of glue code. So, with beads, it is only for convenience that the TLC implements these PAYG interfaces. If you package up the implementation of IClassSelectorListSupport into a bead, that bead should be able to be composed into different classes with different base classes. We actually have a choice of whether to add the glue code that proxies that implementation to the API surface. If you do that proxying, then other code can look like: if (myInstance is IClassSelectorListSupport) (myInstance as IClassSelectorListSupport).someAPi = "foo"; But the other option is the "has" pattern, which looks like: Var foo:IClassSelectorListSupport = myInstance.getBeadByType(IClassSelectorListSupport); If (foo) foo.someAPI = "foo"; I've not done any measuring of which is better, but the latter does not require glue code, which allows someone to just drop in any IClassSelectorListSupport bead on some other random instance they've created and not make any assumptions about base classes or proxy code to interfaces. For example: <my:Instance> <my:beads> <j:JewelClassSelectorListSupport /> </my:beads> </my:instance> This instance, declared in MXML without the overhead of creating a TLC and proxying code to the API surface, would work with the "has" code, but not the "is" code. Is it all worth it? I don't know. I'm waiting to see folks try it, especially in more complex apps. But for sure, composition "has" patterns are more flexible than traditional "is" patterns. This "has" pattern allows us to sort of have multiple inheritance or "mixin" type patterns, but it is done by accessing the beads directly not by proxying code to the TLC so "inheritance" isn't an accurate word. TLCs are more for convenience, to avoid repeating a lot of tags in MXML or calling addBead a lot, but we should try to make our code even more flexible by not requiring folks to work with TLCs. So, in theory, you should try to package the implementation of IClassSelectorListSupport into a bead and see if you run into problems adding it to Group and other base class ancestries. And then consider using the "has" pattern or at least "is" with interfaces instead of concrete classes. Think "beads" not TLCs. My 2 cents, -Alex On 4/30/19, 7:48 AM, "Carlos Rovira" <carlosrov...@apache.org> wrote: Hi Yishay, El mar., 30 abr. 2019 a las 13:27, Yishay Weiss (<yishayj...@hotmail.com>) escribió: > It seems to me this is more an AS3 issue than a Royale issue. It would be > cool to enhance AS to include features such as Mixins, but as long as we > have a simple single inheritance model the solution you implemented is > probably optimal. > > If you and others think is the best we can get, maybe we can left as is. Maybe we can just optimize as Andrew said making that a class to be implemented by the rest of classes, in that way all share that and changing just one class will change the 3 implementors at once... > Also, in my opinion you should always check to see if a said object > implements an interface, rather than extends a class. If you stick to that > your solution works fine. > > the problem with this is what I stated before. I expect users to use UIBase/StyledUIBase classes instead or interface in this class of context. And the problem in this case is that we can't generalize a code since not all components will be "StyledUIBase". For me this is the most serious problem -- Carlos Rovira https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fabout.me%2Fcarlosrovira&data=02%7C01%7Caharui%40adobe.com%7Cf54ca163f75d412f90ff08d6cd7aeafe%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636922325199044381&sdata=FtMO5gSLB5oio5pynuXAdg1cuxJHJkiDYev3crELiXA%3D&reserved=0