I was actually going to bring up #2 myself in the last post but I 
forgot. I believe that in most cases Person.marry(Person other) will 
work but sometimes the implementation requires you to access information 
that spans beyond the state of a single person. Because you never know 
how the implementation might evolve over time I always prefer placing 
such methods at the Persons level. That is, any business logic involving 
a single person goes into Person while logic involving multiple parties 
goes into People. That's just a rule of thumb (feel free to violate it 
if it makes sense).

        With respect to #1 I would suggest injecting two different 
implementations of Persons for the client and server. That is, the code 
lives inside the Persons instance, but the concrete implementation would 
vary.

        Again, I am sort of making this up as I go along but it feels right so 
far.

Gili

Brian Pontarelli wrote:
> A few questions:
> 
> 1. Where is the implementation (actual code) for the /Money 
> calculateIncomeTax();  method located?/
> 
> 2. Why isn't the /marry()/ method on Person like this: /marry(Person 
> other);/?
> 
> -bp
> 
> 
> 
> On Nov 7, 2008, at 3:34 PM, Gili Tzabari wrote:
> 
>>
>>
>> I am actually toying around with a 3rd paradigm. I'm not sure whether
>> it falls under the category of anemic models, rich domain model or
>> something else. Judge for yourself:
>>
>> // Cat + business logic
>> class Person
>> {
>>   private String name;
>>
>>   String getName();
>>   Money calculateIncomeTax();
>> }
>>
>> \-> Key point: all methods operate on the current Person. Unlike anemic
>> models, you store business logic methods at this level so long as they
>> apply to a single Person (i.e. calculateIncomeTax()).
>>
>> // CatService + state
>> class People
>> {
>>   private List<Person> people;
>>
>>   void marry(Person first, Person second);
>>   List<Person> getMarriedPeople();
>> }
>>
>> You would reuse the same Person implementation on both client and
>> server while varying the implementation of People. For your cats
>> example, you'd have Cat and Cats instead of Cat and CatService.
>>
>> Gili
>>
>>
>> Brian Pontarelli wrote:
>>>> Are you talking about wanting to be able to represent a Cat with  
>>>> fix()
>>>> on the server and without fix() on the client because of business-
>>>> logic?
>>>> Or are you saying that technical limitations might cause fix() to fail
>>>> on the client? If it's the latter I argue that it's no different from
>>>> the server because even there the DB might become unreachable. If  
>>>> you're
>>>> arguing the former, then I argue you need different client-side and
>>>> server-side Cat interfaces because they are not really the same.
>>>
>>> What I'm saying is that the fix method must be different on the client  
>>> and server. This generally means a different class for the client and  
>>> server. If it was the same class on the client and server, all the  
>>> logic would need to be pull out into a well known interface and that  
>>> interface would need to be different implementations on the client and  
>>> server, making the domain just a proxy and not very rich.
>>>
>>>
>>>> I guess I am saying that you shouldn't be passing Rich Domain Objects
>>>> over the wire because (from practical experience) the server-side and
>>>> client-side interfaces are almost always "different enough" that you
>>>> can't share the interfaces. Clients usually contain a subset of the
>>>> server methods and might contain some client-only methods. I believe
>>>> Rich Domain Objects still hold a lot of value on the server-end,  
>>>> even if
>>>> you can't pass them to clients. Clients and servers can both run their
>>>> own show (with RDO) and communicate over the wire by passing a  
>>>> subset of
>>>> the state (DTO, REST, whatever you want to call it).
>>>
>>> Yeah, we agree on this. You shouldn't be passing around rich domain  
>>> objects because they don't work that way. This incurs a lot of code  
>>> overhead though.
>>>
>>>
>>>> I argue you always need to define the client-server interface by  
>>>> hand.
>>>> Serializing your state-only Object to the client is very poor  
>>>> practice.
>>>> One reason is that you're essentially exposing an interface to the
>>>> client and this needs to be designed and exposed very carefully. The
>>>> other reason is that you can't rely on having Java on both ends of  
>>>> the wire.
>>>
>>> Not sure what you mean by this. You definitely have to define how your  
>>> client talks to the server and what your server responds with, since  
>>> that is the standard remoting paradigm. In terms of serializing a  
>>> state only object as poor practice, I think you might be confused,  
>>> because that's what you said you should do above with the DTO/REST/
>>> whatever. DTOs are state objects.
>>>
>>> Again, here's a concrete example so we are on the same page:
>>>
>>> RDO
>>> -------
>>>
>>> public class ClientCat {
>>>   @Inject RemoteCatService cs;
>>>   boolean fixed;
>>>
>>>   public void fix() {
>>>     CatDTO dto = new CatDTO();
>>>     dto.fixed = this.fixed;
>>>     this.fixed = cs.fixTheCat(dto);
>>>   }
>>> }
>>>
>>> public class ServerCat {
>>>   @Inject EntityManager em;
>>>   boolean fixed;
>>>
>>>   public void fix() {
>>>     this.fixed = true;
>>>     em.persist(this);
>>>   }
>>> }
>>>
>>> public class CatDTO {
>>>   boolean fixed;
>>> }
>>>
>>> public class Client {
>>>   public void fixTheCat() {
>>>     ClientCat cat = DI.makeCat();
>>>     cat.fix();
>>>   }
>>> }
>>>
>>> // This class runs on a different server
>>> public class RemoteCatService {
>>>   public void fixTheCat(CatDTO dto) {
>>>     ServerCat cat = DI.makeCat();
>>>     cat.fixed = dto.fixed;
>>>     cat.fix();
>>>   }
>>> }
>>>
>>>
>>> Anemic
>>> ----------
>>>
>>> public class Cat {
>>>   boolean fixed;
>>> }
>>>
>>> public class Client {
>>>   @Inject RemoteCatService cs;
>>>
>>>   public void fixTheCat() {
>>>     Cat cat = new Cat();
>>>     cat = cs.fixTheCat(cat);
>>>   }
>>> }
>>>
>>> // This class runs on a different server
>>> public class RemoteCatService {
>>>   @Inject EntityManager em;
>>>
>>>   public Cat fixTheCat(Cat cat) {
>>>     cat.fixed = true;
>>>     em.persist(cat);
>>>     return cat;
>>>   }
>>> }
>>>
>>>
>>> I like the second one personally. Less code and easy to manage. Plus,  
>>> I can pass my Cat around anywhere I want without transforming it into  
>>> other objects. In n-tiered systems, you could potentially pass the Cat  
>>> all the way from the front-end to the last tier and then back up. This  
>>> is how we built most stuff at Orbitz.
>>>
>>> -bp
>>>
>>>>
>>>
>>
>>
>>
> 
> 
> > 

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/google-guice?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to