TLSA versus DDD - Forum - OpenEdge Development - Progress Community
 Forum

TLSA versus DDD

  • The conventional wisdom to approaching contemporary service-oriented business applications is through a layered architecture. The reference application demonstrates the use of OpenEdge and PSC products in an implementation of a layered architecture.

    With the introduction of object-orientation features, the OpenEdge ABL will provide additional choices concerning layered architecture such as the OERA. Fortunately, OO approaches to implementing a layered service-oriented architecture already exist in other languages such as Java and C#. But there appears that these existing OO approaches have divided into two distinct camps: the Three Layered Services Architecture and the Domain Driven Design . This I found discusses these two distinct approaches. Fowler also touches on these options in his EAA patterns concerning domain logic design.

    There are pros and cons to each of these approaches depending on different situations. Also, there is limited scope for overlap and reuse between them, but for the most part they are mutually exclusive. Going one direction doesn't give you any leg-up on the other and indeed, incorporating both approaches together would add an additional level of complexity to the domain logic which would be better to avoid... which is why I suppose there are two distinct camps on this issue.

    So I wonder what would be the pros and cons of each of these approaches when it comes using the OpenEdge. I would be interested in hearing everyone's views.

  • In some respects, I think this is a false contrast ... perhaps influenced by those extra two letters in front of TLSA and hopefully not characteristic of OERA applications. To me, the central topic here is the central topic in OOAD ... where does one draw the line between one class and another class. Creating lots of little classes provides for lighter weight cost of instantiation and very tightly focused units, as well as a very neat segregation into model layers. Creating larger classes means more expense to instantiate, but makes for a closer approximation of the ideal of having all related data and behavior encapsulated in a single class.

    I also don't think that one can really discuss this without simultaneously thinking in terms of services. With services, objects which otherwise might be needed only briefly can be persistent and thus the question of the cost of instantiating them becomes less significant.

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com

  • In some respects, I think this is a false contrast

    ... perhaps influenced by those extra two letters in

    front of TLSA and hopefully not characteristic of

    OERA applications.

    I'm not sure why it should be regarded as a false contrast; these are two very different approaches to organizing and implementing domain logic in a layered architecture to achieve the same functional outcome. And each has very different pros and cons during both construction and operation. Fowler makes similar choices/distinctions concerning design approaches to domain logic when covering the "table module" and "domain model" EAA patterns.

    To me, the central topic here is

    the central topic in OOAD ... where does one draw the

    line between one class and another class. Creating

    lots of little classes provides for lighter weight

    cost of instantiation and very tightly focused units,

    as well as a very neat segregation into model layers.

    Creating larger classes means more expense to

    instantiate, but makes for a closer approximation of

    the ideal of having all related data and behavior

    encapsulated in a single class.

    Sure. But the little light-weight classes as per the domain model also add their own overhead by typically requiring more instances of objects and managing the navigation of these lists/sets of instances. The "larger classes" approach requires fewer instances but can be less flexible/adaptible because it is a coarser-grained object containing embedded data relationships. I agree that it ultimately comes down to where the line is drawn between one class and another. But one approach simulates the data relationships as associations between classes, the other encapsulates those relationships within a single class. There might be some degrees between these approaches but that may imply additional complexity.

    I also don't think that one can really discuss this

    without simultaneously thinking in terms of services.

    With services, objects which otherwise might be

    needed only briefly can be persistent and thus the

    question of the cost of instantiating them becomes

    less significant.

    However, a domain model approach means that it is less likely that an object that is left persistent on the server is actually the object that is needed on subsequent requests.

    Phil

  • I don't see this contrast as relating to table model versus domain model. The latter contrast is more one of a degenerate, simple version versus the full thing. I don't see the intent of TLSA versus DDD in the same way ... I'm just suggesting that the core of each is good OOAD and that one can have good domain models in a layered architecture. ... and should.

    There might be some degrees between these approaches but that may imply additional complexity.

    I think there is an infinite range of degrees, which was my attempted point. I remember years ago having an interaction with a certain OO designer who thought that the concept of an inventory item should include its ability to order itself. That sort of thing I regard as a case of extreme lumping, and almost certainly inappropriate lumping because good purchasing involves considering more than one item at a time (we should order 10 of X because the stock is a little low and we need to order Y and Z from the same company and with the X in the order we get a bigger discount).

    Start at any given point and one could probably analyze an entire application into a single class, but it wouldn't be a good design. Likewise, every property could be its own class. Between those extremes, there are zillions of different variations. All I am suggesting is that I don't find myself wanting to make different object decompositions because I am thinking in terms of layers.

    However, a domain model approach means that it is less likely that an object that is left persistent on the server is actually the object that is needed on subsequent requests.

    Why? I would think, for example, that if one had a inventory service and each item was brought into some kind of most recently used cache as it was accessed, that it would mean that most of the commonly used items would end up in that cache, ready for use.

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com

  • I don't see the intent of TLSA versus DDD in

    the same way ... I'm just suggesting that the core of

    each is good OOAD and that one can have good domain

    models in a layered architecture. ... and should.

    ==snip==

    All I am suggesting is that I don't find myself

    wanting to make different object decompositions

    because I am thinking in terms of layers.

    OK. Now I got you. I agree that the various ways one could make the object decomposition in the domain model can be/should be supported by architectural layering. But there is a distinction that goes beyond levels of object decomposition. A "table module" pattern makes use of one object instance per table/view whereas a "domain model" approach makes use on one object instance per row/rows/data entity.

    Why? I would think, for example, that if one had a

    inventory service and each item was brought into some

    kind of most recently used cache as it was accessed,

    that it would mean that most of the commonly used

    items would end up in that cache, ready for use.

    Sure. If the inventory service accessing inventory data was implemented using a "table module" pattern, then there is no doubt that these object instances would be needed for most every request and therefore persisting these object instances between requests makes absolute sense.

    However, if the inventory service accessing inventory data was implemented using a "domain model" pattern, then there is less certainty that the objects instantiated for one request will be used in a subsequent request. They might be. They might not be. That's all. A cache of commonly used items is fine idea as long as some items are indeed commonly used... which in some use cases they might be. In others, not at all.

    Phil

  • A "table module" pattern makes use of one object instance per table/view whereas a "domain model" approach makes use on one object instance per row/rows/data entity.

    Understood and I think that the table model approach is simply not appropriate for modern OO applications. It is one of the things which I think is "dated" or weak about AutoEdge is that there is a very simple "punch through" on a table by table basis. This enables very deep shared code, but at the expense of having to put de-normalization code too close to the business layer. It is interesting, but not good OO.

    I don't see why a table-model implementation would imply any different caching scheme than a domain model. Caching is a design decision that one would make in order to have objects marshalled and ready for use when they were likely to be reused again fairly soon. Different levels and types of caching are appropriate for different types of objects. An object that contains a list of valid state codes, for example, is not expected to change and so should absolutely be cached, probably in every service that might use it. This would be particularly attractive if one could register for a list-changed event that would trigger refreshing the object. An order object might not get cached at all or be cached only during the time in which it is being actively processed since beyond that time it will be rare that it is accessed.

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com

  • Understood and I think that the table model approach

    is simply not appropriate for modern OO applications.

    It is one of the things which I think is "dated" or

    weak about AutoEdge is that there is a very simple

    "punch through" on a table by table basis. This

    enables very deep shared code, but at the expense of

    having to put de-normalization code too close to the

    business layer. It is interesting, but not good

    OO.

    It may not be good OO. But good OO was not amongst the goals of the current version of AutoEdge. That will come in due course.

    At a layered architecture level, there appears to be less and less argument. However, there are different views at a design level. If good OO is an important goal, then a domain model approach is the option. If good OO is further down the list of priorities, the table module pattern is a perfectly valid alternative. And although it is certainly closer to a table module approach than a domain model, the AutoEdge approach is also a solid option.

    I don't see why a table-model implementation would

    imply any different caching scheme than a domain

    model. Caching is a design decision that one would

    make in order to have objects marshalled and ready

    for use when they were likely to be reused again

    fairly soon. Different levels and types of caching

    are appropriate for different types of objects. An

    object that contains a list of valid state codes, for

    example, is not expected to change and so should

    absolutely be cached, probably in every service that

    might use it. This would be particularly attractive

    if one could register for a list-changed event that

    would trigger refreshing the object. An order object

    might not get cached at all or be cached only during

    the time in which it is being actively processed

    since beyond that time it will be rare that it is

    accessed.

    Don't get me wrong - I'm a proponent of caching. But I just want to separate the issue of the desirability and/or appropriateness of caching and the difference in the caching mechanism between domain model and table module approaches for a moment.

    I do see a distinction between caching for domain model patterns versus table module approach. In a domain model, you are caching real objects which contain both state and behavior, and this is great if there is a reasonable expectation that the objects in the cache are actually going to be used repeatedly in a multi-user, stateless server request environment. Reference codes like US states are a good candidate for caching. Master tables like inventory or customer might not be as good (but depending on the application/use case they might be just as good).

    However, in a table module approach, it is more about caching behavior (ie, persisting components for reuse without reloading) than caching state. You certainly could also cache data inside these components but then again you may decide not to. With a domain model, you do not have that choice; a domain model cache will always include state and behavior. Again, the decision to cache state should be based on the reasonable expectation that this data is going to be needed by subsequent requests. Similarly, the decision to cache components should be based on the reasonable expectation that the behavior of such components is going to be needed by subsequent requests.

    And although the ultimate implementation of caching mechanism for a domain model may not be too different from a caching mechanism for a table module approach (then again they may be quite different), there is a material conceptual distinction here.

    Phil

  • I didn't want to intrude your on-going discussion, however...

    Understood and I think that the table model

    approach

    is simply not appropriate for modern OO

    applications.

    It is one of the things which I think is "dated"

    or

    weak about AutoEdge is that there is a very simple

    "punch through" on a table by table basis. This

    enables very deep shared code, but at the expense

    of

    having to put de-normalization code too close to

    the

    business layer. It is interesting, but not good

    OO.

    It may not be good OO. But good OO was not amongst

    the goals of the current version of AutoEdge. That

    will come in due course.

    As Phil rightly says, OO was not a consideration for the current version of AutoEdge, but we do have some OO plans going forwards.

    But on the more general topic of your discussion, I think you also have to consider the target implementation in some of your design. Sure, you can be as abstract as you like, but at then end of the day, the whole point is to turn the design into code. At that point I think you have to then look at the strengths of the chosen language of implementation. Although a pure Domain Model can be coded in ABL, does that make the best use of ABL as a language, which has the distinction from pure OO languages of being Data-Aware? What would be the added value of having orderlines as a collection of objects, as opposed to a dataset, for which the language has built in features & syntax? Or am I totally missing the point? (Always possible as it's late in the day here!!)

  • It may not be good OO. But good OO was not amongst the goals of the current version of AutoEdge. That will come in due course.

    Well, whether the code utilizes classes or not, I raised a question here http://www.psdn.com/library/thread.jspa?threadID=2608&tstart=0 about whether the structure is ideal. I don't think that the preferred encapsulation changes just because one is not using OO verbs. The AutoEdge structure does not provide isolation between the database structure and the structure in the application and it does the de-normalization at what I think is a late point.

    If good OO is an important goal, then a domain model approach is the option. If good OO is further down the list of priorities, the table module pattern is a perfectly valid alternative.

    "Valid" is an interesting word. What makes something valid or not valid ... other than that it is possible to make it work? If so, lots of architectural alternatives that have been used historically are "valid" because they succeeded as the basic of a working application. I don't think that equates with "equally desirable" or "modern best practice". AutoEdge is a very cool piece of work, but I think that there are pieces of it that are tied to historical practice and which could use a bit of buffing.

    I'm a proponent of caching. But I just want to separate the issue of the desirability and/or appropriateness of caching and the difference in the caching mechanism between domain model and table module approaches for a moment.

    One is a temp-table of rows resembling the rows in the data base and the other is a temp-table of Progress.Lang.Object. What else?

    If it is more expensive to marshal and de-marshal an object because the object includes behavior, that actually increases the performance advantage of caching it, as long as there is a reasonable expectation of re-use. To be sure, that expectation varies from near certainty to near improbability, but that is just a part of the design process ... the same design decision with either model.

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com

  • I didn't want to intrude your on-going discussion, however...

    Much better to have more than just Phil and I!

    What would be the added value of having orderlines as a collection of objects, as opposed to a dataset, for which the language has built in features & syntax?

    Certainly one of the interesting design questions in OO comes when dealing with this kind of parent-child relationship. Moreover, I am beginning to suspect that the OO context of OOABL is different than the context of OO3GL languages because ABL has structures like temp-tables and PDS which are not present in those other languages. In some ways, a temp-table is a sort of ultra-lightweight object with very limited behavior and a PDS is a sort of semi-lightweight object with a limited range of formalized behaviors.

    So, I think that the question is, how much behavior does the child have and in what contexts. Order lines, for example, seem to have a lot of behavior, but I think that one could argue that the bulk of that behavior is actually associated with the order, not with the order line independent of the order. In a non-OO program one might well do a For Each OrderLine, but chances are there will be a join on Order in there somewhere because almost anything that one does to an order line also impacts the order.

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com

  • Well, whether the code utilizes classes or not, I

    raised a question here

    http://www.psdn.com/library/thread.jspa?threadID=2608&

    tstart=0 about whether the structure is ideal. I

    don't think that the preferred encapsulation changes

    just because one is not using OO verbs. The AutoEdge

    structure does not provide isolation between the

    database structure and the structure in the

    application and it does the de-normalization at what

    I think is a late point.

    I'm sure the AutoEdge guys will look seriously at your feedback.

    If good OO is an important goal, then a domain

    model approach is the option. If good OO is further

    down the list of priorities, the table module pattern

    is a perfectly valid alternative.

    "Valid" is an interesting word. What makes something

    valid or not valid ... other than that it is possible

    to make it work? If so, lots of architectural

    alternatives that have been used historically are

    "valid" because they succeeded as the basic of a

    working application. I don't think that equates with

    "equally desirable" or "modern best practice".

    AutoEdge is a very cool piece of work, but I think

    that there are pieces of it that are tied to

    historical practice and which could use a bit of

    buffing.

    I was referring to the "table module" pattern - not AutoEdge. The table module pattern (Fowler - Patterns in EAA) is a perfectly valid and modern design choice.

    One is a temp-table of rows resembling the rows in

    the data base and the other is a temp-table of

    Progress.Lang.Object. What else?

    If it is more expensive to marshal and de-marshal an

    object because the object includes behavior, that

    actually increases the performance advantage of

    caching it, as long as there is a reasonable

    expectation of re-use. To be sure, that expectation

    varies from near certainty to near improbability, but

    that is just a part of the design process ... the

    same design decision with either model.

    As I previously indicated, there may not be too great a difference between the implementation of a caching mechanism for objects from a domain model versus that for business components which follow a table module approach. Afterall, it's just a list of references to persistent processes. But as per the original point, there is a clear distinction between caching objects (data & behavior, lots of instances of small fine-grained classes) in a domain model and caching business components (behavior only, fewer instances of large course-grained classes) in a table module approach. And this distinction between these two design approaches means there are two distinct set of probabilities that an object will be used again on subsequent requests after instantiation for each respective approach, and therefore there are two distinct considerations in the design process.

    Phil

  • Certainly one of the interesting design questions in

    OO comes when dealing with this kind of parent-child

    relationship. Moreover, I am beginning to suspect

    that the OO context of OOABL is different than the

    context of OO3GL languages because ABL has structures

    like temp-tables and PDS which are not present in

    those other languages. In some ways, a temp-table is

    a sort of ultra-lightweight object with very limited

    behavior and a PDS is a sort of semi-lightweight

    object with a limited range of formalized behaviors.

    Personally, I think the notion of "collections", and other constructs from other languages can be quite nicely supplanted / implemented using ABL's temp-table support.

    As such, are "base" classes of collections and such really needed in OOABL?

    Given the presence of TTs and other language constructs, are such t

  • But on the more general topic of your discussion, I

    think you also have to consider the target

    implementation in some of your design. Sure, you can

    be as abstract as you like, but at then end of the

    day, the whole point is to turn the design into code.

    Sure. The intention was to tease out pros and cons of two very distinct different design options including the implementation issues.

    At that point I think you have to then look at the

    strengths of the chosen language of implementation.

    Although a pure Domain Model can be coded in ABL,

    does that make the best use of ABL as a language,

    which has the distinction from pure OO languages of

    being Data-Aware? What would be the added value of

    having orderlines as a collection of objects, as

    opposed to a dataset, for which the language has

    built in features & syntax? Or am I totally missing

    the point? (Always possible as it's late in the day

    here!!)

    Not that I'm trying to land on one side of the discussion or another, but the domain model approach does have its own pros including being more closely aligned with OO design best practices as well as being more flexible/more adaptible over time.

    Phil

  • I'm sure the AutoEdge guys will look seriously at your feedback.

    I hope so. I think there is a lot in AutoEdge to stimulate discussion. The end of the discussion might be a conclusion that one would do it differently if one had to do it over again, but I don't think that needs to reflect poorly on AutoEdge at all. In fact, the point is that AutoEdge is good enough and interesting enough to be worth discussing ... something not true of sports2000, for example.

    I was referring to the "table module" pattern - not AutoEdge. The table module pattern (Fowler - Patterns in EAA) is a perfectly valid and modern design choice.

    Fowler covers a number of patterns which are in some sense competitive and I think he is pretty clear about making the distinction of when to use the more degenerate forms. Table model is appropriate when the connection is over the wire since one currently can't transmit an actual object ... and probably wouldn't want to anyway (Although the "table" would probably be in the form of XML). I don't think that this means in any way that it is a simple toss up which one to use. E.g., among other careful qualifications and value statements he says "for handling complicated domain logic, a Domain Model is a better choice." That seems pretty unequivocal to me.

    But as per the original point, there is a clear distinction between caching objects (data & behavior, lots of instances of small fine-grained classes) in a domain model and caching business components (behavior only, fewer instances of large course-grained classes) in a table module approach.

    Why are you equating domain model with small and fine-grained and table model with large and coarse grained? If anything, an Order object is going to be very large and complex compared to an Order table, an OrderLine table, etc.

    And this distinction between these two design approaches means there are two distinct set of probabilities that an object will be used again on subsequent requests after instantiation for each respective approach, and therefore there are two distinct considerations in the design process.

    Maybe I am reading this wrong, but it seems to me that the probability of re-use is a property of the context, regardless of the model used for implementation.

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com

  • Personally, I think the notion of "collections", and other constructs from other languages can be quite nicely supplanted / implemented using ABL's temp-table support.

    My vote is for "implemented", as expressed here http://www.oehive.org/CollectionClasses

    As such, are "base" classes of collections and such really needed in OOABL?

    Provisionally, I think they provide value, if only because they keep you from having to define a separate collection class for every domain class.

    Given the presence of TTs and other language constructs, are such t

    Press "Post" prematurely?

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com