Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Alex Harui-2
I agree we have to be concerned about DRY.  Research into optimal patterns
for creating common flavors of beads would be very helpful.  The compiler
might be able to help as well.

-Alex

On 6/6/17, 6:52 AM, "Josh Tynjala" <[hidden email]> wrote:

>The way that beads work means that we will frequently "violate" DRY, as I
>understand it. FlexJS is designed to have multiple beads that implement
>the
>same thing in different ways. The simplest bead will be designed to be
>never removed and it probably won't include any properties to configure
>its
>behavior. A more complex bead might include some of the same code from the
>simplest bead, but it will also be designed to be removed, but still not
>configured. An even more complex bead will include all three (the core
>feature, removal, and properties to configure). There might even be a
>fourth one that can't be removed, but has properties to configure. Going
>even further, there might even be variations with different subsets of
>properties that can be configured.
>
>Ideally, we'd find a way to reuse some of the code from the simpler beads.
>It might be possible to subclass them, for instance. However, unless the
>simplest beads are designed for it, reusing their code may not be
>possible.
>In fact, designing them in a way that they can be extended may violate
>PAYG
>instead because it may require adding code that isn't always needed. In
>that case, there's no option except to repeat some code.
>
>- Josh
>
>On Tue, Jun 6, 2017 at 12:02 AM, Justin Mclean <[hidden email]>
>wrote:
>
>> Hi,
>>
>> >  Unless something is functionality that you would (virtually) always
>> need, it’s a separate bead.
>>
>> So for CCS we have border, does everyone need borders? Why do we only a
>> sub set of the font attributes included? Some people are not going to
>>use
>> all of them or in fact any of them and some other may need other
>>properties
>> so why are they not seperate?  Not that I think these should be removed
>> into seperate parts. The issue is just about every feature you can name
>>is
>> going to optional to someone. So I think we near a clearer definition of
>> what PAYG is.
>>
>> Another example why for instance was flexGrow and flexShrink added in to
>> the CSS code? Shouldn't they be implemented in line with the PAYG
>>principal
>> in another class? And there are numerous other examples of this. I feel
>> that PAYG is not being applied consistently and seems selective on who
>>is
>> making the contribution.
>>
>> > PAYG is already well understood
>>
>> IMO it has not been clearly defined. Alex has described in various ways
>>as
>> it size / runtime cost only to move to goal posts. I for one would like
>>a
>> clearer definition of it.
>>
>> > All functionality should be implemented as beads when practical. Beads
>> should be as modular as possible with the smallest possible functional
>>set.
>>
>> What about the cost of violating DRY or the single responsibility
>> principal which two beads do similar things? Is it really OK to add
>> technical debt / penalise users of a new feature when it would be less
>>cost
>> modifying/improving an existing bead at a much smaller cost? How do you
>> discourage copy paste coding?
>>
>> Thanks,
>> Justin

Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

OmPrakash Muppirala
In an attempt to simplify the pattern, can we say:

Strands = components
Beads = functionalities

All components dont need all functionalities.  We add functionalities to
components on a Pay As You Go (PAYG) basis.

This is achieved through composition (the classical OOP paradigm)

That is, a Strand is composed of several Beads.  Beads are added to Strands
only when necessary.

That leaves us with how we build the Beads themselves.  I suggest we
encourage  inheritance for Beads so as to follow the Dont Repeat Yourself
(DRY) principle.

Thanks,
Om


On Jun 6, 2017 8:03 AM, "Alex Harui" <[hidden email]> wrote:

I agree we have to be concerned about DRY.  Research into optimal patterns
for creating common flavors of beads would be very helpful.  The compiler
might be able to help as well.

-Alex

On 6/6/17, 6:52 AM, "Josh Tynjala" <[hidden email]> wrote:

>The way that beads work means that we will frequently "violate" DRY, as I
>understand it. FlexJS is designed to have multiple beads that implement
>the
>same thing in different ways. The simplest bead will be designed to be
>never removed and it probably won't include any properties to configure
>its
>behavior. A more complex bead might include some of the same code from the
>simplest bead, but it will also be designed to be removed, but still not
>configured. An even more complex bead will include all three (the core
>feature, removal, and properties to configure). There might even be a
>fourth one that can't be removed, but has properties to configure. Going
>even further, there might even be variations with different subsets of
>properties that can be configured.
>
>Ideally, we'd find a way to reuse some of the code from the simpler beads.
>It might be possible to subclass them, for instance. However, unless the
>simplest beads are designed for it, reusing their code may not be
>possible.
>In fact, designing them in a way that they can be extended may violate
>PAYG
>instead because it may require adding code that isn't always needed. In
>that case, there's no option except to repeat some code.
>
>- Josh
>
>On Tue, Jun 6, 2017 at 12:02 AM, Justin Mclean <[hidden email]>
>wrote:
>
>> Hi,
>>
>> >  Unless something is functionality that you would (virtually) always
>> need, it’s a separate bead.
>>
>> So for CCS we have border, does everyone need borders? Why do we only a
>> sub set of the font attributes included? Some people are not going to
>>use
>> all of them or in fact any of them and some other may need other
>>properties
>> so why are they not seperate?  Not that I think these should be removed
>> into seperate parts. The issue is just about every feature you can name
>>is
>> going to optional to someone. So I think we near a clearer definition of
>> what PAYG is.
>>
>> Another example why for instance was flexGrow and flexShrink added in to
>> the CSS code? Shouldn't they be implemented in line with the PAYG
>>principal
>> in another class? And there are numerous other examples of this. I feel
>> that PAYG is not being applied consistently and seems selective on who
>>is
>> making the contribution.
>>
>> > PAYG is already well understood
>>
>> IMO it has not been clearly defined. Alex has described in various ways
>>as
>> it size / runtime cost only to move to goal posts. I for one would like
>>a
>> clearer definition of it.
>>
>> > All functionality should be implemented as beads when practical. Beads
>> should be as modular as possible with the smallest possible functional
>>set.
>>
>> What about the cost of violating DRY or the single responsibility
>> principal which two beads do similar things? Is it really OK to add
>> technical debt / penalise users of a new feature when it would be less
>>cost
>> modifying/improving an existing bead at a much smaller cost? How do you
>> discourage copy paste coding?
>>
>> Thanks,
>> Justin
Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Harbs
There’s actually two ways of adhering to DRY:
1. Subclassing
2. Utility classes.

In FlexJS we have a preference towards utility classes. (and I’d like to see even more) Besides very often doing a better job than subclasses in terms of avoiding code-repeat, it’s also more geared towards functional programming which is a good thing. It allows for easier testing and the like. Lots of small utility classes is also much more modular.

So, utility classes solves PAYG, DRY and improved testability. An all around win…

As far as beads go vis a vis subclassing, I’d say it depends:
1. The the vast majority of the functionality could be in utility classes, then I’d go for two separate classes.
2. If two versions of the same bead-type are unlikely to be used in the same app, I’d avoid subclassing as well.
3. If it’s likely to have both versions of the beads in use and utility classes are impractical, I’d lean towards subclassing.

My $0.02
Harbs

> On Jun 6, 2017, at 6:52 PM, OmPrakash Muppirala <[hidden email]> wrote:
>
> In an attempt to simplify the pattern, can we say:
>
> Strands = components
> Beads = functionalities
>
> All components dont need all functionalities.  We add functionalities to
> components on a Pay As You Go (PAYG) basis.
>
> This is achieved through composition (the classical OOP paradigm)
>
> That is, a Strand is composed of several Beads.  Beads are added to Strands
> only when necessary.
>
> That leaves us with how we build the Beads themselves.  I suggest we
> encourage  inheritance for Beads so as to follow the Dont Repeat Yourself
> (DRY) principle.
>
> Thanks,
> Om
>
>
> On Jun 6, 2017 8:03 AM, "Alex Harui" <[hidden email]> wrote:
>
> I agree we have to be concerned about DRY.  Research into optimal patterns
> for creating common flavors of beads would be very helpful.  The compiler
> might be able to help as well.
>
> -Alex
>
> On 6/6/17, 6:52 AM, "Josh Tynjala" <[hidden email]> wrote:
>
>> The way that beads work means that we will frequently "violate" DRY, as I
>> understand it. FlexJS is designed to have multiple beads that implement
>> the
>> same thing in different ways. The simplest bead will be designed to be
>> never removed and it probably won't include any properties to configure
>> its
>> behavior. A more complex bead might include some of the same code from the
>> simplest bead, but it will also be designed to be removed, but still not
>> configured. An even more complex bead will include all three (the core
>> feature, removal, and properties to configure). There might even be a
>> fourth one that can't be removed, but has properties to configure. Going
>> even further, there might even be variations with different subsets of
>> properties that can be configured.
>>
>> Ideally, we'd find a way to reuse some of the code from the simpler beads.
>> It might be possible to subclass them, for instance. However, unless the
>> simplest beads are designed for it, reusing their code may not be
>> possible.
>> In fact, designing them in a way that they can be extended may violate
>> PAYG
>> instead because it may require adding code that isn't always needed. In
>> that case, there's no option except to repeat some code.
>>
>> - Josh
>>
>> On Tue, Jun 6, 2017 at 12:02 AM, Justin Mclean <[hidden email]>
>> wrote:
>>
>>> Hi,
>>>
>>>> Unless something is functionality that you would (virtually) always
>>> need, it’s a separate bead.
>>>
>>> So for CCS we have border, does everyone need borders? Why do we only a
>>> sub set of the font attributes included? Some people are not going to
>>> use
>>> all of them or in fact any of them and some other may need other
>>> properties
>>> so why are they not seperate?  Not that I think these should be removed
>>> into seperate parts. The issue is just about every feature you can name
>>> is
>>> going to optional to someone. So I think we near a clearer definition of
>>> what PAYG is.
>>>
>>> Another example why for instance was flexGrow and flexShrink added in to
>>> the CSS code? Shouldn't they be implemented in line with the PAYG
>>> principal
>>> in another class? And there are numerous other examples of this. I feel
>>> that PAYG is not being applied consistently and seems selective on who
>>> is
>>> making the contribution.
>>>
>>>> PAYG is already well understood
>>>
>>> IMO it has not been clearly defined. Alex has described in various ways
>>> as
>>> it size / runtime cost only to move to goal posts. I for one would like
>>> a
>>> clearer definition of it.
>>>
>>>> All functionality should be implemented as beads when practical. Beads
>>> should be as modular as possible with the smallest possible functional
>>> set.
>>>
>>> What about the cost of violating DRY or the single responsibility
>>> principal which two beads do similar things? Is it really OK to add
>>> technical debt / penalise users of a new feature when it would be less
>>> cost
>>> modifying/improving an existing bead at a much smaller cost? How do you
>>> discourage copy paste coding?
>>>
>>> Thanks,
>>> Justin

Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Justin Mclean
Administrator
In reply to this post by OmPrakash Muppirala
Hi,

> This is achieved through composition (the classical OOP paradigm)

The document pointed to yesterday suggests to avoid inheritance and prefer composition. Is that just for components and it’s OK to use were needed in beads?

Thanks,
Justin.
Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Justin Mclean
Administrator
In reply to this post by Harbs
Hi,

> In FlexJS we have a preference towards utility classes.

So say we have existing bead A and we want to add some functionality to to. In order to use utility classes we would need to modify bead A and pull out some of the code into a utility class so bead B can use it.

This will increase the size/runtime cost to existing people using bead A. Is this accectable?

Thanks,
Justin
Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

OmPrakash Muppirala
On Tue, Jun 6, 2017 at 5:29 PM, Justin Mclean <[hidden email]>
wrote:

> Hi,
>
> > In FlexJS we have a preference towards utility classes.
>
> So say we have existing bead A and we want to add some functionality to
> to. In order to use utility classes we would need to modify bead A and pull
> out some of the code into a utility class so bead B can use it.
>
> This will increase the size/runtime cost to existing people using bead A.
> Is this accectable?
>

Yes, there will be a size cost, which is why the inheritance approach is
better than Utils approach for Beads.

*Utils approach:*

Bead A supports feature X
Bead B needs to support feature X and Y

Create a Util class called FeatureXAndY

Bead A calls util:FeatureXAndY (Now Bead A loads code for unnecessary
feature Y)
Bead B calls util:FeatureXAndY

*Inheritance approach:*

Bead A supports feature X
Bead B needs to support feature X and Y

Bead A has code for feature X alone (no extra code)
Bead B extends Bead A and adds code for feature Y (no extra code)
Moreover, no extra util class to maintain.
Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

yishayw
OmPrakash Muppirala wrote
Bead A supports feature X
Bead B needs to support feature X and Y
Theoretically Bead B could support just feature Y, and the strand would choose to add both A and B or just A.
Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Alex Harui-2
I'm not sure there is one right way.  Some features are "cross-cutting",
some build on other features.  The first is done in some languages via
multiple inheritance, which AS doesn't support, so utility functions (I
would like to see our utility classes broken into utility functions) or
even beads with their own strand of child beads is possible.  The second
lends itself to subclassing.

Another question is whether the smallest bead should carry any overhead to
make subclassing easier.  My personal opinion is no, but I haven't done
any research into how much the cost is for the various options.  A
volunteer willing to do this will be greatly appreciated, but it may not
result in a single answer, maybe just data to advise in certain scenarios.

My 2 cents,
-Alex

On 6/6/17, 10:01 PM, "yishayw" <[hidden email]> wrote:

>OmPrakash Muppirala wrote
>> Bead A supports feature X
>> Bead B needs to support feature X and Y
>
>Theoretically Bead B could support just feature Y, and the strand would
>choose to add both A and B or just A.
>
>
>
>
>--
>View this message in context:
>https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-fle
>x-development.2333347.n4.nabble.com%2FBeads-and-DRY-was-Re-FlexJS-Removing
>-PasswordInputBead-has-no-effect-tp62177p62199.html&data=02%7C01%7C%7C0468
>ec58ff8646d727ca08d4ad645e4e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C
>636324093992333208&sdata=RI6FcM6UJwls9fw6MzZZwwk%2FFu5JonjiVlTx%2B5diuow%3
>D&reserved=0
>Sent from the Apache Flex Development mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

piotrz
In reply to this post by yishayw
Hi,

Personally I prefer this approach even if it is more code.

Piotr
Apache Flex PMC
piotrzarzycki21@gmail.com
Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Justin Mclean
Administrator
Hi,

> Personally I prefer this approach even if it is more code.

I assume you mean subclassing over utility functions?

Thanks,
Justin
Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

piotrz
Hi Justin,

I mean take some part of code from class A to B (could be inheritance) in order to have new functionality. Bead B is doing only Y.

"Bead B extends Bead A and adds code for feature Y (no extra code)"

Piotr
Apache Flex PMC
piotrzarzycki21@gmail.com
Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Harbs
In reply to this post by OmPrakash Muppirala
That’s not what I’m suggesting at all.

If utility classes (or utility functions) are bloated with lots of functionality then they are not done right.

Utilities should be reserved for well defined functionality. A good example of this is AnimationUtil. Imagine you have two animation beads which do different things, they would both use AnimationUtil for requestFrame and cancelFrame.

The same goes for SolidBorderUtil (which should really be split into two). Any bead which needs to apply a border just calls the utility.

So:
Bead A supports feature X
Bead B needs to support feature X and Y

feature x used functionality a and b
feature y uses functionality c and d
Create a Util classes a, b, c and d which beads a and b use as needed.

This is obviously not a pattern useful everywhere, but where applicable, has many advantages.

Harbs


> On Jun 7, 2017, at 4:08 AM, OmPrakash Muppirala <[hidden email]> wrote:
>
> *Utils approach:*
>
> Bead A supports feature X
> Bead B needs to support feature X and Y
>
> Create a Util class called FeatureXAndY

Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Peter Ent-2
In reply to this post by OmPrakash Muppirala
If you look at the layouts, you can see these questions for real. Take
VerticalLayout. The idea is to stack children of some component
vertically. Those children can be given a) no explicit size, b) an
explicit size as pixel values, c) a percentage size. You know what the
VerticalLayout is supposed to do, but how it does it depends on the
platform. Plus there are some questions:

Do you provide an option to space them (a gap) or is that
VerticalLayoutWithGap?
Do you provide an option to horizontally align them or is that
VerticalLayoutWithHorizontalAlignment?
What if you want both a gap and an alignment? Is that
VerticalLayoutWithGapAndHorizontalAlignment?

Achieving a gap and alignment is pretty easy and I believe can be done
within the same loop pass as stacking the elements.

We circumvented the gap issue by saying you achieving by giving the
children being stacked margin style values. So that eliminates two of the
variations. But that comes at a cost on the SWF side (JS side handles
margins in the browser) since it is way more complex to account for those
margins and it might rightly be put into its own layout bead.

And when you make these altered versions, its hard to subclass since you
have the layout algorithm that you've have to tap into from the subclass
and then call out or use a delegate.

‹peter

On 6/6/17, 9:08 PM, "[hidden email] on behalf of OmPrakash Muppirala"
<[hidden email] on behalf of [hidden email]> wrote:

>On Tue, Jun 6, 2017 at 5:29 PM, Justin Mclean <[hidden email]>
>wrote:
>
>> Hi,
>>
>> > In FlexJS we have a preference towards utility classes.
>>
>> So say we have existing bead A and we want to add some functionality to
>> to. In order to use utility classes we would need to modify bead A and
>>pull
>> out some of the code into a utility class so bead B can use it.
>>
>> This will increase the size/runtime cost to existing people using bead
>>A.
>> Is this accectable?
>>
>
>Yes, there will be a size cost, which is why the inheritance approach is
>better than Utils approach for Beads.
>
>*Utils approach:*
>
>Bead A supports feature X
>Bead B needs to support feature X and Y
>
>Create a Util class called FeatureXAndY
>
>Bead A calls util:FeatureXAndY (Now Bead A loads code for unnecessary
>feature Y)
>Bead B calls util:FeatureXAndY
>
>*Inheritance approach:*
>
>Bead A supports feature X
>Bead B needs to support feature X and Y
>
>Bead A has code for feature X alone (no extra code)
>Bead B extends Bead A and adds code for feature Y (no extra code)
>Moreover, no extra util class to maintain.

Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Peter Ent-2
In reply to this post by Harbs
We have never really discussed the use of delegates. Its not something
that ties in that well with FlexJS I think. But using a delegate to
off-load some of the work, just when that work is needed, might be another
solution.

‹peter

On 6/7/17, 2:36 AM, "Harbs" <[hidden email]> wrote:

>That¹s not what I¹m suggesting at all.
>
>If utility classes (or utility functions) are bloated with lots of
>functionality then they are not done right.
>
>Utilities should be reserved for well defined functionality. A good
>example of this is AnimationUtil. Imagine you have two animation beads
>which do different things, they would both use AnimationUtil for
>requestFrame and cancelFrame.
>
>The same goes for SolidBorderUtil (which should really be split into
>two). Any bead which needs to apply a border just calls the utility.
>
>So:
>Bead A supports feature X
>Bead B needs to support feature X and Y
>
>feature x used functionality a and b
>feature y uses functionality c and d
>Create a Util classes a, b, c and d which beads a and b use as needed.
>
>This is obviously not a pattern useful everywhere, but where applicable,
>has many advantages.
>
>Harbs
>
>
>> On Jun 7, 2017, at 4:08 AM, OmPrakash Muppirala <[hidden email]>
>>wrote:
>>
>> *Utils approach:*
>>
>> Bead A supports feature X
>> Bead B needs to support feature X and Y
>>
>> Create a Util class called FeatureXAndY
>

Reply | Threaded
Open this post in threaded view
|

Re: Beads and DRY (was Re: [FlexJS] Removing PasswordInputBead has no effect)

Josh Tynjala
In reply to this post by Peter Ent-2
I actually added VerticalLayoutWithPaddingAndGap recently. I didn't want to
set margins because a gap property is much more convenient in many
situations. :)

- Josh

On Wed, Jun 7, 2017 at 7:15 AM, Peter Ent <[hidden email]> wrote:

> If you look at the layouts, you can see these questions for real. Take
> VerticalLayout. The idea is to stack children of some component
> vertically. Those children can be given a) no explicit size, b) an
> explicit size as pixel values, c) a percentage size. You know what the
> VerticalLayout is supposed to do, but how it does it depends on the
> platform. Plus there are some questions:
>
> Do you provide an option to space them (a gap) or is that
> VerticalLayoutWithGap?
> Do you provide an option to horizontally align them or is that
> VerticalLayoutWithHorizontalAlignment?
> What if you want both a gap and an alignment? Is that
> VerticalLayoutWithGapAndHorizontalAlignment?
>
> Achieving a gap and alignment is pretty easy and I believe can be done
> within the same loop pass as stacking the elements.
>
> We circumvented the gap issue by saying you achieving by giving the
> children being stacked margin style values. So that eliminates two of the
> variations. But that comes at a cost on the SWF side (JS side handles
> margins in the browser) since it is way more complex to account for those
> margins and it might rightly be put into its own layout bead.
>
> And when you make these altered versions, its hard to subclass since you
> have the layout algorithm that you've have to tap into from the subclass
> and then call out or use a delegate.
>
> ‹peter
>
> On 6/6/17, 9:08 PM, "[hidden email] on behalf of OmPrakash Muppirala"
> <[hidden email] on behalf of [hidden email]> wrote:
>
> >On Tue, Jun 6, 2017 at 5:29 PM, Justin Mclean <[hidden email]>
> >wrote:
> >
> >> Hi,
> >>
> >> > In FlexJS we have a preference towards utility classes.
> >>
> >> So say we have existing bead A and we want to add some functionality to
> >> to. In order to use utility classes we would need to modify bead A and
> >>pull
> >> out some of the code into a utility class so bead B can use it.
> >>
> >> This will increase the size/runtime cost to existing people using bead
> >>A.
> >> Is this accectable?
> >>
> >
> >Yes, there will be a size cost, which is why the inheritance approach is
> >better than Utils approach for Beads.
> >
> >*Utils approach:*
> >
> >Bead A supports feature X
> >Bead B needs to support feature X and Y
> >
> >Create a Util class called FeatureXAndY
> >
> >Bead A calls util:FeatureXAndY (Now Bead A loads code for unnecessary
> >feature Y)
> >Bead B calls util:FeatureXAndY
> >
> >*Inheritance approach:*
> >
> >Bead A supports feature X
> >Bead B needs to support feature X and Y
> >
> >Bead A has code for feature X alone (no extra code)
> >Bead B extends Bead A and adds code for feature Y (no extra code)
> >Moreover, no extra util class to maintain.
>
>