Architecture Issue

Architecture Issue

Old forum URL: forums.lhotka.net/forums/t/3707.aspx


tna55 posted on Saturday, October 13, 2007

Hi,

I am someone learning about various architectures so that I can implement one in my next project.

I would like to have a comment on an architecture used very commonly for web applications. In this architecture every business object is split into three classes i.e. BO, BLL and DAL. BLL and DAL having static (shared) methods with BO being passed as parameter. e.g. in order to load an item it would be something like this:

Public Shared Function GetItem(Id As Integer) As CustomerBO

Return CustomerDAL.GetItem(Id)

End Function

Public Shared Function Insert(Customer As CustomerBO) As Boolean

Return CustomerDAL.Insert(Customer)

End Function

These are two sample methods from the BLL and as we can see the Shared methods pass BO into DAL (in case of Insert, Update, Delete) and get BO from DAL (in case of GetItem, GetList etc). BO is just properties i.e. a DTO.

My question really is: Is this an OOA? What are the shortcommings of this?

Second question is regarding the Business Objects that Rocky recommends: In a responsibility-driven design should the methods in a "true" Business Object be static (shared) or instance? What is the difference?

I would really appreciate Rocky's help however comments of other people are good as well.

Tahir

RockfordLhotka replied on Sunday, October 14, 2007

For clarity, I'll rename what you are calling a "business object" to "entity object" as that is more properly what you are describing.

Yes, the use of an EO, BLL and DAL together is an OOA. This model was (and perhaps still is) pretty common in the Java world.

This is a different architecture from the one CSLA supports, because I generally disagree with the idea of splitting the entity and business concepts into separate objects. Splitting out the DAL is fine, though I think it should still be encapsulated behind the combined EO/BLL (which is what I call a business object in my books).

But it does depend on what you are trying to do. The EO/BLL split is often a good one for non-interactive batch processing. It is not very good for interactive scenarios where the user's UI is directly interacting with the object model, because there's too much overhead and complexity to get the levels of interactivity provided by the CSLA BO model.

Conversely, the CSLA BO model can work for non-interactive scenarios, but it isn't necessarily optimal. A lot of the features of the CSLA stereotypes are very UI-focused (data binding, n-level undo, etc) and those aren't useful in a non-interactive scenario.

Other CSLA features, such as authorization and validation, are valuable in all cases, but the way they are used in my books is geared toward interactive scenarios. You should use them differently if you are in a non-interactive scenario, because there are more efficient ways to use them if you don't care about interactivity or user responsiveness.

To answer your final question, it is critical to remember that there's a big difference between object oriented design and object oriented programming. At the design level, many things are "objects" that later turn out to be static methods, or static instances, or full instances, etc.

For example, validation rules are considered "objects" during OOD. A higher level business object, like CustomerEdit, will collaborate with validation rule objects like MaximumCreditLimit. But at implementation time MaximumCreditLimit is almost certainly just a static method - not an object at all.

tna55 replied on Sunday, October 14, 2007

Rocky,

Many thanks for your reply.

I am trying to understand the responsibility driven design and there are not many books around to discuss this topic.

So basically what we are saying is that a 'true' BO will have one responsibility and like the Assignment object ProjectTracker project, a BO can only be methods i.e. no properties. Is that correct?

In Applying UML and Patterns Craig Larman mentioned that we assign responsibilities to an object that has the data to fulfil that responsibility. This pattern is called Information Expert in his book. Is that a data-driven way of thinking rather than responsibility-driven design. He also has pattern like Pure Fabrication which basically says that if Information Expert is breaking coupling and/or cohesion then we should create another object and assign the responsibility to it. I think you both are saying same thing but in a different way. Am I right in thiking this?

Tahir

RockfordLhotka replied on Sunday, October 14, 2007

Single responsibility design merely says that an object (at design time) has exactly one responsibility.

Any behaviors that object has, are in service of fulfilling that responsibility.

If an object becomes overly complex (you can't summarize what it does in a non-compound sentence fragment) then that complexity must be broken into other objects with which it collaborates.

So an entity object is responsibility driven - its responsibilty is to contain shaped data.

A business logic layer object can be responsibility driven - its responsibility is to implement a set of cohesive behaviors around some concept. Though honestly this one gets pretty tough, because it typically turns out that each method has a responsibility and is logically an object. This, by the way, leads to service-oriented and/or workflow (activity) based designs. The end result is typically that you end up abandoning OO and instead use procedural design techniques.

The problem though, either way, is that entity objects aren't defined by business responsibility, but instead literally by "contain shaped data" - which is an implementation responsibility. And at that point even entity objects no longer conform to the goal of responsibility driven object-oriented design.

This, then, is the core. Do your responsibilities flow from business requirements (use cases), or from technology requirements?

If the former, then your objects will all have a responsibilty within a use case, and almost always your business analyst/user can understand the objects' responsibilities.

If the latter, then your objects will have responsibilities defined by technology. By programmers. And your business analysists/users will struggle to understand the responsibilties or relate them to the actual business problem.

This isn't to say that the latter is wrong, because it is, in fact, a really powerful tool for software design. But it is not a powerful tool for mapping business problems into software - and to me that's the real problem we need to solve using OO.

tna55 replied on Monday, October 15, 2007

Rocky,

Many thanks once again.

If an object is responsible for more than one thing then we seperate that responsibility into another object, which is fine. I am trying to understand the communication of this new object with the others really. How do we pass data into this object and then get data back? Let me give an example.

If I had an orignal object BO1 having properties and methods, however it had two responsibilities and I seperated those methods into BO2. Now in order to perform the responsibility the BO2 will require data (properties) from BO1. BO2 does not do any database handling, it is pure business logic.

There are two ways I think I can implement BO2. 1) By having a Shared function that takes *Info object and give back another *info object. 2) By having properties in the BO2 that its user will fill and then some other properties that the user will get after the processing. Some code for these are

1)

Public Shared Function DoSomething(Param as xyzInfo) As abcInfo

The user will fill xyzInfo and will get back abcInfo.

2)

Public Function DoSomething()

The user will fill some properties and will get back some others

BO2.A= "A"

BO2.B="B"

BO2.DoSomething()

C = BO2.C

D = BO2.D

 

I am trying to understand that which one is the correct approach really.

Your help will be much appreciated.

Tahir

RockfordLhotka replied on Monday, October 15, 2007

There's a concept called "coupling" that comes into play at the implementation level. When an object implements a behavior that requires information from outside the object itself, you want to provide that information in a way that keeps everything decoupled.

What that means, is that you want to minimize the knowledge that any one object has about any other object. The less they know about each other, the more flexible and maintainable your code.

If BO2 is an implementation of a single atomic behavior then it is probably best implemented as a Shared function. The only reason to force a consumer to create an instance is if there's some value in BO2 having properties that maintain state - like you are going to call the behavior over and over again and BO2 would need to track state between those calls.

But for most atomic behaviors that isn't the case.

So then you need to ask whether to do this:

DoSomething(Me)

or

DoSomething(A, B, C)

or

Dim tmp As New RequestData
tmp.A = A
tmp.B = B
tmp.C = C
DoSomething(tmp)

or even less coupled would be to define an IRequestData interface that can be implemented either by BO1 or the RequestData class, so DoSomething() can accept an IRequestData parameter.

All of these are valid by the way - you just need to evaluate complexity vs decoupling. The goal, after all, is maintainability, not decoupling and not reuse. And complexity is just as much an enemy of maintainability as coupling...

So if BO2 is for use only in this one use case and you don't anticipate reuse, then there's no sense in using an interface-based scheme, and I'd probably just have it accept BO1 as a parameter:

DoSomething(Me)

But if BO2 is normalized behavior that will likely be used by other objects in this use case then it might be worth creating some RequestData class.

And if BO2 is normalized behavior that will likely be used by other objects in other use cases too, then it is probably worth defining an interface to provide the higher level of decoupling.

tna55 replied on Monday, October 15, 2007

Excellent, that makes a lot of sense now. I am beginning to understand what is wrong with what I am doing.

I would really appreciate if you can help me resolve an issue. This would give me an idea of how to allocate responsibilities.

I have a License BO with Cd-Key and ActivationCode as two properties. I have implemented a CreateNew Method in it that takes two parameters NoOfBuildings and ModuleCode. A New License BO is created based on these parameters. Let me write the code bits from the License BO

Public Shared Function CreateNew(NoOfBuildings As Integer, ModuleCode as String) As LicenseBO

   Dim sCdKey As String = ""

   Dim sActivationCode As String = ""

   sCdKey = CreateCdKey()

   sActivationCode = CreateActivationCode(sCdKey, NoOfBuildings, ModuleCode)

   Dim License As New License

   License.CdKey = sCdKey

   License.ActivationCode = sActivationCode

   Return License

End Function

 

This Shared method is in License BO itself. License BO also saves and deletes itself from database. It is is like CSLA BO (more or less). Now the questions I asked in previous posts were to see whether I should remove this method into another class of its own? As you can see there as two Private methods (CreateCdKey and CreateActivationCode) as well. Will keeping this within License BO make License BO do more than one thing?

If we say that splitting responsibilities is essential then we will probably have many classes with couple of methods and most of them will not have properties. Does that lead to a procedural approach? May be I am missing the key difference between procedural and object-oriented approach, could you please explain me the difference?

Another question: The Architecture I have is such that there is a LicenseBO and LicenseBOList however they both use same LicenseDAL class. My concept is to make one DAL object per table with a DTO to transfer data between BO and DAL. However, there can be various BO's using that DAL. This way DAL and DTO are like data-centric objects whereas all Business Logic is kept in the 'real' Business Objects. I would like your opinion on such an approach and what can be the possible drawbacks for such an approach.

Help will be much appreciated.

Tahir

RockfordLhotka replied on Tuesday, October 16, 2007

In the CSLA model your factory method would call the data portal, and the initialization code would be in DataPortal_Create(). That way the code could run on the app server in an n-tier deployment without requiring changes to your object code.

The creation of a key and activation code probably should be in separate objects (from a design perspective), though I can surely see where they would likely be Shared methods at implementation time (though I'd put those Shared methods in their own classes to maintain better organization of code). Those classes would probably be Friend in scope though, as they'd only be used inside your business layer.

The difference between "OO" and "procedural" at implementation time can sometimes seem small. In my view, the big value of OO is at the design level, and the differences between OOD and procedural design are big, even though some of the "objects" defined by OOD are ultimately implemented as single methods.

Regarding your last question. I look at a DAL as a logical database. From my perspective as a business object author, the DAL is just how I get and store my data, nothing more.

So if I can reuse some parts of the DAL from different objects, that's no different from calling a common stored procedure from different objects. As long as I get the data I need, and only the data I need, then I'm happy.

But you must realize that this is a form of coupling. Any time you reuse code, the result is coupling. And coupling is a bad thing. So you need to balance the cost of coupling against the benefit of reuse and decide (on a case by case basis) whether the benefit outweights the cost.

If objects A and B both use DAL object D to get their data, what happens when A needs an extra 5 fields? Do you change D to provide those 5 fields? Did that break B? Or make B less efficient?

I personally suggest that when that happens (and it always happens!) that you need to create Da and Db. A uses Da and gets the extra 5 fields. B uses Db, which is the original D. At this point you've lost reuse, but avoided the high cost of coupling.

tna55 replied on Tuesday, October 16, 2007

Hi Rocky,

I will let you reply to my questions in previous post however just a quick note. We were always taught that an object contain data (properties) and methods and in OOA/D 'finding attributes' came always before 'assigning responsibilities'. May be that is why my approach like so many other people has been data-centric.

However, thinking about it, .NET Framework itself is an example infront of us where most of the objects are responsibility driven e.g. StreamReader is not there to store some data and perform operations on it, it is there for a reason (responsibility) and in order to do that it needs some data (e.g. filename).

Just a thought really. I am really enjoying my work even more now because thinking in terms of responsibility seems very 'natural'. It is hard 'only' because how we have been taught for years really.

If you do get time, do write a book on responsibility driven design. I am sure people will love it.

Tahir

webjedi replied on Tuesday, October 16, 2007

I'm not sure if this is helpful but I've found the following exercise very helpful in assisting me in thinking responsibility wise vs. data wise.

The code is JAVA based but the design principals are sound I believe.

http://www.math-cs.gordon.edu/courses/cs211/ATMExample/

RockfordLhotka replied on Tuesday, October 16, 2007

tna55:

I will let you reply to my questions in previous post however just a quick note. We were always taught that an object contain data (properties) and methods and in OOA/D 'finding attributes' came always before 'assigning responsibilities'. May be that is why my approach like so many other people has been data-centric.

Most people, including myself, were taught this data-centric way of thinking about object design. I learned the hard way, over years of fighting the same problems over and over again, that the responsibility-driven approach is better.

Other people, like Ward Cunningham, David West and others, have been pushing domain/behavioral/responsibility-driven OO design for years and years. If only I'd listened to them earlier, I'd have avoided a lot of pain Smile [:)]

tna55 replied on Tuesday, October 16, 2007

Many thanks,

Two follow up questions really.

1) Can you explain the difference between OOD and Procedural design?

2) I have read on various post that you learnt the hard way and after a lot of pain. Can you share with us the problems that you and/or anyone might have with data-centric approach?. The problem that I have (which I think is because of data-centric thinking) is that my objects 'were' just representing database tables and I use to assign responsibilities to this object thinking that 'it should do this because it contains the data to do this'. This lead to an object doing to many things and after few weeks into the project the code became un-managable.

Some people have mentioned that with RDD the properties/data is replicated in various BO's. To me it sounded 'bad' at first but then I thought of it in such a way: I am responsible for doing configuration management in my company and another person is responsible for doing testing. We both use same data i.e. source code however responsibilities are different.

Could you please advise me some books to read about RDD.

Many thanks once again.

Tahir

tna55 replied on Wednesday, October 17, 2007

Many thanks,

Two follow up questions really.

1) Can you explain the difference between OOD and Procedural design?

2) I have read on various post that you learnt the hard way and after a lot of pain. Can you share with us the problems that you and/or anyone might have with data-centric approach?. The problem that I have (which I think is because of data-centric thinking) is that my objects 'were' just representing database tables and I use to assign responsibilities to this object thinking that 'it should do this because it contains the data to do this'. This lead to an object doing to many things and after few weeks into the project the code became un-managable.

Some people have mentioned that with RDD the properties/data is replicated in various BO's. To me it sounded 'bad' at first but then I thought of it in such a way: I am responsible for doing configuration management in my company and another person is responsible for doing testing. We both use same data i.e. source code however responsibilities are different.

Could you please advise me some books to read about RDD.

Many thanks once again.

Tahir

tna55 replied on Wednesday, October 24, 2007

I would really appreciate some help with my last questions.

Many thanks

Tahir

RockfordLhotka replied on Wednesday, October 24, 2007

tna55:

I would really appreciate some help with my last questions.

Those are big questions. I answer them in bits and pieces as I have time - and across many threads. To pull it all together into some formal answer would be a lot of work. Ultimately it would be, at least, a series of lengthy articles or, at most, a book. I simply don't have the time for that level of formalization at this point, sorry.

I have been covering this in about 90 minutes during my VS Live all-day workshops. Hopefully I'll be able to do some of these workshops (updated for 3.5, etc) during the 2008 shows. It is somewhat easier to deliver a lot of experience and thoughts through speaking than through writing Smile [:)]

In terms of books, I recommend these:

 

Plowking replied on Thursday, October 25, 2007

Hi

This post is very interesting reading, I never really got the single responsibility per object thing until now. Cheers for spending the time answering those questions Rocky.

That design time objects can become, for example, implementation time static methods, clears up for me how CSLA objects can be considered single responsibility.

It also fits in my mind at least with CRC cards, and role playing to see which Entity objects (in CSLA "BOs") then host the static methods, if appropriate.

Ian

Nicholas Trevatt replied on Sunday, February 24, 2008

I just wanted to add a thank you to Rocky for the time he puts into this forum.  I find it great informative reading! 

Also, I would like to second the vote for you to write a book on the OOD subject.  Having read both Object Thinking and OO Technology I have no doubt that your ebook would hit the mark with me so much more effectively particularly if you had real world examples.  Don't get me wrong, those books are great but I just enjoy David West's comand of the English language too much and the subject matter gets lost in my awe Smile [:)]

I was also wondering if you could make the 90" VS-Live workshops available online in a .avi format or just make your own?  I'd pay money for that!

I have no doubt that your way to busy to do either of these projects but no harm in asking ay Smile [:)]

Thanks,
Nicholas


Copyright (c) Marimer LLC