Model-Set-Entity Pattern

1) Could you elaborate on what are all the CHARACTER parameters used for ? I hope it's not to send the business entity's name as a CHAR ?

2) Regarding GetEntityValue(...), does this imply some generics functionality (in the ABL ?).

3) Are all the methods in IBusinessModel used by the consumer or some are used by the Data components when re-creating from persistence ?

4) Is it really the job of the BusinessModel to persist itself (Persist() method) ? Or should it be the consumer responsibility to send the BusinessModel instance to the data component for persistence. What if I need to commit 2 BusinessModel in the same transaction ? In other business/domain patterns I saw, one of the primary goal is to make the business components completely oblivious to the data components. Could you comment if your model follow this idea, and if not, why ?

5) I still would like to see some pseudo code from the consumer point of view on how it requests for a model and works with it. A sequence diagram would be great.

You have posted to a forum that requires a moderator to approve posts before they are publicly available.

1) Could you elaborate on what are all the CHARACTER parameters used for ? I hope it's not to send the business entity's name as a CHAR ?

This is seems like a trivial item but it is actually one of the more interesting pieces. It is the parameter which allows the consumer to ask for a specific entity type. The challenge was achieving some form of type safety while providing something that the model understands. We originally used a progress.lang.class type reference for this parameter which the model then extracted the type information that it could use. But that approach seemed to place too much burden on the consumer to send in the correct progress.lang.class reference. So we changed it to a CHAR (progress.lang.class doesn't really offer any addiitonal type safety than CHAR) and included static read-only properties (constants if you like) in the model which the consumer would use to refer to a particular entity type. Combining these two approaches, ie, constants defined in the model of type progress.lang.class might also be option.

There's probably more ways to do this but keeping simple and direct would be my preference. I would be interested in any ideas that you may have.

2) Regarding GetEntityValue(...), does this imply some generics functionality (in the ABL ?).

No, not at all. It is just some modeling short-hand.

3) Are all the methods in IBusinessModel used by the consumer or some are used by the Data components when re-creating from persistence ?

No the data components do not use any of the methods in IBusinessModel. The data components refer to the model under a completely different interface type.

4) Is it really the job of the BusinessModel to persist itself (Persist() method) ? Or should it be the consumer responsibility to send the BusinessModel instance to the data component for persistence. What if I need to commit 2 BusinessModel in the same transaction ? In other business/domain patterns I saw, one of the primary goal is to make the business components completely oblivious to the data components. Could you comment if your model follow this idea, and if not, why ?

Actually, I do believe it is the responsibility of the model to handle persistence. I don't believe consumers should be directly referring to data components. I believe consumers should only refer to the model, sets, and entities as per your mention that business components should be completely oblivious to data components. Wrt transactions, I believe that transactions are internal to a given model. I don't believe there is any need to commit 2 models in a single transaction - proper design of the models should eliminate any need for that.

5) I still would like to see some pseudo code from the consumer point of view on how it requests for a model and works with it. A sequence diagram would be great.

It won't be today but I'll post something in due course.

You have posted to a forum that requires a moderator to approve posts before they are publicly available.

To clarify further, a BE will contain the entity logic, but it serves as a facade for the data which remains in the model. Access is via the Value methods you see in the interface. They have also tried using a buffer, as NSRA does, but decided on balance that violated encapsulation and could lead to significant debugging and testing issue since a buffer is navigatable, rather than being an identifier for a particular tuple in the PDS. One could argue that having value methods on the model and properties on the BE which were the same thing is a violation of Normal Form, but the Value methods on the Model are not really usable by anyone other than the BE because an ID is required to identify the entity in question.

Similarly, Entity Sets don't really contain BEs, but rather identify a query in the Model which designates the set which the ES represents.

In sequential processing of a set of BEs, one would typically instantiate a BE, process it, and then delete it, so that the number of currently instantiated BEs is kept very small. This is possible, of course, because the data for the BE remains always in the Model.

I don't believe there is any need to commit 2 models in a single transaction - proper design of the models should eliminate any need for that.

So, if I am doing something like allocating stock to orders, I am going to have a combined Item and Order Model, not an Item Model and an Order Model?

Yes, I would take the combination approach over allowing consumers to directly reference DA components in order to submit multiple models in a single transaction. Using composition to combine models together to form a larger model (which is still compliant with the model interface type) sounds like a much neater tack. Though the DAController would no doubt need some enhancement to accommodate these larger, more complex models.

You have posted to a forum that requires a moderator to approve posts before they are publicly available.

First, it seems like it should be the responsibility of the task to define the transaction scope. Operation 1 might have a scope of a single order and Operation 2 might have a scope of all impacted orders ... how would the Model know.

Second, it seems like it would lead to a combinatorial proliferation of Model types A + B, A + C, A + D, B + C, .... etc.

First, it seems like it should be the responsibility of the task to define the transaction scope. Operation 1 might have a scope of a single order and Operation 2 might have a scope of all impacted orders ... how would the Model know.

A transaction is initiated whenever a model is submitted to the DA. A model may contain changes for a single entity or many changes from multiple changed entities. The business task just requests a model to be persisted and all outstanding changes within a model will be updated to the database in a single transaction whether that transaction encompasses changes to a single record or many.

Second, it seems like it would lead to a combinatorial proliferation of Model types A + B, A + C, A + D, A + E

Sure. I would expect that such composition would be reserved for cases where the model design doesn't quite stretch to certain use cases. If it was getting used beyond that then I would suggest that the design of the unitary models may need rethinking.

What would be your answer to your original question?

You have posted to a forum that requires a moderator to approve posts before they are publicly available.

I don't know that I like the notion of equating a transaction with a request for persistance. Business transactions can be lots of things. Yeah, we are used to managing these mostly with database transactions in an ABL world because it tends to be persisted information that we care about, but not everything is persisted. Moreover, in an ESB world, we have to step back a bit and look at transactions a bit differently. That convenient, simple, and absolute reliance on a DB transaction doesn't work with distributed data ... it might be possible, but undesireable. In particular, I can imagine tasks which would be broken into multiple subtasks and there might be some outside interactiono between subtasks. I may want to define a transaction around the subtask so that I know I am complete and ready for the next interaction, but I may not want to persist anything until I get to the end. Yes, this implies having to start over again from the beginning if something fails before the end, but that seems like a reasonable option.

This proliferation of model vaiations doesn't seem like the OOish thing to do.... and a possible maintenance headache.

I don't know that I like the notion of equating a transaction with a request for persistance. Business transactions can be lots of things. Yeah, we are used to managing these mostly with database transactions in an ABL world because it tends to be persisted information that we care about, but not everything is persisted. Moreover, in an ESB world, we have to step back a bit and look at transactions a bit differently. That convenient, simple, and absolute reliance on a DB transaction doesn't work with distributed data ... it might be possible, but undesireable. In particular, I can imagine tasks which would be broken into multiple subtasks and there might be some outside interactiono between subtasks. I may want to define a transaction around the subtask so that I know I am complete and ready for the next interaction, but I may not want to persist anything until I get to the end. Yes, this implies having to start over again from the beginning if something fails before the end, but that seems like a reasonable option.

Sure. But in the context of this pattern, we're dealing with DB transactions.

This proliferation of model vaiations doesn't seem like the OOish thing to do.... and a possible maintenance headache

Variation via composition is a very OO thing to do and would be very maintenance friendly.

You have posted to a forum that requires a moderator to approve posts before they are publicly available.

But in the context of this pattern, we're dealing with DB transactions.

Surely you don't want to exclude ESB data sources!

Variation via composition is a very OO thing to do and would be very maintenance friendly.

Yes, but you don't have objects to compose. Are you suggesting you will implant a Model within a Model? Even if you did, this seems like it would be a very different thing than composition involving objects.

And, isn't some thing like Items and Orders for allocation more like aggregation than composition?

But in the context of this pattern, we're dealing with DB transactions.

Surely you don't want to exclude ESB data sources!

It doesn't exclude them. It just won't manage distibuted transactions. And I don't believe that it should be expected to.

Variation via composition is a very OO thing to do and would be very maintenance friendly.

Yes, but you don't have objects to compose. Are you suggesting you will implant a Model within a Model? Even if you did, this seems like it would be a very different thing than composition involving objects.

And, isn't some thing like Items and Orders for allocation more like aggregation than composition?

Models are objects. Mulitple uintary models within a larger complex model would form the composition and that sounds perfectly reasonable to me. I wasn't suggesting there would be a composition between Items and Orders.

You have posted to a forum that requires a moderator to approve posts before they are publicly available.

It doesn't exclude them. It just won't manage distibuted transactions. And I don't believe that it should be expected to.

Raising the obvious question of what would manage the distributed transaction?

To be sure, this is a very complext area. I thought Mike did a great job covering the issues in his Exchange talk, including the recognition that, with distributed data one needed to deal at times with what might call "optimistic transactions", i.e., fire off a change expecting it to work and then have some mechanism to put things back again in the rare case where it doesn't. One expects it to work, of course, because one has started with reasonably timely information and one is using a reliable delivery mechanism to get the message there. So, the undo mechanism isn't something that is part of the underlying technology, but rather something that one has to program as a separate task and monitor. It would seem to me that there are even times when subsystem A is going to need to impact subsystem B, but doesn't necessarily have any data of its own to persist.

It just seems to me that the transaction scope belongs in the task, not coupled to the act of persistence ... but I'll think about it a bit and see if anyone else has 2 cents to throw in.

OK, nesting two or more Models into one larger Models does allow for more re-use than what I thought you were talking about, i.e., a Model with a more complext PDS. It does make my head hurt a bit though. It might be OK for sequential processing, but for something more complex I wonder how it would work.

And these instances are still "connected" to the dataset data, so changes made to one instance is automatically reflected into the other instance, right ?

But, even if they are synced, having 2 different instances to represent the same thing smells wrong to me.

When I first saw the pattern, i thought: finally, a pattern where simplicity is a key point in the business entities. But, as more details are revealed, it seems to me that this is drifting away from my first thought. BE being only a facade to the dataset data is a big down for me, as I anticipate the BE to contains many distracting code required for the dataset mapping. For me, BE should be as simple as possible, and contains only business related data AND logic, no infrastructure pollution.

I'm sorry for being quite harsh, this is probably fueled by the fact that the foundation of this pattern is based on temp-table, and my opinion regarding temp-table usage in an OO model is pretty negative... But, I'm still in the very early learning stage of OO modeling, and I still have to see more concrete stuff about this pattern, so my opinion may certainly change.

You have posted to a forum that requires a moderator to approve posts before they are publicly available.

1) Could you elaborate on what are all the CHARACTER parameters used for ? I hope it's not to send the business entity's name as a CHAR ?

This is seems like a trivial item but it is actually one of the more interesting pieces. It is the parameter which allows the consumer to ask for a specific entity type. The challenge was achieving some form of type safety while providing something that the model understands. We originally used a progress.lang.class type reference for this parameter which the model then extracted the type information that it could use. But that approach seemed to place too much burden on the consumer to send in the correct progress.lang.class reference. So we changed it to a CHAR (progress.lang.class doesn't really offer any addiitonal type safety than CHAR) and included static read-only properties (constants if you like) in the model which the consumer would use to refer to a particular entity type. Combining these two approaches, ie, constants defined in the model of type progress.lang.class might also be option.

There's probably more ways to do this but keeping simple and direct would be my preference. I would be interested in any ideas that you may have.

In .Net, I could do the following, all with type safety.

oOrdersModel.GetEntity(typeof(be.Order)).

public IBusinessEntity GetEntity(System.Type beType)

{

if (beType == typeof(be.Order))

{

}

}

Is this possible in ABL ?

However, this does not give any clue to the consumer what are the possible entities returned by the model.

I think this may be a good use case for an Enumeration. Even with your static properties, having a CHAR as a parameter is not clear from the consumer point of view, neither from a UML diagram point of view. Moreover, it doesn't force the consumer to use the static properties. Using an enumeration here helps the clarity, and reduce risk of error.

I vote for an enhancement to have Enumeration in the language !

You have posted to a forum that requires a moderator to approve posts before they are publicly available.