On 8/8/16, 6:23 AM, "Harbs" <[email protected]> wrote: >Th truth of the matter is that Matrix really had many more methods than >really were needed for Matrix. > >I just trimmed down Matrix and removed all the methods that were not >strictly Matrix related. This includes all Vector3D methods as well as >gradient stuff. > >Here’s how I understand PAYG: > >1. Classes should be relatively small and deal with a specific piece of >functionality. >2. Additional functionality of components should be implemented as beads >(separated into model and view when practical). >3. Common code which is shared across multiple classes should be put in >static utility classes to prevent code duplication and unnecessarily >inflating classes for rarely used functionality. >4. The utility classes should be small and have specific uses.
That's a pretty good list. Additional functionality may go in subclasses some times. To be even more PAYG, utility classes would become utility functions. Sure, there is often a tradeoff between code size and encapsulation/abstraction. The way I think of it is that if you have separation of concerns, the tool chain can someday optimize away some of this overhead. But if you entangle concrete classes, it is much harder or impossible. Maybe there is some issue with having servers and browsers use GZIP compression over the wire, but to me, since that is possible and seems to make sense, I tend to not worry so much about code size for FlexJS. That's an example of the "tool chain" solving the right problem in the right place. Every time we add both an interface and a class instead of just a class, we add a bit extra to the download size and initialization time of the app, but I see that as an important tradeoff for future cross-versioning issues, plus GCC hates circular dependencies, plus it allows for other optimizations. If GCC doesn't already do this, FalconJX, or some other post-processor might be able to see that certain setters are just pass through (no change events, just setting a backing variable) and reduce that to direct access to the backing variable. Optimizing compilers and runtimes have been doing this for years, so this is the right place to worry about that. Sure it would be great if FlexJS 1.0 was optimized in this fashion, but before we manually optimize our code and reduce separation of concerns, we should make sure those extra bytes or function calls are truly killing our app. But my philosophy is to use more interfaces in the framework code and let other parts of the chain do optimization. The other thing I factor in is what the JS side looks like. If there is no Matrix implementation, then you have more options as to how to implement something. Doing it the Flash way may not be the right way as Flash doesn't use many interfaces. So comments inline to Yishay's post below. > >On Aug 8, 2016, at 11:22 AM, yishayw <[email protected]> wrote: > >> I thought I'd share a discussion we had on Matrices as it demonstrates >>some >> problems in deciding how to do things 'the FlexJS way'. >> >> We needed a TransformBead which uses a matrix as its model. We started >>out >> by implementing the original AS3 matrix, which has members a, b, c, d, >>tx, >> ty and a bunch of utility methods (copyColumnFrom, copyRowTo, rotate, >>etc.). >> The utility methods seemed like clutter for most cases so in keeping >>with >> PAYG we derived an interface that includes that mostly included access >> methods to the members (get a, set a, get b, etc.) Now we had the >>option of >> using more lightweight matrix when the utility methods were not >>necessary. >> TransformBead relied on IMatrix implementors, which could be >>lightweight or >> rich with convenience methods. >> >> This sounds like 'the FlexJS way' but we ditched it for the following >> considerations: >> >> 1) Method calls in JS are slower than direct access of properties. >>Forcing >> models to implement methods rules out using a faster object. I still think the tools can optimize this some day, assuming change events will not be needed. >> >> 2) The supposedly heavyweight model that is rich with convenience >>methods >> doesn't actually result in heavy instances. The methods are all stored >>once >> on the prototype and not duplicated per instance. So using the >>'lightweight' >> model doesn't really make the difference one might hope it would. If extra methods are bringing in extra dependencies, then I would consider having a subclass with those extra methods/dependencies. If the extra dependencies are a few interfaces, then I would just bake them in. My 2 cents, -Alex
