builder pattern

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

builder pattern

Peter Uhnak
Is there some common / best way for coding builders?

Two ways that I see are:

a) using a block - I've seen this in menus and some other, however in my case I need to add an extra parameter as label

"variant with two params"
aForm addDropList: 'Type' with: [ :dropList |
dropList
items: #(input #output);
" ... ".
].

"variant with one method param and value holder"
aForm addDropList: [ :labelHolder :dropList |
labelHolder value: 'Type'.
dropList
items: #(input #output);
" ... ".
].

b) using return value - no blocks, no extra code
(aForm addDropList: 'Type')
items: #(input #output);
" ... ".

I would use the second variant as it looks much cleaner, however considering how widespread is the use of the first variant I think I must be missing something.

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

Re: builder pattern

Nicolai Hess
Hi Peter,

2015-04-09 21:20 GMT+02:00 Peter Uhnák <[hidden email]>:
Is there some common / best way for coding builders?

Two ways that I see are:

a) using a block - I've seen this in menus and some other, however in my case I need to add an extra parameter as label

"variant with two params"
aForm addDropList: 'Type' with: [ :dropList |
dropList
items: #(input #output);
" ... ".
].

"variant with one method param and value holder"
aForm addDropList: [ :labelHolder :dropList |
labelHolder value: 'Type'.
dropList
items: #(input #output);
" ... ".
].

b) using return value - no blocks, no extra code
(aForm addDropList: 'Type')
items: #(input #output);
" ... ".

I would use the second variant as it looks much cleaner, however considering how widespread is the use of the first variant I think I must be missing something.

Can you give an example, where the first variant is used.
I don't really understand the use of the valueHolder in the second example. Wouldn't it be cleaner to define a
DropList class /model that has methods for setting the label and items list?

aForm addDropList:[:dropListMode |
  dropListModel setLabel:'...'.
  dropListModel setItems:{ .... }
]


 

Thanks,
Peter

Reply | Threaded
Open this post in threaded view
|

Re: builder pattern

Peter Uhnak
Somehow I missed your response -_-

the first example is based on what is used in MenuModel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ApplicationWithToolbar>>initialize
menu := MenuModel new
addGroup: [ :group |
group addItem: [ :item |
item 
name: 'File';
icon: Smalltalk ui icons openIcon;
subMenu: self subMenu ].
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
it is useful as you don't need to worry about creating new instances of MenuGroup/MenuItem constantly.

The reason for the value holder and why I didn't want to go with creating custom classes is that it would (in my opinion) create extra mess.

What I am trying to achieve is some sort of Form Builder... each item in the form has a label and the form component (which is a spec widget).
Thus I would have to wrap every single spec widget with yet another class so I can set the label.

The second variant (b) is probably the worst (just like any block with >1 arguments)

So maybe the last one is the best fit... this is used by WorldMenu builder.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
menuCommandOn: aBuilder <worldMenu> (aBuilder item: #DynaUML) icon: DCIcons current dcOmlDiagramIcon; label: 'UML Class Diagram'; parent: #MostUsedTools; action: [ self openEmpty ];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Peter

On Wed, Apr 15, 2015 at 10:32 AM, Nicolai Hess <[hidden email]> wrote:
Hi Peter,

2015-04-09 21:20 GMT+02:00 Peter Uhnák <[hidden email]>:
Is there some common / best way for coding builders?

Two ways that I see are:

a) using a block - I've seen this in menus and some other, however in my case I need to add an extra parameter as label

"variant with two params"
aForm addDropList: 'Type' with: [ :dropList |
dropList
items: #(input #output);
" ... ".
].

"variant with one method param and value holder"
aForm addDropList: [ :labelHolder :dropList |
labelHolder value: 'Type'.
dropList
items: #(input #output);
" ... ".
].

b) using return value - no blocks, no extra code
(aForm addDropList: 'Type')
items: #(input #output);
" ... ".

I would use the second variant as it looks much cleaner, however considering how widespread is the use of the first variant I think I must be missing something.

Can you give an example, where the first variant is used.
I don't really understand the use of the valueHolder in the second example. Wouldn't it be cleaner to define a
DropList class /model that has methods for setting the label and items list?

aForm addDropList:[:dropListMode |
  dropListModel setLabel:'...'.
  dropListModel setItems:{ .... }
]


 

Thanks,
Peter


Reply | Threaded
Open this post in threaded view
|

Re: builder pattern

stepharo
Peter

I'm not sure I fully understand your point.
I hope to get some time to go back to clean the menu API and I would like to propose
something in the line of the last examples. Is it what you suggested?


menuCommandOn: aBuilder <worldMenu> (aBuilder item: #DynaUML) icon: DCIcons current dcOmlDiagramIcon; label: 'UML Class Diagram'; parent: #MostUsedTools; action: [ self openEmpty ];


https://github.com/pharo-project/pharo-workingRoadmaps/blob/master/MenuNotes.md
I was thinking that when we do not have a builder
    aMenuMorph
        label: aString;
        ...
        addItem.

and avoid all the block usage.

Stef


Le 1/5/15 17:24, Peter Uhnák a écrit :
Somehow I missed your response -_-

the first example is based on what is used in MenuModel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ApplicationWithToolbar>>initialize
menu := MenuModel new
addGroup: [ :group |
group addItem: [ :item |
item 
name: 'File';
icon: Smalltalk ui icons openIcon;
subMenu: self subMenu ].
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
it is useful as you don't need to worry about creating new instances of MenuGroup/MenuItem constantly.

The reason for the value holder and why I didn't want to go with creating custom classes is that it would (in my opinion) create extra mess.

What I am trying to achieve is some sort of Form Builder... each item in the form has a label and the form component (which is a spec widget).
Thus I would have to wrap every single spec widget with yet another class so I can set the label.

The second variant (b) is probably the worst (just like any block with >1 arguments)

So maybe the last one is the best fit... this is used by WorldMenu builder.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
menuCommandOn: aBuilder <worldMenu> (aBuilder item: #DynaUML) icon: DCIcons current dcOmlDiagramIcon; label: 'UML Class Diagram'; parent: #MostUsedTools; action: [ self openEmpty ];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Peter

On Wed, Apr 15, 2015 at 10:32 AM, Nicolai Hess <[hidden email]> wrote:
Hi Peter,

2015-04-09 21:20 GMT+02:00 Peter Uhnák <[hidden email]>:
Is there some common / best way for coding builders?

Two ways that I see are:

a) using a block - I've seen this in menus and some other, however in my case I need to add an extra parameter as label

"variant with two params"
aForm addDropList: 'Type' with: [ :dropList |
dropList
items: #(input #output);
" ... ".
].

"variant with one method param and value holder"
aForm addDropList: [ :labelHolder :dropList |
labelHolder value: 'Type'.
dropList
items: #(input #output);
" ... ".
].

b) using return value - no blocks, no extra code
(aForm addDropList: 'Type')
items: #(input #output);
" ... ".

I would use the second variant as it looks much cleaner, however considering how widespread is the use of the first variant I think I must be missing something.

Can you give an example, where the first variant is used.
I don't really understand the use of the valueHolder in the second example. Wouldn't it be cleaner to define a
DropList class /model that has methods for setting the label and items list?

aForm addDropList:[:dropListMode |
  dropListModel setLabel:'...'.
  dropListModel setItems:{ .... }
]


 

Thanks,
Peter