Newbie question

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

Newbie question

Olek
Hi,

I am just started to learn and use Dolphin 4. If any1 can comment my
small problem I will be grateful. I made following:


subclass of ShellView where I override onPaintRequired: message with

|canvas|
canvas := aPaintEvent canvas.
canvas
        pen: Pen black
        brush Brush grey,
        ellipse: (Rectangle origin: 0@0 extent 250@150);

Above code is quite working no problem.

So fahr so good. Now question - code "Pen black" is sending message
black to object Pen. I have no idea why Pen is accepting message black
and not for example message yellow.

Pen class understands directly 10 methods ( like color, color: etc. )
but there is no "black" nor "yellow" message. I expect that in this
case when class do not understands message its superclass will  try to
resolve the problem but I am unable to do it by myself. Please advice.


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Ian Bartholomew
Olek,

> I am just started to learn and use Dolphin 4. If any1 can comment my
> small problem I will be grateful. I made following:

Welcome, both to Smalltalk and this group. We're quite friendly here so we
should be able to help....

> So fahr so good. Now question - code "Pen black" is sending message
> black to object Pen.

Yes. #black is being sent to the object Pen, but what _is_ the object Pen.in
this case? If the code was ...

x := Pen new.
x black

then you would be sending the message #black to an _Instance_ of Pen, an
instantiated Pen object created for drawing. However,

Pen black

is sending the message #black to the _Class_  Pen (remember that in
Smalltalk classes are Objects as well) and not an instance of Pen.

> I have no idea why Pen is accepting message black
> and not for example message yellow.
>
> Pen class understands directly 10 methods ( like color, color: etc. )
> but there is no "black" nor "yellow" message.

Taking the above into account you have to look in the list of "class
methods", methods implemented for the class itself and not instance of a
class.

In the ClassBrowser locate the Pen class and then click on the "Class" tab
in the central view.   The first method in the list should be #black.

If you want to create a yellow pen then you will have to have something like
the following  (nb #black is a special System pen so we can't copy the code
for that, use Pen>>blue as a template instead).

yellowPen := Pen color: Color yellow

You could use that inline so your full example would read (with corrected
punctuation)

|canvas|
canvas := aPaintEvent canvas.
canvas
    pen: (Pen color: Color yellow);
    brush Brush grey;
    ellipse: (Rectangle origin: 0@0 extent 250@150)

An alternative would be to add a new _Class_ method to Pen (along the lines
of #blue, #red etc) that answered a yellow Pen. Then your code would just
use

[..]
canvas
    pe: Pen yellow;

Any help?
    Ian


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Olek
Ian,

thank you so much for packed with information answer to my note.
You made it so clear I really do not understand now why it was such a
big problem for me. Shame on me.

I am writing now program that should do something interesting  on the
chessboard. What worries me a lot is when I compaire my clumsy code
with sexy one from the Dolphin I see one big difference. I tend to
make very long methods ( like displaying whole chessboard using only
one method ) I do not know if it is right thing to do in smalltalk,
can you or anybody in this group just name objects they will make for
the chessboard drawing? Any advice will help me.

Olek


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Ian Bartholomew
Olek,

> I am writing now program that should do something interesting  on the
> chessboard. What worries me a lot is when I compaire my clumsy code
> with sexy one from the Dolphin I see one big difference. I tend to
> make very long methods ( like displaying whole chessboard using only
> one method ) I do not know if it is right thing to do in smalltalk,
> can you or anybody in this group just name objects they will make for
> the chessboard drawing? Any advice will help me.

OK. Bit of advice #1 is to try and get hold of a copy of "Smalltalk: Best
practice patterns" by Kent Beck. There is a lot of useful stuff in there
that can help with both the creation of Smalltalk code and the way to think
about how you approach the writing of the code (patterns).

I've attached a very simple package that contains 4 classes that implement
the drawing of a draught board (called checkers in some foreign parts). I've
kept it simple, there are a couple of things that I might not do in the same
way for a "proper" application, but it might give some ideas.

First, create the model. Always a good first step. In this case it will
just be a class that represents the Draught board. It will have one instance
variable, "board", which is a LookupTable containing one entry for each
board position. The board axes are numbered 1 to 8 with 1@1 being at the top
left.  I've made it a subclass of Model simply to use it's behaviour of
automatically evaluating #initialize when it is created.

Model subclass: #DraughtBoard
    instanceVariableNames: 'board'
    classVariableNames: ''
    poolDictionaries: ''
    classInstanceVariableNames: ''

Start with one method, #initialize, to set up the board. Before we do that
though we have to set up the Draught class otherwise
DraughtBoard>>initialize will give errors. The instance variable, "colour"
will contain the colour for the draught.

Object subclass: #Draught
    instanceVariableNames: 'colour'
    classVariableNames: ''
    poolDictionaries: ''
    classInstanceVariableNames: ''

Now add the initialize method

DraughtBoard>>initialize
    super initialize.
    board := LookupTable new.
    1 to: 8 do: [:x |
        1 to: 8 do: [:y |
            board at: x @ y put: nil]].
    "Pieces"
    1 to: 7 by: 2 do: [:x |
        board at: x @ 1 put: Draught white.
        board at: x + 1 @ 2 put: Draught white.
        board at: x @ 3 put: Draught white.
        board at: x + 1 @ 6 put: Draught black.
        board at: x @ 7 put: Draught black.
        board at: x + 1 @ 8 put: Draught black]

This takes us back to your original post as you can see that Draught has two
_class_ methods, #black and #white. We can define those now

Draught class>>white
    ^super new setColour: Color black

Draught class>>white
    ^super new setColour: Color white

and add the _instance_ method that sets the variable for the new object

Draught>>setColour: aColour
    colour := aColour

Like all good models we can now try it without worring about any external
responsibilities. Evaluate

DraughtBoard new inspect

in a workspace and you can look at the DraughtBoard and associated Draughts

Ok. Leave the model for the moment and look at the Presenter/View (as we are
creating a MVP triad). We need two more classes

Presenter subclass: #DraughtBoardPresenter
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    classInstanceVariableNames: ''

View subclass: #DraughtBoardView
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    classInstanceVariableNames: ''

Add one class method to DraughtBoardPresenter

DraughtBoardPresenter class>>defaultModel
    ^DraughtBoard new

This tells DraughtBoardPresenter that, unless it is told otherwise, it needs
to create an new instance of DraughtBoard to use as it's model. The
Presenter and View will both interact with this model, using it to get and
set the board information.

We also now need to execute a bit of code that tells the
DraughtBoardPresenter what kind of View it needs. Copy the following into a
workspace and evaluate it.

DraughtBoardPresenter addView: DraughtBoardView asResource: 'Default view'

Right, now if we evaluate

DraughtBoardPresenter show

we can see that the DraughtBoardPresenter now has acquired a model and a
View of the required type. Drilling down into the View shows that it also
has a Model. NB this is the _same_ instance of DraughtBoard as the
Presenter.

OK. The above just displays an empty View so let's try to fill it. Add
the following to DraughtBoardView

DraughtBoardView>>squareExtent
    ^40@40

This just tells the View that each square of the draught board is 40x40
pixels. Normally we would dynamically compute this as a proportion (1/8) of
the views size, but it complicates things a bit too much for this simple
demo.

Now do the drawing

DraughtBoardView>>onPaintRequired: aPaintEvent
    | canvas |
    canvas := aPaintEventCanvas.
    1 to: 8 do: [:x |
        1 to: 8 do: [:y |
            self model
                draw: x@y
                on: canvas
                within: ((x @ y - 1 * self squareExtent) extent: self
squareExtent)]]

This illustrates a guideline that is used quite often in Smalltalk
"never do yourself what you can get someone else to do". In this case the
View is just asking the DraughtBoard to draw each square on a canvas, within
the rectangular area the view provides. The view doesn't know, or care, how
the DraughtBoard does this, it just expects the board to do as it is told.
NB For simplicity I've assumed that the view knows a draught board is 8x8,
something else that might be a dangerous assumption in the real world.

Aside - As a bit of practice is Smalltalk precedence try to work out what
the last line does and how it does it , step by step.

The above means that we now have to add a method to DraughtBoard

DraughtBoard>>draw: aPoint on: aCanvas within: aRectangle
    "Draw the squares background"
    aCanvas
        fillRectangle: aRectangle
        brush: (Brush color: (self colourOfSquare: aPoint)).
    "Draw the draught, if needed"
    (self hasDraughtAt: aPoint)
        ifTrue: [
            (self draughtAt: aPoint)
                drawOn: aCanvas
                within: aRectangle]

This illustrates a couple of things.
 - We delegate the responsibility of drawing the draught to someone else,
the draught itself ("never do yourself what you can get someone else to do")
 - We add extra methods (below) that do the little jobs like seeing if a
specific square has a draught or not. We could do it inline but it makes
thing easier if you create separate methods. This does seem like a pain at
times but you will find that having methods that do one job, and _only_ one
job, with an appropriate method name, make life easier in the long run.

We need three methods for the above

DraughtBoard>>draughtAt: aPoint
    ^board at: aPoint

DraughtBoard>>hasDraughtAt: aPoint
    ^(self draughtAt: aPoint) notNil

DraughtBoard>>colourOfSquare: aPoint
    ^(aPoint x odd & aPoint y odd) | (aPoint x even & aPoint y even)
        ifTrue: [Color red]
        ifFalse: [Color blue]

One final method. A Draught is being asked to draw itself on a canvas so we
need to tell it how. There's no one else to delegate it to, the buck stops
here <g>

Draught>>drawOn: aCanvas within: aRectangle
    aCanvas
        brush: (Brush color: colour);
        ellipse: (aRectangle insetBy: (aRectangle extent // 8))

And that's it. Evaluating the following should draw a nice Draught board
with pieces

DraughtBoardPresenter show

That enough for now. I haven't gone into any details about how to enter all
this using the Dolphin development environment, hopefully you have already
worked that out for yourself. The attached package is, more or less, the
same as the code above - typos excepted.

Questions, from you or anybody else are welcomed as are pointers to errors
or how it could be done differently [1] from other Dolphinites.

Stage two, tomorrow if I can get round to it, will involve the picking up of
draughts and moving them around.

Ian

[1] Excluding the use of Table Oriented Programming methods of course
























begin 666 draughts.pac
M?"!P86-K86=E('P-"G!A8VMA9V4@.CT@4&%C:V%G92!N86UE.B G9')A=6=H
M=',G+@T*<&%C:V%G92!P87A697)S:6]N.B P.PT*"6)A<VEC0V]M;65N=#H@
M)T1R875G:'1";V%R9%!R97-E;G1E<B!S:&]W)RX-"@T*<&%C:V%G92!B87-I
M8U!A8VMA9V5697)S:6]N.B G)RX-"@T*(D%D9"!T:&4@<&%C:V%G92!S8W)I
M<'1S(@T*#0HB061D('1H92!C;&%S<R!N86UE<RP@;&]O<V4@;65T:&]D(&YA
M;65S+"!G;&]B86P@;F%M97,L(')E<V]U<F-E(&YA;65S(@T*<&%C:V%G92!C
M;&%S<TYA;65S#0H)861D.B C1')A=6=H=#L-"@EA9&0Z("-$<F%U9VAT0F]A
M<F0[#0H)861D.B C1')A=6=H=$)O87)D4')E<V5N=&5R.PT*"6%D9#H@(T1R
M875G:'1";V%R9%9I97<[#0H)>6]U<G-E;&8N#0H-"G!A8VMA9V4@;65T:&]D
M3F%M97,-"@EY;W5R<V5L9BX-"@T*<&%C:V%G92!G;&]B86Q.86UE<PT*"7EO
M=7)S96QF+@T*#0IP86-K86=E(')E<V]U<F-E3F%M97,-"@EY;W5R<V5L9BX-
M"@T*(D)I;F%R>2!';&]B86P@3F%M97,B#0IP86-K86=E(&)I;F%R>4=L;V)A
M;$YA;65S.B H4V5T(&YE=PT*"7EO=7)S96QF*2X-"B)297-O=7)C92!.86UE
M<R(-"G!A8VMA9V4@86QL4F5S;W5R8V5.86UE<SH@*%-E="!N97<-"@EA9&0Z
M("-$<F%U9VAT0F]A<F10<F5S96YT97(@+3X@)T1E9F%U;'0@=FEE=R<[#0H)
M>6]U<G-E;&8I+@T*#0HB061D('1H92!P<F5R97%U:7-I=&4@;F%M97,B#0IP
M86-K86=E('-E=%!R97)E<75I<VET97,Z("A)9&5N=&ET>5-E="!N97<-"@EA
M9&0Z("=$;VQP:&EN)SL-"@EY;W5R<V5L9BDN#0H-"G!A8VMA9V4A#0H-"B)#
M;&%S<R!$969I;FET:6]N<R(A#0H-"D]B:F5C="!S=6)C;&%S<SH@(T1R875G
M:'0-"@EI;G-T86YC959A<FEA8FQE3F%M97,Z("=C;VQO=7(G#0H)8VQA<W-6
M87)I86)L94YA;65S.B G)PT*"7!O;VQ$:6-T:6]N87)I97,Z("<G#0H)8VQA
M<W-);G-T86YC959A<FEA8FQE3F%M97,Z("<G(0T*36]D96P@<W5B8VQA<W,Z
M("-$<F%U9VAT0F]A<F0-"@EI;G-T86YC959A<FEA8FQE3F%M97,Z("=B;V%R
M9"<-"@EC;&%S<U9A<FEA8FQE3F%M97,Z("<G#0H)<&]O;$1I8W1I;VYA<FEE
M<SH@)R<-"@EC;&%S<TEN<W1A;F-E5F%R:6%B;&5.86UE<SH@)R<A#0I0<F5S
M96YT97(@<W5B8VQA<W,Z("-$<F%U9VAT0F]A<F10<F5S96YT97(-"@EI;G-T
M86YC959A<FEA8FQE3F%M97,Z("<G#0H)8VQA<W-687)I86)L94YA;65S.B G
M)PT*"7!O;VQ$:6-T:6]N87)I97,Z("<G#0H)8VQA<W-);G-T86YC959A<FEA
M8FQE3F%M97,Z("<G(0T*5FEE=R!S=6)C;&%S<SH@(T1R875G:'1";V%R9%9I
M97<-"@EI;G-T86YC959A<FEA8FQE3F%M97,Z("<G#0H)8VQA<W-687)I86)L
M94YA;65S.B G)PT*"7!O;VQ$:6-T:6]N87)I97,Z("<G#0H)8VQA<W-);G-T
M86YC959A<FEA8FQE3F%M97,Z("<G(0T*(DQO;W-E($UE=&AO9',B(0T*#0HB
M16YD(&]F('!A8VMA9V4@9&5F:6YI=&EO;B(A#0H-"@T*#0I$<F%U9VAT(&-O
M;6UE;G0Z("<G(0T*#0I$<F%U9VAT(&=U:60Z("A'54E$(&9R;VU3=')I;F<Z
M("=[-D9$0T4T.3 M-$%",2TT-44T+4$Y1#(M1$8Y-C5&04%%1C1%?2<I(0T*
M#0HA1')A=6=H="!C871E9V]R:65S1F]R0VQA<W,A56YC;&%S<VEF:65D(2 A
M#0HA1')A=6=H="!M971H;V1S1F]R(0T*#0ID<F%W3VXZ(&%#86YV87,@=VET
M:&EN.B!A4F5C=&%N9VQE#0H)84-A;G9A<PT*"0EB<G5S:#H@*$)R=7-H(&-O
M;&]R.B!C;VQO=7(I.PT*"0EE;&QI<'-E.B H85)E8W1A;F=L92!I;G-E=$)Y
M.B H85)E8W1A;F=L92!E>'1E;G0@+R\@."DI#0H)"2$-"@T*<V5T0V]L;W5R
M.B!A0V]L;W5R#0H)8V]L;W5R(#H](&%#;VQO=7(A("$-"B%$<F%U9VAT(&-A
M=&5G;W)I97-&;W(Z("-D<F%W3VXZ=VET:&EN.B$J+75N8VQA<W-I9FEE9"%P
M=6)L:6,A("$-"B%$<F%U9VAT(&-A=&5G;W)I97-&;W(Z("-S971#;VQO=7(Z
M(2HM=6YC;&%S<VEF:65D(7!U8FQI8R$@(0T*#0HA1')A=6=H="!C;&%S<R!M
M971H;V1S1F]R(0T*#0IB;&%C:PT*"5YS=7!E<B!N97<@<V5T0V]L;W5R.B!#
M;VQO<B!B;&%C:R$-"@T*=VAI=&4-"@E><W5P97(@;F5W('-E=$-O;&]U<CH@
M0V]L;W(@=VAI=&4A("$-"B%$<F%U9VAT(&-L87-S(&-A=&5G;W)I97-&;W(Z
M("-B;&%C:R$J+75N8VQA<W-I9FEE9"%P=6)L:6,A("$-"B%$<F%U9VAT(&-L
M87-S(&-A=&5G;W)I97-&;W(Z("-W:&ET92$J+75N8VQA<W-I9FEE9"%P=6)L
M:6,A("$-"@T*#0H-"D1R875G:'1";V%R9"!C;VUM96YT.B G)R$-"@T*1')A
M=6=H=$)O87)D(&=U:60Z("A'54E$(&9R;VU3=')I;F<Z("=[1C=#0S(S-C@M
M-D$S.2TT-4(Q+3E!-T8M,#=!044Q0S<T-#(S?2<I(0T*#0HA1')A=6=H=$)O
M87)D(&-A=&5G;W)I97-&;W)#;&%S<R%5;F-L87-S:69I960A("$-"B%$<F%U
M9VAT0F]A<F0@;65T:&]D<T9O<B$-"@T*8V]L;W5R3V93<75A<F4Z(&%0;VEN
M= T*"5XH85!O:6YT('@@;V1D("8@85!O:6YT('D@;V1D*2!\("AA4&]I;G0@
M>"!E=F5N("8@85!O:6YT('D@979E;BD-"@D):694<G5E.B!;0V]L;W(@<F5D
M70T*"0EI9D9A;'-E.B!;0V]L;W(@8FQU95TA#0H-"F1R875G:'1!=#H@85!O
M:6YT#0H)7F)O87)D(&%T.B!A4&]I;G0A#0H-"F1R87<Z(&%0;VEN="!O;CH@
M84-A;G9A<R!W:71H:6XZ(&%296-T86YG;&4-"@DB1')A=R!T:&4@8F%C:V=R
M;W5N9"(-"@EA0V%N=F%S( T*"0EF:6QL4F5C=&%N9VQE.B!A4F5C=&%N9VQE
M#0H)"6)R=7-H.B H0G)U<V@@8V]L;W(Z("AS96QF(&-O;&]U<D]F4W%U87)E
M.B!A4&]I;G0I*2X-"@T*"2)$<F%W('1H92!S<75A<F4B#0H)*'-E;&8@:&%S
M1')A=6=H=$%T.B!A4&]I;G0I#0H)"6EF5')U93H@6PT*"0D)*'-E;&8@9')A
M=6=H=$%T.B!A4&]I;G0I#0H)"0D)9')A=T]N.B!A0V%N=F%S#0H)"0D)=VET
M:&EN.B!A4F5C=&%N9VQE72$-"@T*:&%S1')A=6=H=$%T.B!A4&]I;G0-"@E>
M*'-E;&8@9')A=6=H=$%T.B!A4&]I;G0I(&YO=$YI;"$-"@T*:6YI=&EA;&EZ
M90T*"7-U<&5R(&EN:71I86QI>F4N#0H-"@EB;V%R9" Z/2!,;V]K=7!486)L
M92!N97<N#0H),2!T;SH@."!D;SH@6SIX('P-"@D),2!T;SH@."!D;SH@6SIY
M('P-"@D)"6)O87)D(&%T.B!X($ @>2!P=70Z(&YI;%U=+@T*#0H)(E!I96-E
M<R(-"@DQ('1O.B W(&)Y.B R(&1O.B!;.G@@? T*"0EB;V%R9"!A=#H@>"!
M(#$@<'5T.B!$<F%U9VAT('=H:71E+@T*"0EB;V%R9"!A=#H@>" K(#$@0" R
M('!U=#H@1')A=6=H="!W:&ET92X-"@D)8F]A<F0@870Z('@@0" S('!U=#H@
M1')A=6=H="!W:&ET92X-"@D)8F]A<F0@870Z('@@*R Q($ @-B!P=70Z($1R
M875G:'0@8FQA8VLN#0H)"6)O87)D(&%T.B!X($ @-R!P=70Z($1R875G:'0@
M8FQA8VLN#0H)"6)O87)D(&%T.B!X("L@,2! (#@@<'5T.B!$<F%U9VAT(&)L
M86-K70DA("$-"B%$<F%U9VAT0F]A<F0@8V%T96=O<FEE<T9O<CH@(V-O;&]U
M<D]F4W%U87)E.B$J+75N8VQA<W-I9FEE9"%P=6)L:6,A("$-"B%$<F%U9VAT
M0F]A<F0@8V%T96=O<FEE<T9O<CH@(V1R875G:'1!=#HA*BUU;F-L87-S:69I
M960A<'5B;&EC(2 A#0HA1')A=6=H=$)O87)D(&-A=&5G;W)I97-&;W(Z("-D
M<F%W.F]N.G=I=&AI;CHA*BUU;F-L87-S:69I960A<'5B;&EC(2 A#0HA1')A
M=6=H=$)O87)D(&-A=&5G;W)I97-&;W(Z("-H87-$<F%U9VAT070Z(2HM=6YC
M;&%S<VEF:65D(7!U8FQI8R$@(0T*(41R875G:'1";V%R9"!C871E9V]R:65S
M1F]R.B C:6YI=&EA;&EZ92$J+75N8VQA<W-I9FEE9"%P=6)L:6,A("$-"@T*
M#0H-"D1R875G:'1";V%R9%!R97-E;G1E<B!C;VUM96YT.B G1')A=6=H=$)O
M87)D4')E<V5N=&5R(&%D9%9I97<Z($1R875G:'1";V%R9%9I97<@87-297-O
M=7)C93H@)R=$969A=6QT('9I97<G)R<A#0H-"D1R875G:'1";V%R9%!R97-E
M;G1E<B!G=6ED.B H1U5)1"!F<F]M4W1R:6YG.B G>T4R14)&1#!%+3%%0T,M
M-#8U-2TY,S,V+3A%-44R,D4P0T)&0GTG*2$-"@T*(41R875G:'1";V%R9%!R
M97-E;G1E<B!C871E9V]R:65S1F]R0VQA<W,A56YC;&%S<VEF:65D(2 A#0HA
M1')A=6=H=$)O87)D4')E<V5N=&5R(&-L87-S(&UE=&AO9'-&;W(A#0H-"F1E
M9F%U;'1-;V1E; T*"5Y$<F%U9VAT0F]A<F0@;F5W(2 A#0HA1')A=6=H=$)O
M87)D4')E<V5N=&5R(&-L87-S(&-A=&5G;W)I97-&;W(Z("-D969A=6QT36]D
M96PA*BUU;F-L87-S:69I960A<'5B;&EC(2 A#0H-"@T*#0I$<F%U9VAT0F]A
M<F16:65W(&-O;6UE;G0Z("<G(0T*#0I$<F%U9VAT0F]A<F16:65W(&=U:60Z
M("A'54E$(&9R;VU3=')I;F<Z("=[.$%#.#1&,3@M1C R,RTT-$5%+3DX-# M
M,$8S.#@P-$4S.$-%?2<I(0T*#0HA1')A=6=H=$)O87)D5FEE=R!C871E9V]R
M:65S1F]R0VQA<W,A56YC;&%S<VEF:65D(2 A#0HA1')A=6=H=$)O87)D5FEE
M=R!M971H;V1S1F]R(0T*#0IO;E!A:6YT4F5Q=6ER960Z(&%086EN=$5V96YT
M#0H)?"!C86YV87,@? T*"6-A;G9A<R Z/2!A4&%I;G1%=F5N="!C86YV87,N
M#0H-"@DQ('1O.B X(&1O.B!;.G@@? T*"0DQ('1O.B X(&1O.B!;.GD@?" -
M"@D)"7-E;&8@;6]D96P@#0H)"0D)9')A=SH@>"! ('D-"@D)"0EO;CH@8V%N
M=F%S#0H)"0D)=VET:&EN.B H*'@@0"!Y("T@,2 J('-E;&8@<W%U87)E17AT
M96YT*2!E>'1E;G0Z('-E;&8@<W%U87)E17AT96YT*5U=(0T*#0IS<75A<F5%
M>'1E;G0-"@E>-#! -# A("$-"B%$<F%U9VAT0F]A<F16:65W(&-A=&5G;W)I
M97-&;W(Z("-O;E!A:6YT4F5Q=6ER960Z(65V96YT(&AA;F1L:6YG(7!U8FQI
M8R$@(0T*(41R875G:'1";V%R9%9I97<@8V%T96=O<FEE<T9O<CH@(W-Q=6%R
M945X=&5N="$J+75N8VQA<W-I9FEE9"%P=6)L:6,A("$-"@T*( T*(D)I;F%R
M>2!';&]B86QS(B$-"@T*(E)E<V]U<F-E<R(A#0H-"BA297-O=7)C94ED96YT
M:69I97(@8VQA<W,Z($1R875G:'1";V%R9%!R97-E;G1E<B!N86UE.B G1&5F
M875L="!V:65W)RD@87-S:6=N.B H3V)J96-T(&9R;VU":6YA<GE3=&]R94)Y
M=&5S.@T**$)Y=&5!<G)A>2!F<F]M2&5X4W1R:6YG.B G,C$U,S4T-#(R,#,P
M,C T-C R,$,P,# Q,# P,# P-38V.38U-S<U,C8U-S,V1C<U-S(V,S8U,# P
M,# P,# P13 Q,C0P,#4S-30T,C4R-C4W,S9&-S4W,C8S-C4U,S4T-#(T,C<Y
M-S0V-30Q-S(W,C8Q-SDT,38S-C,V-3<S-S,V1C<R-3 W,C9&-S@W.3 P,# P
M,# P,S8P,# Y,# T,C<Y-S0V-30Q-S(W,C8Q-SDQ13 R,# P,#(Q-3,U-#0R
M,C S,#(P-$4P.#!#,# P03 P,# P,#4S-30T,C4V-CDV-3<W-3 W,C9&-S@W
M.3 P,# P,# P-$4P,C!$,# P,3 P,# P,#4S-30T,C0S-D,V,3<S-S,U,#<R
M-D8W.#<Y,# P,# P,# S-C P,#8P,#4S-S0W,C8Y-D4V-S X,# P,# P-C0W
M,C8Q-S4V-S8X-S0W,SDR,# P,# P,3 P,# P,# T-#<R-C$W-38W-C@W-#0R
M-D8V,3<R-C0U-C8Y-C4W-S(V,# P-3 P-#$W,C<R-C$W.3!#,# P,# P,# P
M,# P,# P,# P,# P,$,R,# P,# P,#(P,# P,# S-C P,$,P,#1#-C$W,C8W
M-C4T.39%-S0V-38W-C4W,C T,# P,# P,# P,# P-#0P,3 P,# P,#8P,# P
M,# P,# P,# P,# P,# P,# P,# P,# P,# P,#4P,# P,# P,# P,# P,# P
M,# P,# P,# P,# P,# P,# P,# P,# V,#$P1C P-$0V-3<S-S,V,38W-C4U
M,S8U-S$W-38U-D4V,S8U,# P,# P,# P13 R,3(P,#4S-30T,C0S-D8V0S9#
M-C4V,S<T-CDV1C9%-3 W,C9&-S@W.3 P,# P,# P-T$P,# P,# P,# P,# P
M,#DR,# P,# P,#<P,# P,# T-#9&-D,W,#8X-CDV13DR,# P,# P,3$P,# P
M,# T1C<R-C0V-3<R-C4V-#0S-D8V0S9#-C4V,S<T-CDV1C9%0S(P,# P,# P
M,3 P,# P,# V,#,P0C P-$0V-3<S-S,V,38W-C4U,S8U-D4V-# P,# P,# P
M,$4P,3!%,# U,S4T-#(U,S<Y-D0V,C9&-D,U,#<R-D8W.#<Y,# P,# P,# Y
M,C P,# P,#$P,# P,# P-C,W,C8U-C$W-#8U-#$W-#-!-C4W.#<T-C4V13<T
M,T%#,C P,# P,# R,# P,# P,#8P,C U,# U,#9&-CDV13<T,# P,# P,# P
M,3 P,# P,# Q,# P,# P1C(P,3 P,# P,# P,# P,$,Y,# P,# P0SDP,# P
M,# V,# P,# P,# V,#$P1C P-3<T.31%-#0T1C4W-3 T0S0Q-#,T-31$-#4T
M134T,# P,# P,# S-C P,#DP,#0R-SDW-#8U-#$W,C<R-C$W.3)#,# P,# P
M,D,P,# P,# P,# P,# P,# P,# P,# P1D9&1D9&1D9&1D9&1D9&1D9&1D9&
M1D9&1D9&1D9&1D8P,# P,# P,# P,# P,# P-C0P,# P,# V-# P,# P,#-!
M,#$P,# P,# P,# P,# U,# Q,# P,$,R,# P,# P,# P,# P,#!&,C Q,# P
M,# P,# P,# P0S$P,# P,#!#,3 P,# P,# P,# P,# P,3,P,# P,# T-C U
M,#0P,# S,# P,# P-#DV,S9&-D4P,# P,# P,# P,# P,# P,3 P,# P,# P
M13 R,3$P,#4S-30T,C4S-CDV138W-D,V-3<T-D8V134P-S(V1C<X-SDP,# P
M,# P,#1%,#(P1# P,#$P,# P,# U,S4T-#(T,S9#-C$W,S<S-3 W,C9&-S@W
M.3 P,# P,# P,S8P,# V,# U,S<T-S(V.39%-C<P-S P,# P,#0T-D8V0S<P
M-C@V.39%,3(P,3 P,# Q.# P,# P,#0Y-D0V,38W-C4U,C8U-D,V,3<T-CDW
M-C8U-#8V.39#-C4T0S9&-C,V,3<T-D8W,C!%,#$P13 P-3,U-#0R-3,W.39$
M-C(V1C9#-3 W,C9&-S@W.3 P,# P,# P,3(P,3 P,# P-S P,# P,#8S-S4W
M,C<R-C4V13<T,3(P,3 P,# P.# P,# P,#4V-CDV-3<W,D4V.38S-D8P13 R
M,48P,#4S-30T,C0U-S@W-#8U-S(V138Q-D,U,C8U-S,V1C<U-S(V,S8U-$,V
M.38R-S(V,3<R-SDU,#<R-D8W.#<Y,# P,# P,# Q,C Q,# P,#$P,# P,# P
M-C0V1C9#-S V.#8Y-D4V-#<R,S S,#,T,D4V-#9#-D,P,# P,# P,"<I*2$-
#"@T*
`
end


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Christopher J. Demers
In reply to this post by Olek
Olek <[hidden email]> wrote in message
news:[hidden email]...
> I am writing now program that should do something interesting  on the
> chessboard. What worries me a lot is when I compaire my clumsy code
> with sexy one from the Dolphin I see one big difference. I tend to
> make very long methods ( like displaying whole chessboard using only
> one method ) I do not know if it is right thing to do in smalltalk,
> can you or anybody in this group just name objects they will make for
> the chessboard drawing? Any advice will help me.

There are many ways this could be done.  I think you could even use the View
Composer to make the board, that might simplify hit testing, etc...  It
depends how much control you want to have over the board.  I don't think
drawing a chess board would be too much for one method, if it was coded
efficiently.  However if you are talking about drawing the chess pieces in
the same method then that is probably a bit too procedural.  Each chess
piece should probably be a different object (It will help your logic to have
it distributed this way as well).  Each piece object could draw themselves
on the board.

I just thought of an interesting way to draw a chessboard using intervals.
I don't remember the parameters of a chess board off hand but this code can
be easily changed (this will do an 11x11 board).  I ran this in a workspace
just to test.  I am not sure if this is the best way to do this, it is just
an idea.

======
shell := Shell show.
shell view extent: 591@600.
canvas := shell view canvas.

horizStep := (shell view clientExtent // 11) x.
vertStep := (shell view clientExtent // 11) y.
horizInterval := Interval from: 1 to: 600 by: horizStep.
vertInterval := Interval from: 1 to: 600 by: vertStep.

mustFill := true.
horizInterval do: [ :horizPos |
    mustFill := mustFill not.
    vertInterval do: [ :vertPos |
        mustFill := mustFill not.
        rect := (Rectangle origin: (horizPos @ vertPos) extent: (horizStep @
vertStep)).
        mustFill
           ifTrue: [canvas rectangle: rect]
           ifFalse: [canvas fillRectangle: rect brush: Brush black]]].
=======

Chris


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Olek
Chris,

I was quite happy with my piece of code but your one shocked me
totally. I spent a lot of time  experimenting till I started to
understand what is going on.
There is very clever step evaluation - clientExtent is a point in
reality so you can for example divide it and still ask for x after
such operation (I was always wondering what sense is in point
arithmetical operations and now I have a perfect example), very nice
really.
I didn't now about Interval  class at all. That's undocumented class
in the Dolphin ( I understand Interval do not need any comment because
is so basic, heh ). In reality I am still not good at collections but
Inspecting objects works like a charm so I know now how nicely "do:"
is working on Interval elements.
To summarize thanks a lot for your note!

P.S. I am quite confident now that method can be big if needed and it
is OK in smalltalk.

Olek


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Christopher J. Demers
Olek <[hidden email]> wrote in message
news:[hidden email]...
...
> I didn't now about Interval  class at all. That's undocumented class
> in the Dolphin ( I understand Interval do not need any comment because
> is so basic, heh ). In reality I am still not good at collections but
...

I am glad that my comments were helpful.  It is important to try to
effectively use the base classes that Smalltalk has to offer. The rich base
classes separate it from many other languages.  If you happen to be bored
one day I suggest just looking through all the classes, you may be amazed by
what you find.

I also suggest that you become familiar with Collections, they are one of
the most powerful areas of Smalltalk. "do" is quite cool, but don't stop
there, learn about collect, select, detect, reject, etc...

Ian also had a very nice in-depth response to your previous message (you may
not have seen it as it is only on 1 of the 3 news servers I use).  If you do
not see it I suggest that you read it on news.totallyobjects.com (it is
there and it is a free server) or have Ian repost it.  I think I like his
approach better than my quick hack.

> P.S. I am quite confident now that method can be big if needed and it
> is OK in smalltalk.

As far as method size I guess I am not as much of a zealot as some people.
I think small methods are better than large methods in general.  However I
think things can also be over complicated if they are broken up too much.
As with everything in life, it just depends on the context.

I have been using Smalltalk for 7 years now, and I am still learning new
things.  I think that is what makes it so fun. ;)

Chris


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Ian Bartholomew
Olek / Chris,

> Ian also had a very nice in-depth response to your previous message (you
> may not have seen it as it is only on 1 of the 3 news servers I use).  If
> you do not see it I suggest that you read it on news.totallyobjects.com
> (it is there and it is a free server) or have Ian repost it.

I think that attaching the packaged code to the message caused it's
disappearance from a number of servers (a growing number I would guess) that
reject all incoming message with binary attachments.  Understandable
because of security restrictions and the 19GB (or something) daily load of
binary newsgroup traffic floating around these days.

If anyone didn't see it (it was one of those outpourings that seem to come
over me occasionally, probably after I've drunk a cup of tea that was brewed
too long) then mail me and I'll send a copy.

> As far as method size I guess I am not as much of a zealot as some people.
> I think small methods are better than large methods in general.  However I
> think things can also be over complicated if they are broken up too much.
> As with everything in life, it just depends on the context.

I try to keep method sizes down, a long method is a flag that some
refactoring is probably needed, but I agree there are times when it can
cause more trouble than it is worth. Another thing I try to do, but don't
always succeed at, is to keep each method at the same abstraction level. Say
that you want to open a file and parse the contents on a line by line basis.

| fs |
fs := FileStream read: 'aFile.txt'.
[fs atEnd] whileFalse: [ | line |
    line := fs next.
   ( line beginsWith: 'Error')
        ifTrue: [Transcript print: line; cr]].
fs close

OK, it's a silly example but you get the idea.... In a proper application I
would probably split that into 3 levels

1) FileStream control

parseFile
    | fs |
    fs := FileStream read: 'File.txt'.
    [self parseStream: fs] ensure: [fs close]

2) Stream contents control

parseStream: aStream
    [aStream atEnd] whileFalse: [self parseLine: aStream next]

3) Parsing the text

parseLine: aString
    (aString beginsWith: 'Error') ifTrue: [Transcript print: line; cr]

To my mind splitting it up so that each method just does one things makes it
more readable, as long as appropriate selectors are used of course. Some
people think the opposite and find the constant swapping between methods a
hindrance.  Whatever....

> I have been using Smalltalk for 7 years now, and I am still learning new
> things.  I think that is what makes it so fun. ;)

Yep, I couldn't agree more. I read those threads in comp.object and
comp.lang.smalltalk where people moan about how much easier it is to
understand/use C++ or whatever and shake my head in disbelief. If they only
knew ... but some people just don't want to listen <g>

Ian


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Olek
In reply to this post by Ian Bartholomew
Ian,

first of all I got your wonderful mail only because of Chris help.
Chris pointed out that it may be I didnt get your mail because there
was an attachment. I first didnt believe in that because on my polish
news server are tons of groups with nacked girls and such kind of
binary stuff. Why on earth I can not get small nice attachment in
comp.lang.smalltalk.dolphin group? But Chris was right for some reason
your e-mail didnt go through. Maybe we should change name from
comp.lang.smalltalk.dolphin to something like:
binaries.sex.nacked.dolphins. In such case we will avoid all
attachments problems in the future :-)

I used free news server  news.totallyobjects.com and got everything no
problem (like Chris suggested).

I must say that I am deeply touched by all what was happening after my
initial mail. I never expected something like that, rather was ready
to be ignored in this news group. Usualy everybody is running after
daily business and do not have much time to help others and even more
write quite complicatted code. Now I have more smalltalk code to go
through than I can handle in one go. ( Hmm, few days for sure or even
more I think now ) This is something really wonderful.
Now going back to your mail -

>OK. Bit of advice #1 is to try and get hold of a copy of "Smalltalk: Best
>practice patterns" by Kent Beck. There is a lot of useful stuff in there

I ordered like you suggested  Smalltalk Best Practice Patterns and
also the The Art and Science of Smalltalk by Simon Lewis

>I've attached a very simple package that contains 4 classes that implement
>the drawing of a draught board (called checkers in some foreign parts).

Wow, great 4 classes for one board, 4 times better then I did with my
one class and one longish method. Lets check like it looks!
Ahh class names are:

Draught, DraughtBoard, DraughtBoardPresenter and DraughtBoardView

Ouch! Thats for sure implementation of Model View Presenter something

I do not undestand at all.( for me MVP sounds like horror heh). Maybe
day come then I should try once again to attack this totally mystic
topic ...
I need time now, unfortunately I am very slow in reading smalltalk
code. Will come back soon

Once again Big Thank You!
Olek


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Olek
In reply to this post by Ian Bartholomew
Ian,

I am still not ready to comment your Draughts code. Working hard to
understand everything.It finished me yesterday and I am slowly
recovering today. I need still some time. Maybe you can try
in the mean time correct my basic understanding of MVP triad. I must
say I still do not get the idea
behind MVP so it is rather my basic non understanding of MVP.

In general I imagine that MVP works like that:

I construct my wonderful piece of smalltalk code called model ( for
example its many megabytes long, super complicated code )thats do
something really great like answers very important question (To be or
not to be for example ). Answer object called answer, the result of
all most complicated computations will hold just yes or no at the end.
The only way to see this important answer is the use of development
tool like inspector to inspect what is inside answer
object, but if I like to distribute my program to non smalltalkers (
and make a lot of cash from it ) I need to present this answer in more
readable and convinient for the enduser form. Because I am so smart i
decided to use famous VP pair in addition to do all the dirty and
complicated work of presenting the end result from my model.
I wrote some additional megabytes of code and now my brand new VP part
is nicely presenting the answer. VP code knows exactly where object
answer resides ( in the model object of course ). It is possibile
because model code was started by VP code. VP even knows when all
computations that model makes are done and answer is ready ( because
VP pair just waits till model finishes, VP just calls model and
resumes operations after model is done ) In other words ( C++ words? )
it is like VP is calling model subroutine and continues execution
after subroutine is finished.

Everything looks fine, I can make big changes to the model code or add
additional code to VP part and all the work can be done by two groups
of programmers that do not know about each other. Everything will
still work correctly  as long as the interface between model and VP -
the answer object  will be the same.

Going back to your Draughts program I see that you have done
everything in one breathtaking go. First model and support class for
the Draught next VP and then additional changes to the model and at
the end to the Draught supporting class. Nice development circle from
the start to the end and again to the start.

But it looks to me like the DraughtBoard model is not totally
separated from presenting functions of VP. Model has a
drawing method. He still knows nothing about the view class but it
will take active role in building the final board
on the screen. Thats a surprise for me. Hmm, kind of tight
cooperation. By analogy my "to be or not to be model"
should then also actively support VP code, but I do not see how it can
be done in my example. Why not move draw:on:within: method to VP and
free model from any presentation responsibilities?


P.S.
What confuses me even more now is description of MVP in

http://www.object-arts.com/Lib/EducationCentre4/htm/view.htm

Where #trigger and #when:send:to: method is described as proper MVP
method in Dolphin 4.

That means MVP implementation in Dolphin 4 is different compared to
Dolphin 2.x or 3.x or I am wrong?


Olek


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

ted.bracht
Hi Olek,

 Maybe you can try

> in the mean time correct my basic understanding of MVP triad. I must
> say I still do not get the idea
> behind MVP so it is rather my basic non understanding of MVP.
>
>
> P.S.
> What confuses me even more now is description of MVP in
>
> http://www.object-arts.com/Lib/EducationCentre4/htm/view.htm
>
> Where #trigger and #when:send:to: method is described as proper MVP
> method in Dolphin 4.
>

A couple of months ago we had a number of interesting threads around MPV,
somebody tried to write a mini-library management application in MPV. Ian
wrote a bit of excellent prosa that explained this #trigger issue very well.
You can find this thread in the newsgroup archives on Ian's website (I think
it was 3rd or 4th quarter 2000). Once you've cracked that, I would suggest
to read the many articles about MPV on the Dolphin wiki.

Good luck.

Ted


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Olek
Ted,

>A couple of months ago we had a number of interesting threads around MPV,
>somebody tried to write a mini-library management application in MPV. Ian
>wrote a bit of excellent prosa that explained this #trigger issue very well.
>You can find this thread in the newsgroup archives on Ian's website (I think
>it was 3rd or 4th quarter 2000). Once you've cracked that, I would suggest
>to read the many articles about MPV on the Dolphin wiki.
>

Thx a lot, I do not expected it is so deep topic, reading now
"Twisting the triad" article by Andy and Blair. Very fascinating story
Dolphin story. My micro problem is nothing compared to designers of
Dolphin many months long struggle. Unfotunately they didnt have such
nice group like that to ask for help <g>.

Will check all archives from the end of 2000

Olek


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Ian Bartholomew
In reply to this post by Olek
Olek,

Sorry for the delay in replying. I wanted to make sure I had enough time to
answer your points (hopefully) without rushing..

> I am still not ready to comment your Draughts code. Working hard to
> understand everything.It finished me yesterday and I am slowly
> recovering today. I need still some time. Maybe you can try
> in the mean time correct my basic understanding of MVP triad. I must
> say I still do not get the idea
> behind MVP so it is rather my basic non understanding of MVP.

It was probably a bit much for you're first taste of MVP but it seemed, at
the time, that it might be useful to give an idea of how an application, or
at least part of one, might be put together in Dolphin.  In retrospect a
slower approach might have been better.

Other than MVP I was also trying to answer a bit more of your original
question - showing how a Smalltalk app is put together from a number of
associated classes and using small, focussed methods.

> In general I imagine that MVP works like that:
>
> I construct my wonderful piece of smalltalk code called model ( for
> example its many megabytes long, super complicated code )thats do
> something really great like answers very important question (To be or
> not to be for example ). Answer object called answer, the result of
> all most complicated computations will hold just yes or no at the end.
> The only way to see this important answer is the use of development
> tool like inspector to inspect what is inside answer
> object, but if I like to distribute my program to non smalltalkers (
> and make a lot of cash from it ) I need to present this answer in more
> readable and convinient for the enduser form. Because I am so smart i
> decided to use famous VP pair in addition to do all the dirty and
> complicated work of presenting the end result from my model.
> I wrote some additional megabytes of code and now my brand new VP part
> is nicely presenting the answer. VP code knows exactly where object
> answer resides ( in the model object of course ). It is possibile
> because model code was started by VP code. VP even knows when all
> computations that model makes are done and answer is ready ( because
> VP pair just waits till model finishes, VP just calls model and
> resumes operations after model is done ) In other words ( C++ words? )
> it is like VP is calling model subroutine and continues execution
> after subroutine is finished.

Hmmm. There is nothing obviously wrong with that paragraph but I feel it
shows that you are missing a lot of the advantages of MVP. That's not a
criticism, it's just that you have to use it for a bit, and get used _to_
it, to be able to appreciate how it helps.

A couple of points that might bear stressing.

An application doesn't just comprise of one, large MVP triad but a lot of
smaller ones that work together. For example, an edit field in a date entry
view is actually an MVP triad (aString (model), aTextEdit (View) and a
TextPresenter) in it's own right. This triad is then linked into a "higher"
composite MVP triad, a "DataEntry"  for instance, which in turn is linked
into an even higher level application (main Model, ShellView and Shell
(Presenter)).

There is a separation between a Model and the View/Presenter. A Model should
work the same whether it has zero, one or multiple associated VP's. The last
but one sentence should read - "VP just calls Model, Model informs
any interested parties via a triggered event when it is done". The Model
should not care if nobody is interested!

> Everything looks fine, I can make big changes to the model code or add
> additional code to VP part and all the work can be done by two groups
> of programmers that do not know about each other. Everything will
> still work correctly  as long as the interface between model and VP -
> the answer object  will be the same.

Yes.

> Going back to your Draughts program I see that you have done
> everything in one breathtaking go. First model and support class for
> the Draught next VP and then additional changes to the model and at
> the end to the Draught supporting class. Nice development circle from
> the start to the end and again to the start.

Not to mention one of the big advantages of Smalltalk, the ability to test
every (well, almost every) step as you go. Something that
ExtremeProgramming, with it's unit tests and refactoring, promotes.

> But it looks to me like the DraughtBoard model is not totally
> separated from presenting functions of VP. Model has a
> drawing method. He still knows nothing about the view class but it
> will take active role in building the final board
> on the screen. Thats a surprise for me. Hmm, kind of tight
> cooperation. By analogy my "to be or not to be model"
> should then also actively support VP code, but I do not see how it can
> be done in my example. Why not move draw:on:within: method to VP and
> free model from any presentation responsibilities?

OK. Good point.

Say you have moved the drawing code from the Draught itself into the View.
Then ...

1) The View has to know a bit more about the Draught. It has to know that
the Draught implements methods that answer it's colour and whether it is a
king or not.  Draught itself has to implement the methods that expose these,
supposedly internal, details.

2) The View will have to know how to draw any item that appears on the
Board. Not too bad for Draughts, more difficult for Chess with the greater
number of different pieces.

3) The View would have to be modified if you wanted to use the board for
games other than Draughts. Reuse is something that plays (or should play) a
big part in MVP

4) Say you wanted to print the board or draw it on a bitmap that could be
sent over the Net. If the View implements the drawing you would have to
implement a BoardPrinter and a BoardBitmap that also knew how to render
Draughts. Putting the drawing code in the Draught means that you can just
pass it an instance of a BitmapCanvas or a PrinterCanvas which the Draught
can draw on using the same code as it used for the ViewCanvas.

The bottom line is that because of the separation between Model and View
there has to be some crossover and allowing the Model to know how to draw
itself on a Canvas that is passed to it is better that giving the View
knowledge of everything that it will have to display.

> What confuses me even more now is description of MVP in
>
> http://www.object-arts.com/Lib/EducationCentre4/htm/view.htm
>
> Where #trigger and #when:send:to: method is described as proper MVP
> method in Dolphin 4.
>
> That means MVP implementation in Dolphin 4 is different compared to
> Dolphin 2.x or 3.x or I am wrong?

I'm not quite sure how you read that into the page you mention.? However,
Dolphin is still evolving and some things that worked one way in earlier
versions now work in a slightly different, and invariably better, way in
later versions. The basic premise - Models trigger events that interested
parties can listen to - is the same in all versions.

Hope that helps a bit
    Ian


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Dave Harris-3
[hidden email] (Ian Bartholomew) wrote (abridged):
> An application doesn't just comprise of one, large MVP triad but a lot
> of smaller ones that work together. For example, an edit field in
> a date view is actually an MVP triad (aString (model), aTextEdit
> (View) and a TextPresenter) in it's own right. This triad is
> then linked into a "higher" composite MVP triad, a "DataEntry"
> for instance, which in turn is linked into an even higher level
> application (main Model, ShellView and Shell (Presenter)).

And most of those objects are stock, off-the-shelf, reusable components.

Olek wrote:
   Answer object called answer, the result of all most complicated
   computations will hold just yes or no at the end.

MVP sounds like a lot of work just to display "Yes" or "No", but it's not
so bad because most of the views, presenters, adaptors etc were already
written for us by Object Arts. We just have to pick the ones we want and
wire them together.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      [hidden email]      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Dave Harris-3
In reply to this post by Ian Bartholomew
[hidden email] (Ian Bartholomew) wrote (abridged):
> The bottom line is that because of the separation between Model and
> View there has to be some crossover and allowing the Model to know
> how to draw itself on a Canvas that is passed to it is better
> that giving the View knowledge of everything that it will have
> to display.

This is judgement call, though. Sometimes it is better to keep the model
"pure". We can still get reusable rendering (and views) if we isolate the
code that does that.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      [hidden email]      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Olek
In reply to this post by Ian Bartholomew
Ian,


>Sorry for the delay in replying. I wanted to make sure I had enough time to
>answer your points (hopefully) without rushing..

I found your web page. Really impressive.

>An application doesn't just comprise of one, large MVP triad but a lot of
>smaller ones that work together.
 
Oh, something clicked in my head. I still had wrong perception. My bad
tendency to write everything in one method or do all UI with one big
MVP instance ..

In reality we have in smalltalk a big pool of smaller parts. Small
parts are more useful because it is easy to reuse them and in the
image there are hundreds of them. I can just make subclasses of model,
presenter and view and cut development time significantly.

> For example, an edit field in a date entry
>view is actually an MVP triad (aString (model), aTextEdit (View) and a
>TextPresenter) in it's own right. This triad is then linked into a "higher"
>composite MVP triad, a "DataEntry"  for instance, which in turn is linked
>into an even higher level application (main Model, ShellView and Shell
>(Presenter)).

Yes I get it now. If for instance I will have an idea to write in
circles I will just use aString-model and TextPresenter-presenter and
will override part of aTextEdit-view and will have MVP triad for
writing in circels that can be used as a part in another MVP.

> Why not move draw:on:within: method to VP and
>> free model from any presentation responsibilities?
>
>OK. Good point.
>
>Say you have moved the drawing code from the Draught itself into the View.
>Then ...
>
>1) The View has to know a bit more about the Draught. It has to know that
>the Draught implements methods that answer it's colour and whether it is a
>king or not.  Draught itself has to implement the methods that expose these,
>supposedly internal, details. ....

Hmm I think now it is much better when Draught knows how it looks ...
If some day I will implement another game and will need Draught I will
just reuse one class. Easy and clean solution.  OK point taken. I was
to strict and didnt understand fully the MVP method. Now I think it is
working this way:

M do not know about  VP pair, but it is totaly valid  if M will know
that there probably is some VP.

I mean by that that M can have some supporting VP methods and it is ok
as long as they are very general and do not need any pointer to real
VP pair.

To follow MVP rules it will be enough if my model will know that there
will be some VP pair so it can have some supporting VP code. From
other side model will not care what kind of VP will be there. So in my
programs it will be totally valid if I implement some
presentation-view knowledge into model. Hmm maybe even foto of
customer will be ok inside customer model and that will still be ok
with MVP rules.  

> Models trigger events that interested
>parties can listen to - is the same in all versions.
>
>Hope that helps a bit
>    Ian
>

Oh I am starting to understand what is going on. You was really of
great help pointing out my blind spots. I will start now to play with
MVP. Without your note, I would try to avoid MVP  as long as it would
be possibile. Hmm...  and I think now it is not possibile in case of
UI and Dolphin.

Now I need to put theory into practice and write some code.

Big Thank You!

Olek


Reply | Threaded
Open this post in threaded view
|

Re: Newbie question

Olek
In reply to this post by Dave Harris-3
Dave,


>
>MVP sounds like a lot of work just to display "Yes" or "No", but it's not
>so bad because most of the views, presenters, adaptors etc were already
>written for us by Object Arts. We just have to pick the ones we want and
>wire them together.

I was of course exaggerating a little but in reality it was my call
for help. I was very near the understanding but still blundering.
Ian wonderfully pointed out what is wrong with my thinking  and I
instantly like by magic saw "the light". <g>

Sentence " a lot of small pieces ..." was the key to Olek's mind

Thank you for your answer, you are right of course

Olek