Hello Squeakers,

It is cool that we have this forum for asking these kinds of questions.

-- TL;DR -- I learned I probably shouldn't subclass a singleton even though it 
seemed so easy;  I wonder instead how to design my controller properly in an 
MVC paradigm;  should I learn about Factory methods and add them to my 
singleton?;  should I keep query methods out of my data-holding Singletons and 
move them to new Presenter objects as intermediaries between data-holding 
Singletons and views?; should I read a book?; should I give up and go home?.

-- THE TASK -- I am working on a little Seaside app for my job, with a maximum 
of ~4 simultaneous users.  It started as skunkworks but has proved kind of 
useful.  My model has a couple of singletons for a couple of collections of 
data represented as (say) MyRecords or XYZRecords.  Singletons seemed good 
because the source materials being parsed into these records are ~4.0 MB 
apiece, so I don't want multiple copies of the data hanging around, and I only 
need read-only access.

Maybe the singletons could be described like this:

#MyReader class
   "Singleton;  Reads some CSV or other formats;  parses into MyRecords; makes 
collections of MyRecords available using different query methods"



For a quick-and-dirty solution to get a demo up-and-running to show my boss, I 
subclassed one of my Singletons (oh no!) as FilteredMyReader and added 
#filterByYear:, #filterBlock:, and #resetFilter methods. Inside this subclass, 
I just overrode the accessor for the XYZRecords to something like this:

#records
^ records select: (self filterBlock)

with some helper methods: 

#filterByYear: aYear
self filterBlock: [:ea | ea year = aYear]


... and #resetFilter ...

self filterBlock: [:ea | true ]

With these new methods in my subclass, I had a drop-in replacement for my 
MyReader.  It worked great!  All of my query-style and-reporting-style methods 
were still available (because it is a subclass), but because the accessor 
method now was filtered, they showed only the data I wanted.  Woo-hoo!

-- BUT THERE CAME TO BE A PROBLEM -- the big problem arose when multiple 
sessions (multiple users) were accessing the app at the same time.  Seasoned 
Smalltalk vets are sure to chuckle to themselves now, but I am not exactly sure 
why this happened (subclassing singletons is not threadsafe?).  I think when 
one session would change the filterBlock, it would affect another session's 
view into the data.  So one user may be intending to view 2016 but it may 
actually show 2012.  (When designing this quick-and-dirty solution, I may have 
mistakenly thought that each Session had a new instance of my new 
FilteredMyReader subclass, but probably not [!], because it was a subclass of a 
singleton [!]).

So, I have reached the philosophical point where I get to ask "is this is a bug 
in my implementation, or a flaw in my design?"  A quick Google of "subclass a 
singleton" brings up a number of results akin to "don't do this, but if you 
have to, here's how: " so I think my quick-and-dirty solution might be at fault.

-- SO -- as I ponder whether the flaw is in my implementation or my design, I 
question whether the proper approach   and a working solution would be to stop 
subclassing the Singleton and instead do one of the following:

1) In the Singleton, keep my query/reporting methods, but instead of returning 
Bags or OrderedCollections or what-have-you, have them manufacture (like a 
Factory?) instances of a to-be-created class of object which would be like a 
'looking glass' into the data, like an intermediary between the Seaside 
component and the model.  Not sure what the terminology would be -- Presenter?  
Controller?  I think "Art and Science of Smalltalk" (Simon Lewis) might have 
called it a Presenter or a PluggableSomething.

2) Similar to (1) but skip any interaction between the Singleton and the 
View/Session altogether.   Create a new XYZPresenter or Controller or 
PluggableSomething class which can have many instances around, without holding 
copies of the Singleton's data.  Create these on-demand from my WASession 
subclass (controller) or in my components (view).  These new objects will 
interact with the Singleton themselves in a read-only fashion.  

3) Give up on Singletons for holding data and keep this stuff in a database 
outside of the image.  My coworkers want a traditional relational database 
anyway.

After writing all of this up, I am still a bit confused how to proceed, because 
the HPI Seaside tutorial I read many years ago says a WASession subclass is 
supposed to be my "Controller."  So maybe I should leverage /it/ more to access 
the singletons / model (without storing copies of the data!).  But maybe I 
still would be best served by creating an additional intermediary between my 
WASession subclass (as controller) and the Singletons (as /part/ of the model).

I hope this wasn't too much to follow, and might prove fun and instructive for 
someone. (Please note that while I may make references to what may be some 
Design Patterns, I haven't fully read the books or the Smalltalk companion, so 
I am speaking only with some infantile understanding of what I am talking 
about.)

Thanks,
Tim


_______________________________________________
Beginners mailing list
[email protected]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

Reply via email to