It seems to me that Smalltalkers are not very fond of constructors and I can't comprehend why.
If for example I want to create object X that _needs_ object Y, then I would have to make a Y accessor. X>>y: anY y := anY but this makes no sense as I can still change the `y` object at later date breaking everything. An alternative is having: X>>initializeWithY: anY y := anY. self initialize. X>>y: anY ^ self basicNew initalizeWithY: anY. However I see only 59 initializeWith* methods (in about 6 packages) compared to 2302 initialize methods. Thus I am deducing that doing this is not very common. Am I missing something or am I trying to unnecessarily constraint the user and I should just trust™ him that he knows what he should use? As a user of an interface I would prefer not to have useless things available that would just break things. Thanks, Peter |
First I would like to make the distinction between user as the user of an application and user as the user of an object.
How we program has to do more with the user as a programmer using an object. In that case I program assuming the programmers that will use my object know what they are doing. Because I can't do anything otherwise. Another thing is that restricting access to a variable makes sense for code that uses the object (telling them not to mess or change this variable) but that restriction does not make sense for other kind of objects: Factories, constructor methods, editor objects, etc. |
In reply to this post by Peter Uhnak
There are other conventions like: * set... * Delay class >> forMilliseconds: aNumber ^ self new setDelay: aNumber forSemaphore: Semaphore new * initializeFor... * DynamicMessageImplementor class>>#for:in: ^ self new initializeFor: aMessage in: aClass * from:to:... * Bezier2Segment class>>#from:to:via: ^self new from: startPoint to: endPoint via: viaPoint I dug a bit to produce this script so you can view more yourself... protocols := (Protocol allInstances select: [ :p | p name = 'instance creation' ]) flatCollect: [ :p | p methods ]. methods := protocols select: [ :m | (m occurrencesOf: $:) > 1 ]. implementors := methods flatCollect: [ :m | m implementors ]. constructorExamples := implementors select: [ :i | (i sourceCode includesAll: 'new') or: [ i sourceCode includesAll: 'basicNew' ] ]. cheers -ben On Sat, May 2, 2015 at 9:02 PM, Peter Uhnák <[hidden email]> wrote:
|
Hi
Kent Beck came up with some useful idioms in his book Smalltalk Best Practice Patterns. One of them was the 'Creation Parameter Method' which is basically the "set" based initialisation method (which Ben mentioned below). This idiom used in conjunction with the "Complete Creation Method" I believe helps communicate "how can I create a valid instance?" to users of your objects. Cheers Carlo On 02 May 2015, at 4:52 PM, Ben Coman <[hidden email]> wrote: There are other conventions like: * set... * Delay class >> forMilliseconds: aNumber ^ self new setDelay: aNumber forSemaphore: Semaphore new * initializeFor... * DynamicMessageImplementor class>>#for:in: ^ self new initializeFor: aMessage in: aClass * from:to:... * Bezier2Segment class>>#from:to:via: ^self new from: startPoint to: endPoint via: viaPoint I dug a bit to produce this script so you can view more yourself... protocols := (Protocol allInstances select: [ :p | p name = 'instance creation' ]) flatCollect: [ :p | p methods ]. methods := protocols select: [ :m | (m occurrencesOf: $:) > 1 ]. implementors := methods flatCollect: [ :m | m implementors ]. constructorExamples := implementors select: [ :i | (i sourceCode includesAll: 'new') or: [ i sourceCode includesAll: 'basicNew' ] ]. cheers -ben On Sat, May 2, 2015 at 9:02 PM, Peter Uhnák <[hidden email]> wrote:
|
But remember that it was before new invoke initialized was
introduced.
We introduced back in squeak because it helps newcomers: they do not have to understand metaclass the first day. Stef Le 4/5/15 00:40, Carlo a écrit :
Hi |
Free forum by Nabble | Edit this page |