Hmm.. this all sounds like a cachemanager approach.
 
In my concept recently, i used a cacheManager, as a composite object within my main controller/manager/listener. In that a Listener/Manager would ask the cacheManager for information pertaining to a record - the cache manager would then do a internal lookup, if the information is not their it would return empty response. The Listener/Manager then would initiate a READ lookup (ie DG/DAO)
 
The cacheManager was always accessed via a facade, in that i had a cacheFacade object which each Listener/Manager would instantiate in its instance scope, the cacheFacade would know where to access a cacheManager itself (ie cacheFacade.getManager() would return application.cacheData.cacheManagerObj).
 
Persk of this approach
-----------------------------------
- cacheFacade could swap and change its scope (application/session) depending on setScope method.. (not a major win but nice one at that).
- cacheManager would only consider instance scope, and knows how to maintain its own internal structure, keeping other scopes out of the picture.
- cacheManager could have settings in place that decide how it operates (setArticleDAO(refXYZDAO), setArticleCacheEnabled(true/false)) etc..
- cacheManager could have singleton instances of objects within itself or object instance pooling capabilities.
 
I implemented a usage state where, for example if a DB Connection were slow or has 10000's of records and you're only likely to use 10% of them - store them inside either memory direct or file. There are a number of ways to do this in that:
 
    - dump to WDDX files.
    - append to an internal Query (ie using QoQ)
    - hashtables (aka Structs)
    - object entities themselves (beans - i've heard this is a major overhead compared to the others but i've not seen any specific evidence which backs this up as yet just speculations).
    - Access a specific VIEW setup in another SQL server? ..
 
As for other shared vs instance, this is where you need to decide in that if you do store reference to beans/businessobjects in memory and somewhere within the application a setXXX() occurs, your "cacheData" will reflect this. This can be bad i guess if you consider that the data may of been set within memory but not updated via the DataLayer (ie your DB doesn't reflect this)
 
Taking that onboard I then ask what gains do you get by storing cached objects within memory? in that why not store "snapshot" of data in memory, then when you have a need to access the object itself, instantiate the BO then initialize that BO with the instance data you have in memory, then pass that object out. This will make a new object each time you need it, while the internal data isn't affected. Then when you're ready to update that information within memory you hand your object back to the cacheManager in an aggressive way (ie updateArticles(articleBO)) - it will simply blow away the key pertaining to your new object information, extract that data from your passed in BO and store that information in the internal memory tree (BO could in this context be a TransferObject,Struct etc up to you on its complexity and weight)
 
The execution of in/out data is entirey up to you in the end, you may simply wish to have the cacheManager handle lastRead data (considered dirty reads) and when you need to extract information from your application, you do so via cacheManager every time. If you do this, you will also need to keep the cachedData uptodate when a new change has made. You can do this via two ways:
 
1) Instead of your Listener/Manager following the typical DAO procedure (ie getArticleDAO().create(articleBO)) it would simply go cacheManager.saveArticle(articleBO)) which would not only do the normal procedure but also update its memory tree.
 
2) Use the typical DAO procedure but also update the cacheManager (ie.. getArticleDAO().create(articleBO)) THEN cacheManager.saveArticle(articleBO)) (i prefer this, as cacheManager can be easily removed down the road)
 
Similiar techniques also could be applied for read:
 
1) cacheManager.getArticle(id) (if recordcount 0, getArticleDAO().read(id))) (preferred method - again, not relying on cacheManager to know about DL).
2) cacheManager.getArticle(id) (it would then do the 1st step internally).
 
point is you can make your cacheManager the overall "Datalayer" manager or you could make it a partial manager but still keep your listener/manager logic to itself - (ie cacheManager is almost an afterthought object).
 
I in the end preferred to keep cacheManager looking after cached data - thats it. Any DB specific needs would be handled by the controller/manager/listener, it would decide what conditions to apply in that if not in memory carry out its own logic else use memory - this way you could design your cacheManager in some really coolways (could become singletonManager, articleCaching).
 
Not sure if this is the correct way, but it held up ok for me and in one final cool point, i could create all sorts of whacky cache techniques but have no affect on the overall core Manager (ie i built caching as an afterthought in the end).
 

Regards,

--------------------------------------------------

Scott Barnes

System Development Engineer

 

Goro Nickel Project
Level 8, 201 Charlotte Street
Brisbane QLD 4000
Email: [EMAIL PROTECTED]

 
--
 
 


From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Micha Schopman
Sent: Tuesday, 11 January 2005 1:40 AM
To: [email protected]
Subject: RE: [CFCDev] Shared persistent objects pattern ?

You are on the right track, but do you think it is smart to let each DAO manage it's own "cached" data? I'd personally look for a generic and central solution, handling all data in a generic way. Providing them with a type of object, and input data. Base on that information, you can create a Hash of the data key.

 

Something like

 

<cfset myobj = createObject("component",article).getArticleById(1)>

 

And within the getArticleById method I might do something like this

 

<cffunction name="getArticleById">

<cfargument name="id">

 

<cfif application.persistancyLayer.getObjectByRef("article",arguments.id)>

            <cfreturn application.persistancyLayer.getObjectByRef("article",arguments.id)>

<cfelse>

            // get data and store into persistancylayer with application.persistancyLayer.setObjectByRef(object,input)

</cfif>

Micha Schopman
Software Engineer

Modern Media, Databankweg 12 M, 3821 AL  Amersfoort
Tel 033-4535377, Fax 033-4535388
KvK Amersfoort 39081679, Rabo 39.48.05.380

-----------------------------------------------------------------------------------------------------------------------------------------------------

Modern Media, Making You Interact Smarter. Onze oplossingen verbeteren de interactie met uw doelgroep.
Wilt u meer omzet, lagere kosten of een beter service niveau? Voor meer informatie zie www.modernmedia.nl
-----------------------------------------------------------------------------------------------------------------------------------------------------

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Marcantonio Silva
Sent: maandag 10 januari 2005
13:15
To: [email protected]
Subject: Re: [CFCDev] Shared persistent objects pattern ?

 

Hi Micha,

 

I'm not working with queries or recordsets in the repository, what I do is that I have a DAO that retrieves the objects

from the database based on the parameter (id for while).

 

The object is then created in the bean and stored in the repository (whish is an application.Structure[id].

 

Next time I come to the repository to get an objects, it's still there.

 

My queries don�t change, since any filters, groups or business logic are managed by the "manager" cfc,

if I need to get a subset of articles, I will get them though the gateway (which returns a query or a list) and then

I get the objects from the repository again.

 

Resuming:

if I need object article id =1 I do:

myArticle = repository.getArticle("1");

 

The repository tries to get it from the application.stArticles["1"], if its not there, gets it from the DAO through the bean by doing:

 

if NOT structKeyExists(application.stArticles,"1")

myArticlenotPersisted =  articleBean.getArticle("1"); (which invokes articleDAO to query the database,  and then maps the query to an article object)

/if

 

and then stores te returned object in the repository application by doing:

 

addToRepository(myArticlenotPersisted ); (here I add a timestamp just to have some metrics)

 

Next time someone wants object article  id = 1, the repository gets it from the application.structure.

 

Getting objects based on property values, as you mentioned, is another feature, that will be managed by the gateway, but I'm not there yet.

 

Here comes a doubt:

Since the object is hold by reference, when someone changes its properties, it will automatically change the shared instance.

I don�t know if this is right behavior, but since we dont have duplicate(object) I guess it will work fine whenever myArticle.setName("new name") is invoked.

 

Regards,

 

 

Marcantonio Silva
Diretor de Desenvolvimento de Produtos - Navita
[EMAIL PROTECTED]
www.navita.com.br
Tel: +55 11 3055.2004
Cel: +55 11 7732.4907 (novo)

 

Reply via email to