Repository Pattern & Collection Interface

Posted by Phillip Magnay on 13-Nov-2006 17:04

With the introduction of OO language features in the ABL, tried and proven OO design patterns can now be more readily leveraged in the development of OpenEdge applications. Discussion of some of the more common OO design patterns can also serve as a useful way of introducing more OO concepts to the PSDN/OpenEdge community. One of the more common and simpler OO design patterns is the Repository pattern.

The Repository Pattern is a very popular way to abstract a domain model from the underlying data mapping and data access by providing access to domain objects (business objects) via a collection interface. For example, the business objects can form collections under a single repository object such as:

end interface.

The data access/mapping and data update for the domain objects in these collections is performed by an underlying set of Data Access Objects.

There has been some prior debate about the pros and cons of a true domain model approach versus a static business object approach. I would be very interested to hear people's experiences with the domain model approach if they have tried it - both good and bad, and people's thoughts about the benefits and drawbacks.

Phil

All Replies

Posted by Thomas Mercer-Hursh on 13-Nov-2006 18:42

With the introduction of OO language features in the ABL, tried and proven OO design patterns can now be more readily leveraged in the development of OpenEdge applications.

Only if people starting writing .cls files instead of .p, .i, and .w ... which doesn't seem to be a very broad movement yet. Still, I heartily applaud your point.

The Repository Pattern is a very popular way to abstract a domain model from the underlying data mapping and data access by providing access to domain objects (business objects) via a collection interface.

I'm not sure that we are starting off with the same sense about what a Repository is all about. It is the Finder and Mapper (or other versions of implementing the data access layer) which provide the abstraction and isolation of the domain model from the data access. To me, the function of a Repository is more that of a cache.

"A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection." from http://www.martinfowler.com/eaaCatalog/repository.html

In this sense, the Repository provides a function not unlike the -B database cache, isolating the program which is using or creating the data from the need to manage the actual physical update to and from disk.

Thus, it seems to me that a Repository is, in effect, a Collection with an active hidden aspect in which it manages the persistence of any changes made to it. This means that we have two different questions or topics here, i.e., the Collection itself, and any issues related to this behind-the-scenes synchronization.

Collections as such are unquestionably useful, even necessary in some form. This is one of the reasons why one of my first framework projects in 10.1A was a set of generic Collection and Map Classes ( http://www.oehive.org/CollectionClasses ). The biggest negative about that implementation is simply a certain inelegance which results from not having generics and/or object versions of primitives so that one needs rather more specific classes than one would wish.

The one issue of "taste" I see about the use of generic Collection Classes like this versus domain-specific Collection Classes is the necessity of casting the generic object in the collection to a specific domain before being able to do operations on it. The flip side is that a handful of Collection and Map classes suffice to handle a very large percentage of the need at a huge savings in development and a great uniformity of operation.

As to the hidden operations, I think this depends a great deal on context. If one has a collection of ... to take a potential example from the AuthEdge context ... Dealers, i.e., something that one expects to remain highly static and where there might be a need to validate and drill down while in a context where dealer information would need to come remotely, then a Repository seems like a good solution. It can be primed at start up or first use.

Off the cuff, I would say that the big potential issue with an "active" collection would be transaction atomicity on updates. If I make a change to an object in a local collection with the expectation of this change being persisted, do I really want to rely on some behind the scenes update process or do I want to use an explicit SaveChanges operation on the domain object which can be directly enclosed within a transaction including any related or dependent changes. My inclinations, being paranoid, leans toward the latter.

Perhaps you are getting at something else, however?

Posted by Phillip Magnay on 13-Nov-2006 19:13

The Repository Pattern is a very popular way to

abstract a domain model from the underlying data

mapping and data access by providing access to domain

objects (business objects) via a collection

interface.

I'm not sure that we are starting off with the same

sense about what a Repository is all about. It is

the Finder and Mapper (or other versions of

implementing the data access layer) which provide the

abstraction and isolation of the domain model from

the data access. To me, the function of a Repository

is more that of a cache.

Yes, but whichever underlying data access/caching mechanism that is used, the domain model is still presented as a conceptually simple set of of collections accessed from a root Repository object. Sure, these objects in these collections could be cached... or if not yet resident in cache then retrieved from the database into a cache.

"A Repository mediates between the domain and data

mapping layers, acting like an in-memory domain

object collection." from

http://www.martinfowler.com/eaaCatalog/repository.html

That's right. There's a number of Fowler's patterns that I believe are relevant and could be readily applied in an implementation of OERA-based OpenEdge application.

In this sense, the Repository provides a function not

unlike the -B database cache, isolating the program

which is using or creating the data from the need to

manage the actual physical update to and from disk.

That's a great analogy... especially for those folks more familiar with traditional Progress/OpenEdge than OO. The collection interface approach to accessing domain objects is also conceptually significant.

Thus, it seems to me that a Repository is, in effect,

a Collection with an active hidden aspect in which it

manages the persistence of any changes made to it.

This means that we have two different questions or

topics here, i.e., the Collection itself, and any

issues related to this behind-the-scenes

synchronization.

Sure.

Collections as such are unquestionably useful, even

necessary in some form. This is one of the reasons

why one of my first framework projects in 10.1A was a

set of generic Collection and Map Classes (

http://www.oehive.org/CollectionClasses ). The

biggest negative about that implementation is simply

a certain inelegance which results from not having

generics and/or object versions of primitives so that

one needs rather more specific classes than one would

wish.

It certainly would be nice to have generics and/or more suitable primitive data types in the ABL to make the implementation of collections a little less awkward (although I've read several harsh criticisms of generics). Some syntactic sugar which would certainly be nice to have. But a saving grace would be that if the implementation faithfully follows the model, then regenerating the code from the model to a later version of ABL should be reasonably straight forward.

The one issue of "taste" I see about the use of

generic Collection Classes like this versus

domain-specific Collection Classes is the necessity

of casting the generic object in the collection to a

specific domain before being able to do operations on

it. The flip side is that a handful of Collection

and Map classes suffice to handle a very large

percentage of the need at a huge savings in

development and a great uniformity of operation.

Casting to the generic object is not ideal but it works.

As to the hidden operations, I think this depends a

great deal on context. If one has a collection of

... to take a potential example from the AuthEdge

context ... Dealers, i.e., something that one expects

to remain highly static and where there might be a

need to validate and drill down while in a context

where dealer information would need to come remotely,

then a Repository seems like a good solution. It can

be primed at start up or first use.

Preloading some collections on startup is certainly an interesting idea. I could also imagine that if combined with some flexible configuration options then this idea should almost be a no-brainer.

Off the cuff, I would say that the big potential

issue with an "active" collection would be

transaction atomicity on updates. If I make a change

to an object in a local collection with the

expectation of this change being persisted, do I

really want to rely on some behind the scenes update

process or do I want to use an explicit SaveChanges

operation on the domain object which can be directly

enclosed within a transaction including any related

or dependent changes. My inclinations, being

paranoid, leans toward the latter.

I agree. It's my inclination also. But I believe that the SaveChanges operation on a specific domain object (and dependents) is conceptually simpler and simpler to implement atomic transactions than the SaveChanges on a static business entity component which accepts a potentially large and complex PDS.

Perhaps you are getting at something else, however?

No. I just wanted to stimulate some discussion about the possible approaches that the advent of OO opens up. I would also be interested in discussing the various approaches to underlying data access/persistence mechanism.

Phil

Posted by Thomas Mercer-Hursh on 14-Nov-2006 12:41

Yes, but whichever underlying data access/caching mechanism that is used, the domain model is still presented as a conceptually simple set of of collections accessed from a root Repository object.

I get the sense that you are contrasting something with something else and I'm not sure what the two pieces are.

or if not yet resident in cache then retrieved from the database into a cache.

I.e., potentially lazy resolution.

That's right. There's a number of Fowler's patterns that I believe are relevant and could be readily applied in an implementation of OERA-based OpenEdge application.

Amen! ... at least if one starts programming in .cls ... unlike PSC!

The collection interface approach to accessing domain objects is also conceptually significant.

Again, I get the sense of contrast ... but not sure between what and what.

although I've read several harsh criticisms of generics

I view them as one of those things to be used carefully, like method overloading. They are very handy, even key, in making a compact, clean, simple framework, but one is less sure one wants the typical domain programmer fiddling with them.

hen regenerating the code from the model to a later version of ABL should be reasonably straight forward.

At least if one can keep people from breaking the link to the model!

the SaveChanges operation on a specific domain object (and dependents) is conceptually simpler and simpler to implement atomic transactions than the SaveChanges on a static business entity component which accepts a potentially large and complex PDS.

Of course, the SaveChanges ultimately has to be at the level of atomicity, no matter how complex that might be. However, a SaveChanges method in some complex object can certainly be composed of multiple SaveChanges calls on simpler objects.

I would also be interested in discussing the various approaches to underlying data access/persistence mechanism.

I have done some work on this with the aim of publishing it, but at this point I think I will have to wait until 10.1B FCS since I would want the model to include the structure I posted in the example to the beta forum.

Posted by Phillip Magnay on 14-Nov-2006 13:03

I get the sense that you are contrasting something

with something else and I'm not sure what the two

pieces are.

No, not really. , "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects". I'm just emphasizing the "collection-like interface for accessing domain objects".

or if not yet resident in cache then retrieved

from the database into a cache.

I.e., potentially lazy resolution.

Fowler's "Lazy Load" pattern is definitely relevant to the data access going on behind the Repository abstraction.

That's right. There's a number of Fowler's

patterns that I believe are relevant and could be

readily applied in an implementation of OERA-based

OpenEdge application.

Amen! ... at least if one starts programming in .cls

... unlike PSC!

I'm sure there will be more .cls examples after 10.1B FCS.

although I've read several harsh criticisms of

generics

I view them as one of those things to be used

carefully, like method overloading. They are very

handy, even key, in making a compact, clean, simple

framework, but one is less sure one wants the typical

domain programmer fiddling with them.

I definitely agree. Generics are very powerful but could be more than enough rope for some.

hen regenerating the code from the model to a

later version of ABL should be reasonably straight

forward.

At least if one can keep people from breaking the

link to the model!

Some good tools can solve that. Enterprise Architect anyone.

the SaveChanges operation on a specific domain

object (and dependents) is conceptually simpler and

simpler to implement atomic transactions than the

SaveChanges on a static business entity component

which accepts a potentially large and complex

PDS.

Of course, the SaveChanges ultimately has to be at

the level of atomicity, no matter how complex that

might be. However, a SaveChanges method in some

complex object can certainly be composed of multiple

SaveChanges calls on simpler objects.

Of course.

I would also be interested in discussing the

various approaches to underlying data

access/persistence mechanism.

I have done some work on this with the aim of

publishing it, but at this point I think I will have

to wait until 10.1B FCS since I would want the model

to include the structure I posted in the example to

the beta forum.

Yes. I think a lot of people are waiting for FCS. There should be quite a flurry of writing and publishing once it does.

Phil

Posted by Thomas Mercer-Hursh on 14-Nov-2006 13:23

I'm just emphasizing the "collection-like interface for accessing domain objects".

OK, why are you emphasizing it. To me, one is likely to need both individual domain objects and collections thereof. Some collections will be transitory and some will behave like a repository.

That's what I expected after 10.1A FCS.

Generics are very powerful but could be more than enough rope for some.

Some people only need a short piece of string!

Some good tools can solve that. Enterprise Architect anyone

Somehow, I am skeptical that even EA has unbreakable round trip engineering ... someone will figure out how to break it in the same way that people edit files that then can no longer be read by the AppBuilder.

There should be quite a flurry of writing and publishing once it does.

I'll attempt to do my part ... we'll see who else does. It isn't as if there is such an overwhelming raft of new OO stuff in 10.1B that one couldn't do any reasonable work until it comes along. The only reason for me to wait on the data access piece is that I rather like that thing I did in the example posted.

Posted by Phillip Magnay on 14-Nov-2006 14:47

I'm just emphasizing the "collection-like

interface for accessing domain objects".

OK, why are you emphasizing it. To me, one is likely

to need both individual domain objects and

collections thereof. Some collections will be

transitory and some will behave like a repository.

I am emphasizing it because those who are new to OO are probably unfamiliar with a domain object model approach (which is distinctly different from the business logic component approach), collections, and collection interfaces to access domain objects. Of course we will need both domain object classes and collections. And yes, collections will be used in other ways besides providing a means to access domain objects via the repository pattern.

I'm sure there will be more .cls examples after

10.1B FCS.

That's what I expected after 10.1A FCS.

There will always be disagreements over priorities and allocation of resources.

Somehow, I am skeptical that even EA has unbreakable

round trip engineering ... someone will figure out

how to break it in the same way that people edit

files that then can no longer be read by the

AppBuilder.

Skepticism is healthy. EA's round-trip engineering is certainly not unbreakable. But it is quite functional and reasonably robust... certainly to the extent that there are few objections using it to keep code and model in sync.

There should be quite a flurry of writing and

publishing once it does.

I'll attempt to do my part ... we'll see who else

does. It isn't as if there is such an overwhelming

raft of new OO stuff in 10.1B that one couldn't do

any reasonable work until it comes along. The only

reason for me to wait on the data access piece is

that I rather like that thing I did in the example

posted.

I'll do a search through the beta forum and have a look what you have posted to date concerning data access.

Phil

Posted by Thomas Mercer-Hursh on 14-Nov-2006 15:32

There will always be disagreements over priorities and allocation of resources.

Perhaps OO needs a specific champion ...

EA's round-trip engineering is certainly not unbreakable. But it is quite functional and reasonably robust... certainly to the extent that there are few objections using it to keep code and model in sync.

I don't suppose there are any ABL examples we can look at and play with ...

I'll do a search through the beta forum and have a look what you have posted to date concerning data access.

It's here:

http://www.psdn.com/library/thread.jspa?threadID=2460&tstart=0

Note that the focus of the use case is not data access, but that is the context. The part I liked was the domain class.

This thread is closed