Could TDD help to avoid "Anemic Domain Model "?

View: New views
13 Messages — Rating Filter:   Alert me  

Could TDD help to avoid "Anemic Domain Model "?

by ablmf :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Recently, when I think about some project I invovled, I realized they
have a "bad smell" I never figured out how to avoid.  So I made a little
study and I found that all of them have a model that Martin Fowler
called "Anemic Domain Model <AnemicDomainModel>  ".

I think TDD is good to help find out a solution for some low level
design problem, like these examples in books, but could it also help on
high level design?   Especailly, I want to know, if it could help to
find out something better than Anemic Domain Model?

Actually, I tried some TDD in my last project, but it is also "anemic".
Although I don't feel very weel with the design, but it came in to my
mind naturally when I wrote my first test case.



[Non-text portions of this message have been removed]


Re: Could TDD help to avoid "Anemic Domain Model "?

by Carlo Bottiglieri :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,
in my own experience tdd is not enough to "force" you to write
meaningful objects instead of a bunch of data-holders used by a bunch
of procedures. Unfortunately I've been able to write hundreds of
perfectly procedural lines of code in tdd, all that it takes is
refactoring in the wrong direction.

Carlo

On Wed, Sep 2, 2009 at 3:20 PM, ablmf<ablmf@...> wrote:

> Recently, when I think about some project I invovled, I realized they
> have a "bad smell" I never figured out how to avoid.  So I made a little
> study and I found that all of them have a model that Martin Fowler
> called "Anemic Domain Model <AnemicDomainModel>  ".
>
> I think TDD is good to help find out a solution for some low level
> design problem, like these examples in books, but could it also help on
> high level design?   Especailly, I want to know, if it could help to
> find out something better than Anemic Domain Model?
>
> Actually, I tried some TDD in my last project, but it is also "anemic".
> Although I don't feel very weel with the design, but it came in to my
> mind naturally when I wrote my first test case.
>
>
>
> [Non-text portions of this message have been removed]
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
>

Re: Could TDD help to avoid "Anemic Domain Model "?

by Steven Gordon-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Yes, TDD is just a better way for developers to write code that does
what the developers believe the software should do.  It does not have
any direct effect on what the developers believe the software should
do.

ATDD (acceptance test driven development - acceptance tests are
negotiated with the customer before writing code to make those tests
pass) could help align what the developers believe the software should
do with what the customers believe the software should do.  Even then,
iteratively aligning those beliefs may be insufficient to iteratively
develop an adequate domain model without:
- people asking each other the right questions, and
- obtaining feedback from real users on delivered slices of working
software as quickly as possible.

SteveG

On Wed, Sep 2, 2009 at 7:48 AM, Carlo
Bottiglieri<carlo.bottiglieri@...> wrote:

>
>
> Hello,
> in my own experience tdd is not enough to "force" you to write
> meaningful objects instead of a bunch of data-holders used by a bunch
> of procedures. Unfortunately I've been able to write hundreds of
> perfectly procedural lines of code in tdd, all that it takes is
> refactoring in the wrong direction.
>
> Carlo
>

Re: Could TDD help to avoid "Anemic Domain Model "?

by Carfield Yim-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

For me "Anemic Domain Model " usually introduce Service objects to
hold the business logic / validation, and usually code in that style
is harder to have unit test. I will consider that is helping us to
avoid "Anemic Domain Model ", although, like Carlo mentioned, there is
still see a lot of code TDD code is a bunch of data-holders used by a
bunch of procedures.

On Wed, Sep 2, 2009 at 9:20 PM, ablmf<ablmf@...> wrote:

> Recently, when I think about some project I invovled, I realized they
> have a "bad smell" I never figured out how to avoid.  So I made a little
> study and I found that all of them have a model that Martin Fowler
> called "Anemic Domain Model <AnemicDomainModel>  ".
>
> I think TDD is good to help find out a solution for some low level
> design problem, like these examples in books, but could it also help on
> high level design?   Especailly, I want to know, if it could help to
> find out something better than Anemic Domain Model?
>
> Actually, I tried some TDD in my last project, but it is also "anemic".
> Although I don't feel very weel with the design, but it came in to my
> mind naturally when I wrote my first test case.
>
>
>
> [Non-text portions of this message have been removed]
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
>

RE: Could TDD help to avoid "Anemic Domain Model "?

by Donaldson, John (GEO) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ablmf,

The old techniques can help here: go through customer supplied documents and descriptions, and build a concept model of the domain. Then try to align your TDD discovered objects with that. It's a craft, not a science though.

John D.

-----Original Message-----
From: testdrivendevelopment@... [mailto:testdrivendevelopment@...] On Behalf Of ablmf
Sent: 02 September 2009 15:21
To: testdrivendevelopment@...
Subject: [TDD] Could TDD help to avoid "Anemic Domain Model "?

Recently, when I think about some project I invovled, I realized they
have a "bad smell" I never figured out how to avoid.  So I made a little
study and I found that all of them have a model that Martin Fowler
called "Anemic Domain Model <AnemicDomainModel>  ".

I think TDD is good to help find out a solution for some low level
design problem, like these examples in books, but could it also help on
high level design?   Especailly, I want to know, if it could help to
find out something better than Anemic Domain Model?

Actually, I tried some TDD in my last project, but it is also "anemic".
Although I don't feel very weel with the design, but it came in to my
mind naturally when I wrote my first test case.



[Non-text portions of this message have been removed]



------------------------------------

Yahoo! Groups Links




Re: Could TDD help to avoid "Anemic Domain Model "?

by George Dinwiddie :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

ablmf wrote:
> Recently, when I think about some project I invovled, I realized they
> have a "bad smell" I never figured out how to avoid.  So I made a little
> study and I found that all of them have a model that Martin Fowler
> called "Anemic Domain Model <AnemicDomainModel>  ".
>
> I think TDD is good to help find out a solution for some low level
> design problem, like these examples in books, but could it also help on
> high level design?   Especailly, I want to know, if it could help to
> find out something better than Anemic Domain Model?

It helps me, because I generally do most of my unit testing against the
domain model, and am quick to factor out collaborators in accordance
with the Single Responsibility Principle.  TDD won't force a robust
domain model, but does give you good tools for building one.

  - George

--
  ----------------------------------------------------------------------
   * George Dinwiddie *                      http://blog.gdinwiddie.com
   Software Development                    http://www.idiacomputing.com
   Consultant and Coach                    http://www.agilemaryland.org
  ----------------------------------------------------------------------


Re: Could TDD help to avoid "Anemic Domain Model "?

by Adam Sroka-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

It depends on what "simple" means... no, really.

The folks who invented TDD were mostly smalltalkers. They come from a
world where simple design means object-oriented code without a lot of
duplication. "Anemic Domain Model" is an example of something that is
not terribly object-oriented, so it doesn't meet the definition of
"simple" that most of these guys are talking about. On the other hand,
a C programmer might not have any problem with pure data structures
and collections of procedures that operate on those structures since
that is the paradigm that they generally use.

TDD won't force you to use a particular paradigm. You can TDD
object-oriented code, or procedural code, or functional code, etc.
Most of the literature on refactoring focuses on OO code, so you may
find it harder to learn how to refactor other paradigms (There has
been some work on collecting refactorings for functional code, and
some of the patterns do transfer, but nonetheless...) The real
question is, what paradigm do you intend to use? And, can you get your
team to agree on a definition of "simple" that works for you?

On Wed, Sep 2, 2009 at 6:20 AM, ablmf<ablmf@...> wrote:

>
>
> Recently, when I think about some project I invovled, I realized they
> have a "bad smell" I never figured out how to avoid. So I made a little
> study and I found that all of them have a model that Martin Fowler
> called "Anemic Domain Model <AnemicDomainModel> ".
>
> I think TDD is good to help find out a solution for some low level
> design problem, like these examples in books, but could it also help on
> high level design? Especailly, I want to know, if it could help to
> find out something better than Anemic Domain Model?
>
> Actually, I tried some TDD in my last project, but it is also "anemic".
> Although I don't feel very weel with the design, but it came in to my
> mind naturally when I wrote my first test case.
>
> [Non-text portions of this message have been removed]
>
>

Re: Could TDD help to avoid "Anemic Domain Model "?

by Lance Walton :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

There is no technique of which I'm aware that can prevent such things. In fact I've heard 'it's easier to test' being used in support of separation of data and behaviour. Actually, I've heard that phrase used in support of myriad troublesome practices. It's like a throat clearing utterance used by those that feel the need to say something when there is nothing left to say.

Two ways to help produce an rich domain model are:

1) Realize that a domain model is largely defined by it's behavior not it's data, in the sense that we hide primitive forms of data in a higher level semantic unit (a class), and the reason that it is a higher level semantic unit is that it exports nothing more than a coherent set of operations. The abstracting power of the model comes precisely from hiding one level of abstraction behind higher level abstraction barriers. To then tear down that barrier in the anaemic way that we see so often renders all of this kind of pointless.

2)  Always ask 'what do I have in scope that I can sensibly delegate some work to?' If you need to pass something to that delegate in order for it to do it's work, congratulations; you have just done some dependency injection (make sure you update your CV). Just make sure that the type of the injected thing expected by the delegate represents an appropriate (lower) level of abstraction than the delegate's type.

If someone argues that, for example, 'in a real world library, books don't lend themselves' then remind them that OO is not a simulation of the real world, but one of many possible modelling perspectives, and it is one that favours encapsulation, which is 'a commitment not just to abstraction of state, but to eliminate state oriented metaphors from programming' (Alan Kay).

Also... practice. A lot. For years. :-)

Finally, though, a question for you: what is the difference between this 'low level design' and 'high level design' of which you speak?

Regards,

Lance

--- In testdrivendevelopment@..., "ablmf" <ablmf@...> wrote:

>
> Recently, when I think about some project I invovled, I realized they
> have a "bad smell" I never figured out how to avoid.  So I made a little
> study and I found that all of them have a model that Martin Fowler
> called "Anemic Domain Model <AnemicDomainModel>  ".
>
> I think TDD is good to help find out a solution for some low level
> design problem, like these examples in books, but could it also help on
> high level design?   Especailly, I want to know, if it could help to
> find out something better than Anemic Domain Model?
>
> Actually, I tried some TDD in my last project, but it is also "anemic".
> Although I don't feel very weel with the design, but it came in to my
> mind naturally when I wrote my first test case.
>
>
>
> [Non-text portions of this message have been removed]
>



Re: Could TDD help to avoid "Anemic Domain Model "?

by ablmf :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks for this thoughtful and interesting reply.

I've heard and tried these 2 ways in some of my project looks like the multi-currency money example in "Test-Driven Development by example".  I think for this kind of problem contains some complex logic and procedure, abstraction and delegation works very well.

But for some problems which are less complex but more tedious, I feel harder to apply these principles.

For example:

#=========================================
class Shop:
   
    def addBook(name, author):
       
        #Check name and author is OK

        book = Book(name, author)

        # Save book to DB

    def delBook(book_id):
        pass

    def findBookByName(name):
        pass

    def findBookByAuthor(name):
        pass

    def updateBook(book):
        pass


    def addFood(name, author):
        pass

    def delFood(book_id):
        pass

    def findFoodByName(name):
        pass

    def findFoodByAuthor(name):
        pass

    def updateFood(book):
        pass


class Book:
    def __init__(name, author):
        self.name = name
        self.author = author

class Food:
    pass

class Drink:
    pass
#=========================================

This is simplification, but shows the problem.  Shop is only a set of procedure functions, Book/Food/Drink only contains data.

Seems there is nothing to encapsulate and delegate, only problem is Shop will become very large.


I know this could be not that easy to explain in this group, so can you recommend some books on this topic?

--- In testdrivendevelopment@..., "extremeprogrammer" <LanceWalton@...> wrote:

>
> There is no technique of which I'm aware that can prevent such things. In fact I've heard 'it's easier to test' being used in support of separation of data and behaviour. Actually, I've heard that phrase used in support of myriad troublesome practices. It's like a throat clearing utterance used by those that feel the need to say something when there is nothing left to say.
>
> Two ways to help produce an rich domain model are:
>
> 1) Realize that a domain model is largely defined by it's behavior not it's data, in the sense that we hide primitive forms of data in a higher level semantic unit (a class), and the reason that it is a higher level semantic unit is that it exports nothing more than a coherent set of operations. The abstracting power of the model comes precisely from hiding one level of abstraction behind higher level abstraction barriers. To then tear down that barrier in the anaemic way that we see so often renders all of this kind of pointless.
>
> 2)  Always ask 'what do I have in scope that I can sensibly delegate some work to?' If you need to pass something to that delegate in order for it to do it's work, congratulations; you have just done some dependency injection (make sure you update your CV). Just make sure that the type of the injected thing expected by the delegate represents an appropriate (lower) level of abstraction than the delegate's type.
>
> If someone argues that, for example, 'in a real world library, books don't lend themselves' then remind them that OO is not a simulation of the real world, but one of many possible modelling perspectives, and it is one that favours encapsulation, which is 'a commitment not just to abstraction of state, but to eliminate state oriented metaphors from programming' (Alan Kay).
>
> Also... practice. A lot. For years. :-)
>
> Finally, though, a question for you: what is the difference between this 'low level design' and 'high level design' of which you speak?
>
> Regards,
>
> Lance
>
> --- In testdrivendevelopment@..., "ablmf" <ablmf@> wrote:
> >
> > Recently, when I think about some project I invovled, I realized they
> > have a "bad smell" I never figured out how to avoid.  So I made a little
> > study and I found that all of them have a model that Martin Fowler
> > called "Anemic Domain Model <AnemicDomainModel>  ".
> >
> > I think TDD is good to help find out a solution for some low level
> > design problem, like these examples in books, but could it also help on
> > high level design?   Especailly, I want to know, if it could help to
> > find out something better than Anemic Domain Model?
> >
> > Actually, I tried some TDD in my last project, but it is also "anemic".
> > Although I don't feel very weel with the design, but it came in to my
> > mind naturally when I wrote my first test case.
> >
> >
> >
> > [Non-text portions of this message have been removed]
> >
>



Re: Could TDD help to avoid "Anemic Domain Model "?

by Scott Ambler :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

One way to improve the quality of your work is to actually do a bit of modeling before coding.  Contrary to some of the dogma you may have heard, modeling is a common part of agile development efforts.  At http://www.agilemodeling.com/essays/amdd.htm you can see how modeling and TDD go hand in hand.  You can also read about it in Dave Astels TDD book if you happen to have a copy.

- Scott

--- In testdrivendevelopment@..., "ablmf" <ablmf@...> wrote:

>
> Recently, when I think about some project I invovled, I realized they
> have a "bad smell" I never figured out how to avoid.  So I made a little
> study and I found that all of them have a model that Martin Fowler
> called "Anemic Domain Model <AnemicDomainModel>  ".
>
> I think TDD is good to help find out a solution for some low level
> design problem, like these examples in books, but could it also help on
> high level design?   Especailly, I want to know, if it could help to
> find out something better than Anemic Domain Model?
>
> Actually, I tried some TDD in my last project, but it is also "anemic".
> Although I don't feel very weel with the design, but it came in to my
> mind naturally when I wrote my first test case.
>
>
>
> [Non-text portions of this message have been removed]
>



Re: Could TDD help to avoid "Anemic Domain Model "?

by Alan Baljeu :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Seconded.  And trimmed to emphasize the important points.

 Alan Baljeu




________________________________
From: Adam Sroka <adam.sroka@...>

   
It depends on what "simple" means... no, really.

...Anemic Domain Model" is an example of something that is
not terribly object-oriented, so it doesn't meet the definition of
"simple" that most of these guys are talking about. On the other hand,
a C programmer might not have any problem with pure data structures
and collections of procedures that operate on those structures since
that is the paradigm that they generally use.

...The real
question is, what paradigm do you intend to use? And, can you get your
team to agree on a definition of "simple" that works for you?


.

   


      __________________________________________________________________
Get a sneak peak at messages with a handy reading pane with All new Yahoo! Mail: http://ca.promos.yahoo.com/newmail/overview2/

[Non-text portions of this message have been removed]


Re: Could TDD help to avoid "Anemic Domain Model "?

by franz see :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I strongly agree with what Carlo Bottiglieri and Adam Sroka have mentioned.

It depends on the direction of your refactoring - are you going the OOP way
or the procedural way? If it's the former, then good news - there are a lot
of resources for that. If not, then you might find it hard to find much
resource on that :-)

Cheers,

--
Franz Allan Valencia See | Java Software Engineer
franz.see@...
LinkedIn: http://www.linkedin.com/in/franzsee

On Fri, Sep 4, 2009 at 3:40 AM, Alan Baljeu <alanbaljeu@...> wrote:

>
>
> Seconded. And trimmed to emphasize the important points.
>
> Alan Baljeu
>
> ________________________________
> From: Adam Sroka <adam.sroka@... <adam.sroka%40gmail.com>>
>
>
> It depends on what "simple" means... no, really.
>
> ...Anemic Domain Model" is an example of something that is
> not terribly object-oriented, so it doesn't meet the definition of
> "simple" that most of these guys are talking about. On the other hand,
> a C programmer might not have any problem with pure data structures
> and collections of procedures that operate on those structures since
> that is the paradigm that they generally use.
>
> ...The real
> question is, what paradigm do you intend to use? And, can you get your
> team to agree on a definition of "simple" that works for you?
>
> .
>
> __________________________________________________________
> Get a sneak peak at messages with a handy reading pane with All new Yahoo!
> Mail: http://ca.promos.yahoo.com/newmail/overview2/
>
> [Non-text portions of this message have been removed]
>
>  
>


[Non-text portions of this message have been removed]


Re: Re: Could TDD help to avoid "Anemic Domain Model "?

by Adam Sroka-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Sep 2, 2009 at 11:19 PM, ablmf<ablmf@...> wrote:
>
>
> Thanks for this thoughtful and interesting reply.
>
> I've heard and tried these 2 ways in some of my project looks like the
> multi-currency money example in "Test-Driven Development by example". I
> think for this kind of problem contains some complex logic and procedure,
> abstraction and delegation works very well.
>


Just to add on and/or drive home what Lance said, good OO designs are
about what the things do rather than the nature of what the things
are. That is the reason for BDD, to make this more explicitly a part
of how we write tests so that we drive in that direction. i.e. if we
are talking about what X "should do" then we are talking about
behavior. If we are talking about what X should have then we are
explicitly starting by playing with X's private bits and there's a
good chance that won't lead to an OO solution.

> But for some problems which are less complex but more tedious, I feel harder
> to apply these principles.
>

Regarding the below: CRUD systems are inherently procedural in nature.
If you frame the problem in terms of a procedural solution then guess
what you will end up with? In other words, when we say:

"I will need to have a foo and a bar. Foo will have this data, and bar
will have that data. I will need to put foos and bars into the
database, and find them in the database, and delete them in the
database..." We are already framing the problem in terms of a
procedural solution to that problem. Is there another way to express
the problem? Perhaps one that focuses on what foos and bars really
are. Why are they here? What is it we want them to do? Perhaps if we
start there rather than starting with the fact that they will have to
be stored somewhere (Hopefully, one of the least interesting things
about them) we will arrive at a solution that feels less anemic.


> For example:
>
> #=========================================
> class Shop:
>
> def addBook(name, author):
>
> #Check name and author is OK
>
> book = Book(name, author)
>
> # Save book to DB
>
> def delBook(book_id):
> pass
>
> def findBookByName(name):
> pass
>
> def findBookByAuthor(name):
> pass
>
> def updateBook(book):
> pass
>
> def addFood(name, author):
> pass
>
> def delFood(book_id):
> pass
>
> def findFoodByName(name):
> pass
>
> def findFoodByAuthor(name):
> pass
>
> def updateFood(book):
> pass
>
> class Book:
> def __init__(name, author):
> self.name = name
> self.author = author
>
> class Food:
> pass
>
> class Drink:
> pass
> #=========================================
>
> This is simplification, but shows the problem. Shop is only a set of
> procedure functions, Book/Food/Drink only contains data.
>
> Seems there is nothing to encapsulate and delegate, only problem is Shop
> will become very large.
>
> I know this could be not that easy to explain in this group, so can you
> recommend some books on this topic?
>
> --- In testdrivendevelopment@..., "extremeprogrammer"
> <LanceWalton@...> wrote:
>>
>> There is no technique of which I'm aware that can prevent such things. In
>> fact I've heard 'it's easier to test' being used in support of separation of
>> data and behaviour. Actually, I've heard that phrase used in support of
>> myriad troublesome practices. It's like a throat clearing utterance used by
>> those that feel the need to say something when there is nothing left to say.
>>
>> Two ways to help produce an rich domain model are:
>>
>> 1) Realize that a domain model is largely defined by it's behavior not
>> it's data, in the sense that we hide primitive forms of data in a higher
>> level semantic unit (a class), and the reason that it is a higher level
>> semantic unit is that it exports nothing more than a coherent set of
>> operations. The abstracting power of the model comes precisely from hiding
>> one level of abstraction behind higher level abstraction barriers. To then
>> tear down that barrier in the anaemic way that we see so often renders all
>> of this kind of pointless.
>>
>> 2) Always ask 'what do I have in scope that I can sensibly delegate some
>> work to?' If you need to pass something to that delegate in order for it to
>> do it's work, congratulations; you have just done some dependency injection
>> (make sure you update your CV). Just make sure that the type of the injected
>> thing expected by the delegate represents an appropriate (lower) level of
>> abstraction than the delegate's type.
>>
>> If someone argues that, for example, 'in a real world library, books don't
>> lend themselves' then remind them that OO is not a simulation of the real
>> world, but one of many possible modelling perspectives, and it is one that
>> favours encapsulation, which is 'a commitment not just to abstraction of
>> state, but to eliminate state oriented metaphors from programming' (Alan
>> Kay).
>>
>> Also... practice. A lot. For years. :-)
>>
>> Finally, though, a question for you: what is the difference between this
>> 'low level design' and 'high level design' of which you speak?
>>
>> Regards,
>>
>> Lance
>>
>> --- In testdrivendevelopment@..., "ablmf" <ablmf@> wrote:
>> >
>> > Recently, when I think about some project I invovled, I realized they
>> > have a "bad smell" I never figured out how to avoid. So I made a little
>> > study and I found that all of them have a model that Martin Fowler
>> > called "Anemic Domain Model <AnemicDomainModel> ".
>> >
>> > I think TDD is good to help find out a solution for some low level
>> > design problem, like these examples in books, but could it also help on
>> > high level design? Especailly, I want to know, if it could help to
>> > find out something better than Anemic Domain Model?
>> >
>> > Actually, I tried some TDD in my last project, but it is also "anemic".
>> > Although I don't feel very weel with the design, but it came in to my
>> > mind naturally when I wrote my first test case.
>> >
>> >
>> >
>> > [Non-text portions of this message have been removed]
>> >
>>
>
>