|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
"Business Objects" and the DALIn designing a basic n-tier application, what exactly is the relationship between the "Business Objects" and the "Data Access Layer"? In the past when I have attempted to make an n-tier application, business objects end up basically being a representation of the data from the database. I see terms like "Business Rules" and "Business Logic" and I just don't understand what that is? I have a couple questions I hope someone can answer for me: 1) Should the Business Objects make calls to the DAL? ( IE: BusinessObjectCollection BusinessObject::GetCustomers() calls DataSet Dal::GetCustomers() ) then the Business Object builds itself up from the results of the DAL DataSet, or should there be a third class that gets a DataSet from a DAL, then passes it to a business object to digest? 2) Can someone please give me 1 or 2 examples of a Business Rule and Business Logic? Tons of articles make reference to the two, but finding an example is next to impossible. Spinning my wheels, I really hope someone can shed some light on this. Thanks for reading, Steve Klett Steve wrote:
> I still can't get my head around this. Depends on how you look at data. > > In designing a basic n-tier application, what exactly is the > relationship between the "Business Objects" and the "Data Access > Layer"? > In the past when I have attempted to make an n-tier application, In general, developers agreed more or less on the concept of abstract> business objects end up basically being a representation of the data > from the database. I see terms like "Business Rules" and "Business > Logic" and I just don't understand what that is? I have a couple > questions I hope someone can answer for me: > > 1) Should the Business Objects make calls to the DAL? ( IE: > BusinessObjectCollection BusinessObject::GetCustomers() calls > DataSet Dal::GetCustomers() ) then the Business Object builds > itself up from the results of the DAL DataSet, or should there be a > third class that gets a DataSet from a DAL, then passes it to a > business object to digest? entities, like you have 'customer', 'order', product'. You can define relations between these entities. Now, for some the physical representation of these entities in a database model, like in table / view form, is the way to go. Others think in classes where you have a class representing an entity like customer, order, product and these are eventually saved somewhere in a database. So this is more a discussion about semantics: where is the physical representation defined of an abstract definition of an entity. Ok, you can go a step further. Say you define an entity's definition in a class. Then you can define behavior in that class as well, thus the code related to the data in the class, like you would do in normal OO. Take for example logic related to persistence of the data inside the entity object: e.g. the Save() method. Should that logic be part of the entity class? Or should that be part of some external class? Or maybe a generic persistence object? Not truly definable: some say they find it logical that the behavior (Save()) is part of the entity class, others say persistence is a service applied to an entity class, so it should be placed outside the entity class. I.o.w.: it depends on how you look at things, both have pro's and con's. You can go even further. Say you have the entities Customer, Order and OrderLine. You can then define a new class called SalesOrder. SalesOrder has a reference to a customer, an order and that order contains several orderlines. The behavior of the SalesOrder isn't part of customer, order or orderline, but part of salesorder and it's treated as a single unit. Should you go this far? Unclear, if you find it more appropriate for your project, i.e.: it makes sense, do it. If not, leave it. With all of this: keep in mind that all of this only works if it makes sense to you, if it matches the way you want to work with data, the way you look at how data is used in a software system. If you think in tables and raw SQL, it's a bit hard to imagine what an entity is, at least it's a step away from what you're working with. > 2) Can someone please give me 1 or 2 examples of a Business Rule and Keep in mind that as with everything in IT, it's largely buzzword> Business Logic? Tons of articles make reference to the two, but > finding an example is next to impossible. driven. Business Logic/rules/code/tier, it's all about that piece of your application which defines the application logic. So, simply put: you have 3 parts: the GUI part which is meant to be the interface to the actual logic in your application, a business logic part which is the actual logic in your application and the data-access part which is the layer which makes the business logic part be able to persist data and read data as a result of business logic processing. there are roughly 3 categories of rules: - single field rules: CustomerID must be > 0, inventory can't be negative etc. - single entity rules: ShippingDate must be >= orderdate. - cross entity rules: A customer is a gold customer if s/he purchased more than n orders in the last m months in general the first 2 are placed inside an entity class, the 3rd can be placed outside the entity class as it relates to more than one entity. You can see these rules as both validation rules but also as rules when something is true or not, like the gold customer example. Frans -- ------------------------------------------------------------------------ Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com My .NET blog: http://weblogs.asp.net/fbouma Microsoft MVP (C#) ------------------------------------------------------------------------ WOW! Man, what a great post. Thank you so much for taking that time, this
one is going to the printer for sure. OK, this is great, thanks again, Steve Show quote "Frans Bouma [C# MVP]" <perseus.usenetNOSPAM@xs4all.nl> wrote in message news:xn0eijpdg4m11s003@news.microsoft.com... > Steve wrote: > >> I still can't get my head around this. >> >> In designing a basic n-tier application, what exactly is the >> relationship between the "Business Objects" and the "Data Access >> Layer"? > > Depends on how you look at data. > >> In the past when I have attempted to make an n-tier application, >> business objects end up basically being a representation of the data >> from the database. I see terms like "Business Rules" and "Business >> Logic" and I just don't understand what that is? I have a couple >> questions I hope someone can answer for me: >> >> 1) Should the Business Objects make calls to the DAL? ( IE: >> BusinessObjectCollection BusinessObject::GetCustomers() calls >> DataSet Dal::GetCustomers() ) then the Business Object builds >> itself up from the results of the DAL DataSet, or should there be a >> third class that gets a DataSet from a DAL, then passes it to a >> business object to digest? > > In general, developers agreed more or less on the concept of abstract > entities, like you have 'customer', 'order', product'. You can define > relations between these entities. Now, for some the physical > representation of these entities in a database model, like in table / > view form, is the way to go. Others think in classes where you have a > class representing an entity like customer, order, product and these > are eventually saved somewhere in a database. So this is more a > discussion about semantics: where is the physical representation > defined of an abstract definition of an entity. > > Ok, you can go a step further. Say you define an entity's definition > in a class. Then you can define behavior in that class as well, thus > the code related to the data in the class, like you would do in normal > OO. > > Take for example logic related to persistence of the data inside the > entity object: e.g. the Save() method. Should that logic be part of the > entity class? Or should that be part of some external class? Or maybe a > generic persistence object? Not truly definable: some say they find it > logical that the behavior (Save()) is part of the entity class, others > say persistence is a service applied to an entity class, so it should > be placed outside the entity class. I.o.w.: it depends on how you look > at things, both have pro's and con's. > > You can go even further. Say you have the entities Customer, Order and > OrderLine. You can then define a new class called SalesOrder. > SalesOrder has a reference to a customer, an order and that order > contains several orderlines. The behavior of the SalesOrder isn't part > of customer, order or orderline, but part of salesorder and it's > treated as a single unit. > > Should you go this far? Unclear, if you find it more appropriate for > your project, i.e.: it makes sense, do it. If not, leave it. > > With all of this: keep in mind that all of this only works if it makes > sense to you, if it matches the way you want to work with data, the way > you look at how data is used in a software system. If you think in > tables and raw SQL, it's a bit hard to imagine what an entity is, at > least it's a step away from what you're working with. > >> 2) Can someone please give me 1 or 2 examples of a Business Rule and >> Business Logic? Tons of articles make reference to the two, but >> finding an example is next to impossible. > > Keep in mind that as with everything in IT, it's largely buzzword > driven. > > Business Logic/rules/code/tier, it's all about that piece of your > application which defines the application logic. So, simply put: you > have 3 parts: the GUI part which is meant to be the interface to the > actual logic in your application, a business logic part which is the > actual logic in your application and the data-access part which is the > layer which makes the business logic part be able to persist data and > read data as a result of business logic processing. > > there are roughly 3 categories of rules: > - single field rules: CustomerID must be > 0, inventory can't be > negative etc. > - single entity rules: ShippingDate must be >= orderdate. > - cross entity rules: A customer is a gold customer if s/he purchased > more than n orders in the last m months > > in general the first 2 are placed inside an entity class, the 3rd can > be placed outside the entity class as it relates to more than one > entity. > > You can see these rules as both validation rules but also as rules > when something is true or not, like the gold customer example. > > > Frans > > > -- > ------------------------------------------------------------------------ > Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com > My .NET blog: http://weblogs.asp.net/fbouma > Microsoft MVP (C#) > ------------------------------------------------------------------------ The most important thing about n-tier application design is that each
layer talks to the layer next to it. The purpose for this is abstraction. If you have three layers, UI, Business, and Data, then the UI layer should never talk to the Data layer (and vice versa). I've seen people create a BAL class and DAL class for every entity because they wanted to implement the "traditional three tier application design". The data entity returned a dataset, and the business entity returned that up to the UI for binding to a grid. But there is a problem. This does not include any abstraction between database entities and the UI. If a database table column names changes, then the entire application has to adjust, including the datagrid that is bound to the dataset. I propose an alternative. Use custom entities. The business layer is responsible for returning the same consistent entities no matter how the database and data layer code changes. The "data layer" is for calling database stored procedures to update, insert, delete, or select data. Next you'll question how you organize these layers and classes into components. There are multiple schools of thought on that, and I'll point out a few below. Start by defining what your entities are, and what properties those entities have. Also map out what the relationships between the entities are. You may want to do all this on paper or a UML tool like Visio before you write any code. Next what database entities will you need to call to fill these entities? Are you using stored procedures, or are you using dynamic *parameterized* queries. I strongly discourage dynamically build unparameterized queries. What parameter values are required for the updates/inserts/deletes? What columns will be returned by the select queries or stored procedures? Have you accounted for all these required items in your entity designs? Once you have all that information, it is time to design how you'll organize your components / layers. As I said before, I've seen multiple ways of doing this. There is no one "correct" way to do it. Each could be considered a "pattern", and most are documented somewhere. Many companies may have designed their own pattern that is similar to another published pattern. In rare cases, some companies have some great new pattern. I can't tell you which pattern you should use for your scenario, but I can point you in the direction for a few of them. Pattern 1: "Business Layer Fully Functional Entities". This doesn't map to an exact pattern that I've seen anywhere, so I gave it my own name. Essentially there is a single business layer. It contains the entities, and each entity contains Save, Load, and Delete methods. These methods may either be static or instance. The static methods may return a collection of that entity type. An organization that uses this pattern typically has their own common data component that makes the actual calls to the database. Some of these components may be database neutral. An example that many use as a base is the Microsoft Enterprise Data Application Block. These business entity methods call the custom data component to make database calls. Then the UI calls these business classes to perform operations, and uses those entities to bind to their datagrid, or other controls. Pattern 2: "Typical UI - BAL - DAL 3 tier design". This design has one extra tier than pattern 1. The BAL is identical, except that instead of calling the database component directly, it makes an identical call on a same named DAL class. The dal class handles the decision as to what database should be called. This design may or may not use a separate data operations component. This component may return a DataReader, a DataSet, or a special more lightweight data transport container to the BAL layer. Pattern 2b: "UI - BAL - DAL factories" the only difference in this pattern is that the DAL classes are not the same name as the BAL classes. Instead functionality is grouped into data factories, which may not map as simply to the business entities. Instead it maps to the database tables. If the business entities are a direct map to the database tables, then pattern 2 and 2b are effectively the same, except that the DAL classes have the suffix "Factory". Pattern 3: "Provider Pattern". This pattern is used extensively in the ..net framework 2.0. Have you seen the membership system? Is uses the provider pattern. You can create you own MembershipProvider that determines how each call is made. In other words, you decide what database to call, what stored procedure, and what return columns are used to fill the base framework user class. For an example of the .Net 2.0 membership system, see the following which describes how to use this pattern in .net 1.1: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspnet/html/asp04212004.asp I use pattern 3 in development of my components. You can see a full API documentation with some examples on my web site here: http://www.xquisoft.com/xqsdn/documentation/index.html Here are a direct links to examples: "An employee provider" http://www.xquisoft.com/xqsdn/documentation/xquisoft.data.datamanager.html "EmployeeFactory and EmployeeDbMap" http://www.xquisoft.com/xqsdn/documentation/XQuiSoft.Data.IDataFactory.html (The employee class iteself is a simple class with a couple public properties only, not shown.) For more API examples (no source) see the following: >From the table of contents see the XQuiSoft.Security component, User class, UserManager class, and UserProvider class. This component isbasically my "Business layer" Also see XQuiSoft.Security.Data, DbUserProvider class, UserFactory class, and UserDbMap class. This component is basically my "data layer". The user interface layer calls the business layer "manager" class to authenticate a user. The ui layer can then store that user in session for the next page request. It could also display that user in an edit page, update it, and then call the "manager" class to save the user. The actual work in the provider pattern is done by the providers. In this case UserProvider is the abstract base class, and DbUserProvider makes the calls through the database via the UserFactory class. Application configuration determines the provider type that is used to fulfil requests to the manager. UserFactory uses UserDbMap just to get the name constants for the user database tables. Note that the XQuiSoft.Data component is open source, and you can find it here: http://sourceforge.net/projects/xqs-data/ So is my version of the provider pattern in .net 1.1: http://sourceforge.net/projects/xqs-provider/ Michael Lang XQuiSoft LLC http://www.xquisoft.com/ This is incredible! I need to review my original post and determine hwo I
wrote that to catch 2 amazing responses like this! Mike, thank you so much, I'm following right along with you and soaking all this knowledge up, this is a great post. Thank you for beign so thorough, Steve Klett PS: Also printing yours :) Show quote "Mike" <michael.l***@xquisoft.com> wrote in message news:1140110441.136567.66220@z14g2000cwz.googlegroups.com... > The most important thing about n-tier application design is that each > layer talks to the layer next to it. The purpose for this is > abstraction. If you have three layers, UI, Business, and Data, then > the UI layer should never talk to the Data layer (and vice versa). > > I've seen people create a BAL class and DAL class for every entity > because they wanted to implement the "traditional three tier > application design". The data entity returned a dataset, and the > business entity returned that up to the UI for binding to a grid. But > there is a problem. This does not include any abstraction between > database entities and the UI. If a database table column names > changes, then the entire application has to adjust, including the > datagrid that is bound to the dataset. > > I propose an alternative. Use custom entities. The business layer is > responsible for returning the same consistent entities no matter how > the database and data layer code changes. The "data layer" is for > calling database stored procedures to update, insert, delete, or select > data. Next you'll question how you organize these layers and classes > into components. There are multiple schools of thought on that, and > I'll point out a few below. > > Start by defining what your entities are, and what properties those > entities have. Also map out what the relationships between the > entities are. You may want to do all this on paper or a UML tool like > Visio before you write any code. > > Next what database entities will you need to call to fill these > entities? Are you using stored procedures, or are you using dynamic > *parameterized* queries. I strongly discourage dynamically build > unparameterized queries. What parameter values are required for the > updates/inserts/deletes? What columns will be returned by the select > queries or stored procedures? Have you accounted for all these > required items in your entity designs? > > Once you have all that information, it is time to design how you'll > organize your components / layers. As I said before, I've seen > multiple ways of doing this. There is no one "correct" way to do it. > Each could be considered a "pattern", and most are documented > somewhere. Many companies may have designed their own pattern that is > similar to another published pattern. In rare cases, some companies > have some great new pattern. I can't tell you which pattern you should > use for your scenario, but I can point you in the direction for a few > of them. > > Pattern 1: "Business Layer Fully Functional Entities". This doesn't > map to an exact pattern that I've seen anywhere, so I gave it my own > name. Essentially there is a single business layer. It contains the > entities, and each entity contains Save, Load, and Delete methods. > These methods may either be static or instance. The static methods may > return a collection of that entity type. An organization that uses > this pattern typically has their own common data component that makes > the actual calls to the database. Some of these components may be > database neutral. An example that many use as a base is the Microsoft > Enterprise Data Application Block. These business entity methods call > the custom data component to make database calls. Then the UI calls > these business classes to perform operations, and uses those entities > to bind to their datagrid, or other controls. > > Pattern 2: "Typical UI - BAL - DAL 3 tier design". This design has one > extra tier than pattern 1. The BAL is identical, except that instead > of calling the database component directly, it makes an identical call > on a same named DAL class. The dal class handles the decision as to > what database should be called. This design may or may not use a > separate data operations component. This component may return a > DataReader, a DataSet, or a special more lightweight data transport > container to the BAL layer. > > Pattern 2b: "UI - BAL - DAL factories" the only difference in this > pattern is that the DAL classes are not the same name as the BAL > classes. Instead functionality is grouped into data factories, which > may not map as simply to the business entities. Instead it maps to the > database tables. If the business entities are a direct map to the > database tables, then pattern 2 and 2b are effectively the same, except > that the DAL classes have the suffix "Factory". > > Pattern 3: "Provider Pattern". This pattern is used extensively in the > .net framework 2.0. Have you seen the membership system? Is uses the > provider pattern. You can create you own MembershipProvider that > determines how each call is made. In other words, you decide what > database to call, what stored procedure, and what return columns are > used to fill the base framework user class. For an example of the .Net > 2.0 membership system, see the following which describes how to use > this pattern in .net 1.1: > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspnet/html/asp04212004.asp > > I use pattern 3 in development of my components. You can see a full > API documentation with some examples on my web site here: > http://www.xquisoft.com/xqsdn/documentation/index.html > > Here are a direct links to examples: > "An employee provider" > http://www.xquisoft.com/xqsdn/documentation/xquisoft.data.datamanager.html > "EmployeeFactory and EmployeeDbMap" > http://www.xquisoft.com/xqsdn/documentation/XQuiSoft.Data.IDataFactory.html > (The employee class iteself is a simple class with a couple public > properties only, not shown.) > > For more API examples (no source) see the following: >>From the table of contents see the XQuiSoft.Security component, User > class, UserManager class, and UserProvider class. This component is > basically my "Business layer" > Also see XQuiSoft.Security.Data, DbUserProvider class, UserFactory > class, and UserDbMap class. This component is basically my "data > layer". > The user interface layer calls the business layer "manager" class to > authenticate a user. The ui layer can then store that user in session > for the next page request. It could also display that user in an edit > page, update it, and then call the "manager" class to save the user. > > The actual work in the provider pattern is done by the providers. In > this case UserProvider is the abstract base class, and DbUserProvider > makes the calls through the database via the UserFactory class. > Application configuration determines the provider type that is used to > fulfil requests to the manager. UserFactory uses UserDbMap just to get > the name constants for the user database tables. > > Note that the XQuiSoft.Data component is open source, and you can find > it here: http://sourceforge.net/projects/xqs-data/ > So is my version of the provider pattern in .net 1.1: > http://sourceforge.net/projects/xqs-provider/ > > Michael Lang > XQuiSoft LLC > http://www.xquisoft.com/ > In article <1140110441.136567.66***@z14g2000cwz.googlegroups.com>, Mike
<michael.l***@xquisoft.com> writes <snip> Nice post, makes very interesting reading, thanks. Incidentally, there's a typo on your front page. In the first sentence of the final paragraph, "it's" should be "its" :) -- Toby There are already some excellent posts in this thread about how DAL fits into
an n-tier application. If you want to see an example of DAL implementation, you can check the famous .NET Pet Shop application at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/petshop3x.asp .. The Pet Shop DAL implementation has recently been re-architected using NJDX OR-Mapping technology, which simplfies persistence of business objects (aka domain model objects). You can see a detailed report on that project at http://www.softwaretree.com/products/njdx/whitepaper/NJDXPetShopProjectReport.pdf .. Steve wrote: Show quote >I *still* can't get my head around this. > >In designing a basic n-tier application, what exactly is the relationship >between the "Business Objects" and the "Data Access Layer"? > >In the past when I have attempted to make an n-tier application, business >objects end up basically being a representation of the data from the >database. I see terms like "Business Rules" and "Business Logic" and I just >don't understand what that is? I have a couple questions I hope someone can >answer for me: > >1) Should the Business Objects make calls to the DAL? ( IE: >BusinessObjectCollection BusinessObject::GetCustomers() calls DataSet >Dal::GetCustomers() ) then the Business Object builds itself up from >the results of the DAL DataSet, or should there be a third class that gets a >DataSet from a DAL, then passes it to a business object to digest? > >2) Can someone please give me 1 or 2 examples of a Business Rule and >Business Logic? Tons of articles make reference to the two, but finding an >example is next to impossible. > >Spinning my wheels, I really hope someone can shed some light on this. > >Thanks for reading, >Steve Klett |
|||||||||||||||||||||||