Class side vs instance side

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

Class side vs instance side

Peter Uhnak
Hi,

I am trying to figure out where to best place some mapping/data/stable methods.

For example imagine method
~~~~~~~~~~~~~~~~~~~~~
MyRectangle>>oppositeSides
    ^ { #top -> #bottom.
#bottom -> #top.
#topLeft -> #bottomRight
....
} asDictionary
~~~~~~~~~~~~~~~~~~~~

And then the class might have some other related methods such as
~~~~~~~~~~~
MyRectangle>>oppositeSideFor: aSide
    ^ self oppositeSides at: aSide
~~~~~~~~~~~~

So it's a method returning a mapping between opposite sides/corners and thus is really not going to change.
Now I could place this in instance-side and create a new instance every time I wanted to use it (which doesn't seem practical), or I could put it in class-side.
The problem I have with class-side is that naming is more like going through minefield (more than once I corrupted my image by naming a method or variable something I shouldn't have), and for whatever reason it feels like either metaprogramming or procedural programmming... That class side methods are pretty much global functions/variables... and short of constructors I am avoiding static methods even in other languages... but maybe using it is ok. Or maybe have it object an use singleton?

The only oop-like approach I see would be to extend symbols (#top oppositeSide), or have separate objects for sides, but that seems like overkill.

MySide subclass: #Top

Top>>oppositeSide
    ^ Bottom new

Are there any best practices regarding this? This is also true for actual data stored in methods/attributes (such as icons).

P.s.: For english natives... Should the second method be ned "oppositeSideOf:" or "oppositeSideFor:"?

Any ideas/pointers appreciated,
Peter
Reply | Threaded
Open this post in threaded view
|

Re: Class side vs instance side

Ben Coman
Even if you put the method on the class-side, you would still be
creating an new instance each time.  Maybe you can store it in a class
variable...

    MyRectangle>>oppositeSides
        ^ oppositeSides ifNil: [ oppositeSidesCache := { #top -> #bottom.
    #bottom -> #top.
    #topLeft -> #bottomRight
    ....
    } asDictionary ].

cheers -ben

On Thu, Jul 23, 2015 at 8:40 AM, Peter Uhnak <[hidden email]> wrote:

> Hi,
>
> I am trying to figure out where to best place some mapping/data/stable
> methods.
>
> For example imagine method
> ~~~~~~~~~~~~~~~~~~~~~
> MyRectangle>>oppositeSides
>     ^ { #top -> #bottom.
> #bottom -> #top.
> #topLeft -> #bottomRight
> ....
> } asDictionary
> ~~~~~~~~~~~~~~~~~~~~
>
> And then the class might have some other related methods such as
> ~~~~~~~~~~~
> MyRectangle>>oppositeSideFor: aSide
>     ^ self oppositeSides at: aSide
> ~~~~~~~~~~~~
>
> So it's a method returning a mapping between opposite sides/corners and thus
> is really not going to change.
> Now I could place this in instance-side and create a new instance every time
> I wanted to use it (which doesn't seem practical), or I could put it in
> class-side.
> The problem I have with class-side is that naming is more like going through
> minefield (more than once I corrupted my image by naming a method or
> variable something I shouldn't have), and for whatever reason it feels like
> either metaprogramming or procedural programmming... That class side methods
> are pretty much global functions/variables... and short of constructors I am
> avoiding static methods even in other languages... but maybe using it is ok.
> Or maybe have it object an use singleton?
>
> The only oop-like approach I see would be to extend symbols (#top
> oppositeSide), or have separate objects for sides, but that seems like
> overkill.
>
> MySide subclass: #Top
>
> Top>>oppositeSide
>     ^ Bottom new
>
> Are there any best practices regarding this? This is also true for actual
> data stored in methods/attributes (such as icons).
>
> P.s.: For english natives... Should the second method be ned
> "oppositeSideOf:" or "oppositeSideFor:"?
>
> Any ideas/pointers appreciated,
> Peter

Reply | Threaded
Open this post in threaded view
|

Re: Class side vs instance side

Peter Uhnak
Cache of the mapping is just an implementation detail.

I was referring to the instance of the ==MyRectangle== object;
so I am more interested in this from outside perspective --- other objects that will have to use the API...

So whether I would call
[[[
"class-side methods"
MyRectangle oppositeSideOf: #top "-> #bottom"

"instance side"
MyRectangle new oppositeSideOf: #top

"singleton"
MyRectangle instance oppositeSideOf: #top

"extending symbols"
#top oppositeSide

"a lot of classes"
Top "new/instance/whatever" oppositeSide "-> a Bottom instance/class"

" or something (completely) different?"
]]]

Peter


On Thu, Jul 23, 2015 at 2:18 PM, Ben Coman <[hidden email]> wrote:
Even if you put the method on the class-side, you would still be
creating an new instance each time.  Maybe you can store it in a class
variable...

    MyRectangle>>oppositeSides
        ^ oppositeSides ifNil: [ oppositeSidesCache := { #top -> #bottom.
    #bottom -> #top.
    #topLeft -> #bottomRight
    ....
    } asDictionary ].

cheers -ben

On Thu, Jul 23, 2015 at 8:40 AM, Peter Uhnak <[hidden email]> wrote:
> Hi,
>
> I am trying to figure out where to best place some mapping/data/stable
> methods.
>
> For example imagine method
> ~~~~~~~~~~~~~~~~~~~~~
> MyRectangle>>oppositeSides
>     ^ { #top -> #bottom.
> #bottom -> #top.
> #topLeft -> #bottomRight
> ....
> } asDictionary
> ~~~~~~~~~~~~~~~~~~~~
>
> And then the class might have some other related methods such as
> ~~~~~~~~~~~
> MyRectangle>>oppositeSideFor: aSide
>     ^ self oppositeSides at: aSide
> ~~~~~~~~~~~~
>
> So it's a method returning a mapping between opposite sides/corners and thus
> is really not going to change.
> Now I could place this in instance-side and create a new instance every time
> I wanted to use it (which doesn't seem practical), or I could put it in
> class-side.
> The problem I have with class-side is that naming is more like going through
> minefield (more than once I corrupted my image by naming a method or
> variable something I shouldn't have), and for whatever reason it feels like
> either metaprogramming or procedural programmming... That class side methods
> are pretty much global functions/variables... and short of constructors I am
> avoiding static methods even in other languages... but maybe using it is ok.
> Or maybe have it object an use singleton?
>
> The only oop-like approach I see would be to extend symbols (#top
> oppositeSide), or have separate objects for sides, but that seems like
> overkill.
>
> MySide subclass: #Top
>
> Top>>oppositeSide
>     ^ Bottom new
>
> Are there any best practices regarding this? This is also true for actual
> data stored in methods/attributes (such as icons).
>
> P.s.: For english natives... Should the second method be ned
> "oppositeSideOf:" or "oppositeSideFor:"?
>
> Any ideas/pointers appreciated,
> Peter


Reply | Threaded
Open this post in threaded view
|

Re: Class side vs instance side

Nicolai Hess


2015-07-23 14:33 GMT+02:00 Peter Uhnák <[hidden email]>:
Cache of the mapping is just an implementation detail.

I was referring to the instance of the ==MyRectangle== object;
so I am more interested in this from outside perspective --- other objects that will have to use the API...

So whether I would call
[[[
"class-side methods"
MyRectangle oppositeSideOf: #top "-> #bottom"

"instance side"
MyRectangle new oppositeSideOf: #top

"singleton"
MyRectangle instance oppositeSideOf: #top

"extending symbols"
#top oppositeSide

"a lot of classes"
Top "new/instance/whatever" oppositeSide "-> a Bottom instance/class"

" or something (completely) different?"
]]]

Peter



All of them, except the second and third. Depending on the use case.
- the clean solution, make a concept (edge/corner) a class.
- if it is common to denote edges/corner by symbols, extend Symbol
- if this is all about Rectangles, put it into rectangle CLASS
- if you have to create a Rectangle instance, just to call a method, where the returned value does not depend on the instance -> then the code is wrong :)

And of course, you should ask yourself: If the mapping has to be accessible from the outside, maybe my code is wrong
and all users of this mapping should have been methods of the Rectangle class instead.


nicolai

 

On Thu, Jul 23, 2015 at 2:18 PM, Ben Coman <[hidden email]> wrote:
Even if you put the method on the class-side, you would still be
creating an new instance each time.  Maybe you can store it in a class
variable...

    MyRectangle>>oppositeSides
        ^ oppositeSides ifNil: [ oppositeSidesCache := { #top -> #bottom.
    #bottom -> #top.
    #topLeft -> #bottomRight
    ....
    } asDictionary ].

cheers -ben

On Thu, Jul 23, 2015 at 8:40 AM, Peter Uhnak <[hidden email]> wrote:
> Hi,
>
> I am trying to figure out where to best place some mapping/data/stable
> methods.
>
> For example imagine method
> ~~~~~~~~~~~~~~~~~~~~~
> MyRectangle>>oppositeSides
>     ^ { #top -> #bottom.
> #bottom -> #top.
> #topLeft -> #bottomRight
> ....
> } asDictionary
> ~~~~~~~~~~~~~~~~~~~~
>
> And then the class might have some other related methods such as
> ~~~~~~~~~~~
> MyRectangle>>oppositeSideFor: aSide
>     ^ self oppositeSides at: aSide
> ~~~~~~~~~~~~
>
> So it's a method returning a mapping between opposite sides/corners and thus
> is really not going to change.
> Now I could place this in instance-side and create a new instance every time
> I wanted to use it (which doesn't seem practical), or I could put it in
> class-side.
> The problem I have with class-side is that naming is more like going through
> minefield (more than once I corrupted my image by naming a method or
> variable something I shouldn't have), and for whatever reason it feels like
> either metaprogramming or procedural programmming... That class side methods
> are pretty much global functions/variables... and short of constructors I am
> avoiding static methods even in other languages... but maybe using it is ok.
> Or maybe have it object an use singleton?
>
> The only oop-like approach I see would be to extend symbols (#top
> oppositeSide), or have separate objects for sides, but that seems like
> overkill.
>
> MySide subclass: #Top
>
> Top>>oppositeSide
>     ^ Bottom new
>
> Are there any best practices regarding this? This is also true for actual
> data stored in methods/attributes (such as icons).
>
> P.s.: For english natives... Should the second method be ned
> "oppositeSideOf:" or "oppositeSideFor:"?
>
> Any ideas/pointers appreciated,
> Peter



Reply | Threaded
Open this post in threaded view
|

Re: Class side vs instance side

stepharo
In reply to this post by Peter Uhnak
What I like with having class is that you can attach behavior

aTop opposite
  ->  aBottom

Le 23/7/15 02:40, Peter Uhnak a écrit :
Hi,

I am trying to figure out where to best place some mapping/data/stable methods.

For example imagine method
~~~~~~~~~~~~~~~~~~~~~
MyRectangle>>oppositeSides
    ^ { #top -> #bottom.
#bottom -> #top.
#topLeft -> #bottomRight
....
} asDictionary
~~~~~~~~~~~~~~~~~~~~

And then the class might have some other related methods such as
~~~~~~~~~~~
MyRectangle>>oppositeSideFor: aSide
    ^ self oppositeSides at: aSide
~~~~~~~~~~~~

So it's a method returning a mapping between opposite sides/corners and thus is really not going to change.
Now I could place this in instance-side and create a new instance every time I wanted to use it (which doesn't seem practical), or I could put it in class-side.
The problem I have with class-side is that naming is more like going through minefield (more than once I corrupted my image by naming a method or variable something I shouldn't have), and for whatever reason it feels like either metaprogramming or procedural programmming... That class side methods are pretty much global functions/variables... and short of constructors I am avoiding static methods even in other languages... but maybe using it is ok. Or maybe have it object an use singleton?

The only oop-like approach I see would be to extend symbols (#top oppositeSide), or have separate objects for sides, but that seems like overkill.

MySide subclass: #Top

Top>>oppositeSide
    ^ Bottom new

Are there any best practices regarding this? This is also true for actual data stored in methods/attributes (such as icons).

P.s.: For english natives... Should the second method be ned "oppositeSideOf:" or "oppositeSideFor:"?

Any ideas/pointers appreciated,
Peter