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
-~----------~----~----~----~------~----~------~--~---