"ad" <ad@wfes.tcc.edu.tw> a écrit dans le message de news:
ea**************@TK2MSFTNGP10.phx.gbl...
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