How to define business object

  • Thread starter Thread starter Joanna Carter \(TeamB\)
  • Start date Start date
J

Joanna Carter \(TeamB\)

I have studied buisness layer in
http://beta.asp.net/QUICKSTART/util/srcview.aspx?path=~/aspnet/samples/data/
GridViewObject.src

It separate Author class to Author and AuthorComponent
If I combine the two together into Author Class for convenience, like
codes below:
Is it ok to do that?

This is not a good idea as you are going to be mixing functionality that is
not strictly part of the business object into that class.

IMO, the example is a poor one in the naming of the "AuthorComponent" class.
It is good to separate out the retrieval of a list of States and the
provision of a Comparer class as these don't necessarily belong in the
Author class. The aim of this example is to separate out classes to
accomodate an ASP control scenario, which is not necessarily the best way to
partition classes.

Are you aiming to use ASP or do you want to use the classes in a more
general business scenario ?

Joanna
 
Thank, I want to use the classes in a more general business scenario.
Could you give me more advice?
 
Thank, I want to use the classes in a more general business scenario.
Could you give me more advice?

In the example of an Author, I would use the class as it is demonstrated,
but would possibly also add a property which allows access to a list of
Books. But when it comes to retrieving a list of States, this is really not
a part of the Author class, it seems to be just a utility function that
isn't actually used or even necessary.

If you need to get a list of Authors according to which State they live in
then you could consider adding a static method to the Author Class

class Author
{
...

public static List<Author> GetAuthorsByState(string state)
{
AuthorsDB.GetAuthorsByState(state);
}
}.

However, placing code that knows about database functionality means that you
have inextricably tied your business class to using one particular type of
database; something you might want to change later on.

So instead, it is a good idea to develop something known as an OPF (Object
Persistence Framework). Now OPFs can be as simple or as complicated as you
wish, but one way is to use the idea of something like the AuthorComponent
as described in the example.

I would remove the GetStates method from the whole example as it seems to
server no purpose and is not part of the Author class's responsibilities.

But apart from that the idea of the AuthorComponent class is to act as a
mediator so that the Author class need know nothing about getting its own
data, it is just submitted to the AuthorComponent for
storage/retrieval/deletion and it is the Component class that is the only
class that needs to know anything about databases.

Personally, I would change all the methods of the AuthorsComponent class to
be static as there is no state data required.

So then you could rewrite the static GetAuthorsByState method to address the
component class.

class Author
{
...

public static List<Author> GetAuthorsByState(string state)
{
AuthorsComponent.GetAuthorsByState(state);
}
}.

To give you an idea of what a true OPF provides, here is an extract from one
of mine :

class PersistenceBroker
{
public static bool StoreObject(object obj)
{
...
}

public static bool DeleteObject(object obj)
{
...
}

public static T RetrieveObject<T>()
{
...
}

public static List<T> RetrieveList<T>()
{
...
}

public static List<T> RetrieveList<T>(Criteria crit)
{
...
}
}

Now internally, there is a system of class maps that allow me to detect
which type of object has been passed in and to select the appropriate
internal connection for handling instances of that type. The Connection
classes can use SQL, XML, text, or any other means of storage; the trick
being that it doesn't matter what the underlying data mechanism is, each
Connection knows how to do whatever translation is required.

In the example of an SQL Connection, you can either auto-generate the SQL on
the fly or you can create custom translation classes, one for each type to
be stored.

The overriding raison d'être for this level of separation of data from
business classes is the provision of a flexible framework that allows you to
change database without having to change any of your business logic.

Likewise, the Component example you cited also allows us to separate the UI
(in this case ASP) from the business layer; equally important if you want to
write all your business logic only once, regardless of whether you want to
display objects in a WinForms or ASP app.

Take a look at some articles on OPF and MVP on my website for further
information. Then I guess you might have one or two more questions ? :-))

www.carterconsulting.org.uk

Joanna

--
Joanna Carter (TeamB)

Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
 
Please ensure that your system clock is set correctly. People who push to
the head of the queue are generally considered as rude.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
Joanna,

Very interesting that you can write so much sensible comments about so
meaningless a piece of code. However somewhere in your comments I have
to disagree.

Regards,
Rick


In the example of an Author, I would use the class as it is demonstrated,
but would possibly also add a property which allows access to a list of
Books. But when it comes to retrieving a list of States, this is really not
a part of the Author class, it seems to be just a utility function that
isn't actually used or even necessary.

If you need to get a list of Authors according to which State they live in
then you could consider adding a static method to the Author Class

class Author
{
...

public static List<Author> GetAuthorsByState(string state)
{
AuthorsDB.GetAuthorsByState(state);
}
}.

However, placing code that knows about database functionality means that you
have inextricably tied your business class to using one particular type of
database; something you might want to change later on.
1) AuthorsDB could be some a data management class which makes Author
independent of every database knowledge.
2) Writing for multiple database support is a much overrated scenario.
80% of the time a program supports 1 database platform for its entire
life.
 
Rick Elbers said:
Joanna,

Very interesting that you can write so much sensible comments about so
meaningless a piece of code. However somewhere in your comments I have
to disagree.

Regards,
Rick



1) AuthorsDB could be some a data management class which makes Author
independent of every database knowledge.
2) Writing for multiple database support is a much overrated scenario.
80% of the time a program supports 1 database platform for its entire
life.




2) Writing for multiple database support is a much overrated scenario.
80% of the time a program supports 1 database platform for its entire
life.
I agree on that one.
But if you only design the application for that, you will have a huge job
redesigning the whole program if the program must support another engine.
If you have that in mind when designing your program the time you save
is huge if changed to another DB and minor at design time.
 
Very interesting that you can write so much sensible comments about so
meaningless a piece of code. However somewhere in your comments I have
to disagree.

Well, I was trying to reinforce the intent of the cited example to separate
business logic from everything else like data storage and UI. But it is a
truly horrible example :-)
1) AuthorsDB could be some a data management class which makes Author
independent of every database knowledge.
2) Writing for multiple database support is a much overrated scenario.
80% of the time a program supports 1 database platform for its entire
life.

As I mentioned I have a much more comprehensive approach to object storage;
reducing such a monster to simple concepts is quite difficult. In fact it is
more difficult to write application code for a simple persistence mechanism
than it is to do so for a more comprehensive one.

You are correct in saying that most applications only ever get to talk to
one type of database, but the design of a good OPF so separates the business
layer from *any* database knowledge that it is simplicity itself to change
DB at will; not the original aim maybe but a very useful side-effect :-)

Joanna

--
Joanna Carter (TeamB)

Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
 
"Joanna Carter said:
You are correct in saying that most applications only ever get to talk to
one type of database, but the design of a good OPF so separates the business
layer from *any* database knowledge that it is simplicity itself to change
DB at will; not the original aim maybe but a very useful side-effect :-)

Agree entirely, and given that the hard part of the abstraction layer is
done for you (that's what System.Data *is*) there's no real reason not
to implement a separate data access tier.
 
I have studied buisness layer in
http://beta.asp.net/QUICKSTART/util/srcview.aspx?path=~/aspnet/samples/data/GridViewObject.src

It separate Author class to Author and AuthorComponent
If I combine the two together into Author Class for convenience, like
codes below:
Is it ok to do that?





------------Code-------------------------------------------------
public class Author
{
private String _id;

public String ID
{
get
{
return _id;
}

set
{
_id = value;
}
}

private String _name;

public String Name
{
get
{
return _name;
}
set { _name = value; } } private String _lastName;
......

public Author (String id, String name, String lastName, String state)
{
this.ID = id;
this.Name = name;
this.LastName = lastName;
this.State = state;
}

public Author()
{
// default constructor
}

public List<Author> GetAuthorsByState (String state, String
sortExpression)
{
List<Author> authors = new List<Author> ();
DataSet ds = AuthorsDB.GetAuthorsByState (state);

foreach (DataRow row in ds.Tables[0].Rows)
{
authors.Add (new Author ((String)row["au_id"],
(String)row["au_fname"], (String)row["au_lname"], (String)row["state"]));
}

authors.Sort(new AuthorComparer(sortExpression));
return authors;
}

public int UpdateAuthor (string ID, string LastName, string Name, string
State)
{
return AuthorsDB.UpdateAuthor (ID, LastName, Name, State);
}

public int UpdateAuthor(Author a)
{
return AuthorsDB.UpdateAuthor(a.ID, a.LastName, a.Name, a.State);
}

public List<String> GetStates()
{
List<String> states = new List<String>();
DataSet ds = AuthorsDB.GetStates();

foreach (DataRow row in ds.Tables[0].Rows)
{
states.Add((String)row["state"]);
}
return states;
}
}

}
 
Back
Top