Hi Tim,

I'm not clear on which of your methods are instance-side or
class-side. Can you clarify this using the form..
XYZRecords >> filterByYear  -- for instance side
XYZRecords class >> filterByYear  -- for class side

I'm not overly familiar with Seaside or Design Pattern architectures,
but it seems you want multiple filter instances accessing one copy of
the data.  So maybe try putting your data in a class variable.
Something like this...

Object subclass: #XYZRecords
    instanceVariableNames: 'filterBlock'
    classVariableNames: 'Data'
    ...

XYZRecords class >> readFromCSVFile: aFile
    Data := OrderedCollection new.
    "for all lines from file..."
         Data add: ......

XYZRecords >> filterByYear: aYear
    filterBlock := [ :ea | ea year = aYear]

XYZRecords>>records
     ^ Data select: filterBlock

XYZRecords class >> filterByYear:  aYear
    ^self new filterByYear:  aYear


_Example usage_

XYZRecords readFromCSVFile: '~user/data.csv'.

recordset1 := XYZRecords filterByYear: 1971
recordset2 := XYZRecords filterByYear: 2000

recordset1 records inspect.
recordset2 records inspect.

No need to necessarily reset the filter.  You might just throw the
recordset instance away.

cheers -ben

On Fri, May 13, 2016 at 1:01 AM, Tim Johnson <di...@sonic.net> wrote:
> 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
> Beginners@lists.squeakfoundation.org
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
_______________________________________________
Beginners mailing list
Beginners@lists.squeakfoundation.org
http://lists.squeakfoundation.org/mailman/listinfo/beginners

Reply via email to