An Abstraction Too Far??

R

RichB

I am trying to investigate design options for an application using seperate
layers and only passing data transfer objects (i.e. objects just of a data
struture to transfer data within the application) between the layers. If I
look at the Data Layer, I have a class which is a factory with for example a
"public Response Synchronise (iSycronisable dto)" method.

"iSyncronisable" is an interface, though there is nothing in the interface
to implement and the "Response" object is an abstract object with no
implementation (though of course this could be an interface aswell).

The reasoning behind this is that the Syncronise method can be called with
any object which derives from the iSyncronisable interface. The code in the
DAL factory creates a Data Access Object which knows all about the
interaction with the database for that type of Object and depending on
whether the object is new or existing decides to add new, update or delete
existing data. If a derived type is passed which was not understood by the
method, then an exception would be thrown.

The "Response" may then be different objects dependent on the action taken
and the iSyncronisable object passed. The calling class obviously needs to
then act on this object according to it's type.

Is this a reasonable thing to do or is it a no-no to use an interface or
abstract class to 'label' it's derived classes?

I would appreciate any advice or alternative suggestions.
Thanks, Richard
 
B

Brian Gideon

I am trying to investigate design options for an application using seperate
layers and only passing data transfer objects (i.e. objects just of a data
struture to transfer data within the application) between the layers. If I
look at the Data Layer, I have a class which is a factory with for examplea
"public Response Synchronise (iSycronisable dto)" method.

"iSyncronisable" is an interface, though there is nothing in the interface
to implement and the "Response" object is an abstract object with no
implementation (though of course this could be an interface aswell).

The reasoning behind this is that the Syncronise method can be called with
any object which derives from the iSyncronisable interface. The code in the
DAL factory creates a Data Access Object which knows all about the
interaction with the database for that type of Object and depending on
whether the object is new or existing decides to add new, update or delete
existing data. If a derived type is passed which was not understood by the
method, then an exception would be thrown.

The "Response" may then be different objects dependent on the action taken
and the iSyncronisable object passed. The calling class obviously needs to
then act on this object according to it's type.

Is this a reasonable thing to do or is it a no-no to use an interface or
abstract class to 'label' it's derived classes?

I would appreciate any advice or alternative suggestions.
Thanks, Richard

The Framework Design Guidelines says to "avoid using marker
interfaces" and instead use a custom attribute. The book never really
explains the logic behind this, but does list two exceptions to that
rule. First, checking a type for an attribute is more costly than
checking for an interface so if performance is a concern then choose
the interface. Second, the check for the attribute can only occur at
run-time whereas an interface can be enforced at compile-time.

My personal opinion is that using marker interfaces or classes is fine
generally speaking. I can see that it could make an API a little more
self documenting. Though, with most situations I think the decision
should be made on a case-by-case basis.
 
A

Alun Harford

RichB said:
I am trying to investigate design options for an application using
seperate layers and only passing data transfer objects (i.e. objects
just of a data struture to transfer data within the application) between
the layers.

This idea is pretty nasty. DTOs are sometimes needed to transfer data
between *systems* (although transfering plain old CLR objects is
generally better if you possibly can - maintaining 2 classes instead of
1 is nasty - see the NHibernate/Entity Framework war over POCOs for more
good information) but I cannot see any good reason to use them to
transfer data within the application.

Generally, you'd want to pass around an object that implements an
interface and other components within the system need not understand the
implementation details of the underlying object.

Alun Harford
 
T

Tim Jarvis

RichB said:
I would appreciate any advice or alternative suggestions.
Thanks, Richard

I have been re-thinking lately about some aspects of OO design, so
please bear with me, I'd really love to hear other peoples idea's on
this.

The idea of layering our applications into Presentation, Data and
Business Logic has been born out of practicality and notions of
resuability, for example if we are saving our Customer object into an
Oracle database and we are using CoreLabs Oracle components to access
that database it makes no sense to tie that dependency to the Customer
object itself, in fact the best practice is to write a data mapper
class (and possibly even separate assembly) to take up that dependency
along with the ER mapping logic this means that our Customer class
could possibly be re-used elsewhere and put into a SQL Sever database
for example. However, in a perfect OO world, it would be great if we
could simply load and save our Customer object directly i.e.
Cust.Load(); Cust.Save(); etc. This really is from a consumer of our
class point of view the easiest contract to learn and use.

So, here is my crazy thought, it seems to me that Extension methods
will give us the best of both worlds here, the ability to physically
separate these layers for all the reasons thats now best practice, and
provide the ability to make it look (to the class consumer) as if its
all part of the same object...

So you could still have a basic re-usable class like

public class Customer
{
public string Name {get;set;}
public string Address {get;set;}
}


and in another assembly have.....


using Some3rdPartyDataBaseProvider;


public static class CustomerDataAccessExtensions
{
public static void Load(this Customer c)
{
// etc
}
}

Thoughts?

Regards Tim.

--
 
R

RichB

Thanks, I'll take a look through the Framework Design Guidlines. I
suspecteded that this may be one of those things that are fairly normally
used, but offensive to some people.

Thanks for your response.

Richard


I am trying to investigate design options for an application using
seperate
layers and only passing data transfer objects (i.e. objects just of a data
struture to transfer data within the application) between the layers. If I
look at the Data Layer, I have a class which is a factory with for example
a
"public Response Synchronise (iSycronisable dto)" method.

"iSyncronisable" is an interface, though there is nothing in the interface
to implement and the "Response" object is an abstract object with no
implementation (though of course this could be an interface aswell).

The reasoning behind this is that the Syncronise method can be called with
any object which derives from the iSyncronisable interface. The code in
the
DAL factory creates a Data Access Object which knows all about the
interaction with the database for that type of Object and depending on
whether the object is new or existing decides to add new, update or delete
existing data. If a derived type is passed which was not understood by the
method, then an exception would be thrown.

The "Response" may then be different objects dependent on the action taken
and the iSyncronisable object passed. The calling class obviously needs to
then act on this object according to it's type.

Is this a reasonable thing to do or is it a no-no to use an interface or
abstract class to 'label' it's derived classes?

I would appreciate any advice or alternative suggestions.
Thanks, Richard

The Framework Design Guidelines says to "avoid using marker
interfaces" and instead use a custom attribute. The book never really
explains the logic behind this, but does list two exceptions to that
rule. First, checking a type for an attribute is more costly than
checking for an interface so if performance is a concern then choose
the interface. Second, the check for the attribute can only occur at
run-time whereas an interface can be enforced at compile-time.

My personal opinion is that using marker interfaces or classes is fine
generally speaking. I can see that it could make an API a little more
self documenting. Though, with most situations I think the decision
should be made on a case-by-case basis.
 
R

RichB

Alun,
Thanks for your response. You have outlined my concerns regarding DTOs well.
I have may be 30 classes in my model, which translate to roughly 25 DTOs
most of which are pretty close duplicates of those classes, I then have
differences between the DTOs used by the Business Layer and those used by
the DB layer which introduces as you say a real maitainance nightmare.

You stated that "DTOs are sometimes needed to transfer data between
*systems*". By "Systems" do you mean seperate applications or are you
referring to seperate physical machine tiers? If you are refering to the
former, then without DTOs how is the application deployed?

In simplest terms if you have 3 layers UI, BOL, DAL you might have 3
assemblies now the DAL would be deployed on the Database server, BOL on
application server and UI on Web Server. However if they are on seperate
machines, then how does the structure of an object on the BOL transfer to
the DAL without it knowing what that structure is in advance? If each object
implements interfaces which describe the data structure of the object (as I
think is implied in your answer) and these interfaces are deployed to the
layers in which they are used, then how does this really differ from the DTO
approach?

I realise that these are pretty fundamental questions of architecture and am
happy to do some background reading if you are able to refer me to
appropriate online or offline resource.

Thanks, Richard
 
R

RichB

Tim,

Sorry that I hadn't responded sooner, but I needed to sit down and think
about the problem subsequent in the light of the response from Alun.

I got a little lost in your response, but I am looking at this with a pretty
simple mind. In your example it appears that Customer is effectivly a DTO,
so all data and no behaviour, then is your CustomerDataAccessExtensions
within your Data Access Layer. The method within that class is a little odd
and perhaps needs some explanation:

public static void Load(this Customer c)

Firstly, I am not sure what the 'this' is doing... I assume that the method
takes a Customer object as a parameter and is responsible for loading the
data to the database?

If this is the case, then this is essentially what I am already doing, it is
just that my Load method is called Sychronise and it takes an
iSynchronisable object as a parameter and depending on whether that object
is a customer or product object and whether it has an id on the object, it
will create a corresponding Data Access Object (which knows how too interact
with the database for that type of object) and creates a new record or
updates an existing record if id is provided.

In order to do that the method signature is public DataResponse
Synchronise(iSyncronisable syncObject)

This is called by my business Layer which therefore must reference the DAL.
The iSyncronisable and DataResponse classes must therefore be defined within
the DAL or a seperate Assembly reffered to be the BOL and DAL (I actually
have them in a seperate assembly).

Either way they are effectively DTOs and I do not know of any other way of
doing this unless the BOL and DAL are within the same assembly which then
makes them impossible to physically seperate. The same problem is replicated
between BOL and UI.

If I have misunderstood your post then please provide a little more to your
example to explain further, otherwise I would be interested in any furthe
thoughts that you or anyone else might have.

Thanks,
Richard
 
T

Tim Jarvis

RichB said:
Tim,

Sorry that I hadn't responded sooner, but I needed to sit down and
think about the problem subsequent in the light of the response from
Alun.

No Probs
I got a little lost in your response, but I am looking at this with a
pretty simple mind. In your example it appears that Customer is
effectivly a DTO, so all data and no behaviour, then is your

Ah, not meant to be a DTO, I just didn't add any behaviour in the
example but that would be the intention.
CustomerDataAccessExtensions within your Data Access Layer. The
method within that class is a little odd and perhaps needs some
explanation:

public static void Load(this Customer c)

Firstly, I am not sure what the 'this' is doing... I assume that the
method takes a Customer object as a parameter and is responsible for
loading the data to the database?

Sorry I had assumed that most people had come across extension methods,
in hindsight thats a bad assumption, they are pretty new still. This
method uses the keyword "this" in a special way, it will extend the
Customer class with a new instance method (in this case, Load), the
consumer of Customer would use it like this...

Customer cust = new Customer();
cust.Load();

In this case the load method is used to populate the Customer class,
the extension class would also have a corresponding Save method.
(doesn't have to be Load and Save of course, it could be Sync etc)
If I have misunderstood your post then please provide a little more
to your example to explain further, otherwise I would be interested
in any furthe thoughts that you or anyone else might have.

I guess what I am saying in a nutshell, is that I also favour layering
an app along Business Object and Data Access lines, I wouldn't have
data access objects separate from my business objects, I think that is
as you asked an abstraction one to many. And now with extension
methods, you can make the layers appear to disappear, effectively
hiding another level of abstraction ;-) this makes programming against
the model very simple and intuative for consumers of the Business
Objects, and that translates to easy to maintain.

Regards Tim.


--
 
R

RichB

OK Thanks Tim I think that I get it. I'm only reallly geting to grips with
c#1, with a bit of use of the generics collections in v.2, so I haven't even
looked at v.3.

Having said that I've taken a peak this morning at some information on
extensions and now have a little understanding. However I'm not sure how you
would stucture the assemblies and references between assemblies without
having illegal circular referencing.

It is probably all my lack of understanding and I think that I am going to
stick with my original approach. However if you want to discuss further,
then please feel free to walk me through a fuller example.

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top