The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Object Orientation vs Service Orientation

Hi all

I'm still working on the facade I mentioned in a previous post, which will offer a single access point to a framework (http://discuss.joelonsoftware.com/default.asp?design.4.499349.14).

Now, I have a doubt about following a service or object orientation in the facade.

For instace, the low level framework handle an object called Offer, which is used to negotiate the Terms of an Agreement in a negotiation.

Currently I have this methods in the facade:

Offer createOffer(Credentials, Terms);
Offer[] publishOffer(Offer);
answerOffer(Offer, Terms);

createOffer creates an offer based on some Tems and signs it using user's Credentials. Then this Offer can be published and  the matching offers from other users are returned. Finally, the user can answer an Offer with new terms (a counter, offers, so to speak).

I'm wondering is it should be better, for instance, that the Offer class has the answer(Terms) method, instead of the facade class offering the answer(Offer, terms) method.
There are pleanty of examples like this in the facade.

The current approach is more Service Oriented and I suppose  it will meke easier to use a web services wrapper. But in the other hand, I found the second option, the object oriented one, cleaner.

What do you think guys? I know this is a rather general question, but I will be more than happy to hear your comments


Pablo
Pablo Chacin Send private email
Monday, May 28, 2007
 
 
The whole point of a facade class is to hide the complexity of the actual set of classes that provide services behind a single easy to use front end class. The facade means that users of the facade don't need to know how the service is actually provided. They don't know what set of classes lie behind the facade.

However, you are passing an Offer class across this front end. Of course it's a good thing to pass classes across interfaces, so I have no objection to that. But the Offer class is therefore not one of the things that's hidden behind the facade - the facade's clients need to know how to use Offer already. So it's part of the interface - the facade can't hide this part. Logically as a user you'd expect this object to have its own set of properties and methods - I wouldn't expect to have to use the facade all the time just to manipulate an Offer I can already see.

There's therefore no objection to having methods on Offer that do things - if it feels good, do it. (Sorry.) As long as the method relates strongly to the logical content of an Offer, it's good. But if you find yourself wanting to pass a reference to the facade to the Offer, don't - put the method on the facade instead.

Overall I'd suggest not to worry over-much about it. Put the method where you think it's right. If when you come to use your own interface it feels yucky having it there, move it. You'll soon get a feel for it.
Duncan Sharpe
Monday, May 28, 2007
 
 
What are your facade usages? Or, put differently, how would you test your facade?

Once you start writing the code using the facade (either the client code or the unit tests) the answers you need are going to become obvious. IMO, get used to driving your coding by testing (code a bit, test a bit).


PS SOA != web services.
Dino Send private email
Monday, May 28, 2007
 
 
Is your client code going to look like below?

OfferService oSvc = OfferService.getInstance();

Terms terms = createInitialTerms();
Offer offer = oSvc.createOffer(credentials, terms);

while(!termsMet(offer, terms)) {
  Offer [] matchingOffers = oSvc.publishOffer(offer);
  terms = createResponseTerms(offer, matchingOffers);
  offer = oSvc.answerOffer(offer, terms);
}
return offer;

private Terms createInitialTerms() { ... }
private Terms createResponseTerms(Offer offer, Offer [] matchingOffers) { ... }
private boolean termsMet(Offer offer, Terms terms) { ... }

If that's always the case then your service could be:

interface OfferService {
  Offer negotiateOffer(TermGenerator termGenerator);
}

or

interface OfferService {
  Offer negotiateOffer(Class<? extends TermGenerator> termGeneratorClass);
}

with

interface TermGenerator {
  Terms createInitialTerms();
  Terms createResponseTerms(Offer offer, Offer [] matchingOffers);
  boolean termsMet(Offer offer, Terms terms);
}

One more thing, don't forget to manage dependencies between services.
Dino Send private email
Monday, May 28, 2007
 
 
Dino

The initial usage of the facade will be in an java class that runs stand alone (that is, no J2EE stuff in there) as a middleware service for a distributed application. This class communicates with other clases using different native protocols.

However, later I will probably expose it as web services to open it to other client applications that don't use such native protocols.

By the way, I never said than soa == ws.

Pablo
Pablo Chacin Send private email
Tuesday, May 29, 2007
 
 
Dino

Regarding your second posting, I like the idea of the terms generator as a way to hide more stuff inside the service.

However, tthe problem with this  suggestion is that the negotiation process should be part of the application, not the service because it cab become quite complex, are diverse possible algorithms and I don't want to impose one algorithm into the service.

Therefore, my question was more about using methods of the type

offerService.answer(offer, terms)

or

offer.answer(terms)

in the context of a service oriented design. I'm quite sure the first option is more apealing for soa because the offer is passed as a parameter to the service and it will be easier to expose this method as a web service.

In the other case, I would need to expose Offer as a web service, too and keeping the state of the service (knowing which offer I reffer to in the answer method will be more complex.

Pablo



Pablo
Pablo Chacin Send private email
Tuesday, May 29, 2007
 
 
Duncan

 
I think  didn't explained me correclty. The Offer class is defined in the facade, to avoid exposing classes from the framework that is behind the facade. This issue is precisely what my previous posting was abot.

So my question now is if I shoul but the answer method in that class or leave it as a method of facade.

I do care were to put the method because if I leave it in the facade, it seams to me that will be easier to later expose it as  a web service. If I put it in the Offer object, then I will need to expose the Offer as a web service and then I will have the problem of identifying which offer I'm refering to in the web service invocation.

This is the biggest annoyance of web services: they are stateless (unless you use something like WS-RF) and therefore the object oriented programming model doesn't fit nicely to it.

Pablo
Pablo Chacin Send private email
Tuesday, May 29, 2007
 
 
Pablo,

First of all SOA != web services. There are many ways to do SOA, including the case where the app is not distributed (so no need for web services; you can still design your interfaces around services rather than object interactions).

Secondly, making everything a web service is an anti-pattern: fine grained distributed objects. You can end up in this anti-pattern with any distributed technology, not limited to web services: CORBA, DCOM, EJBs, etc.

Finally, there's no need to make the Offer a service. It seems to me that the Offer is more of a DTO than a service. DTO stands for data transfer object.

Anyway, if you're building an app which uses LANs or WANs, you must read and understand "enterprise" design patterns (they all revolve around how to handle network access correctly). If you don't apply these patterns correctly most likely your app will lack performance.
Dino Send private email
Tuesday, May 29, 2007
 
 
Dino

First a couple of clarifications:

I never said, neither implied, than soa == ws. I think you missed this comment from a previous posting.  In any case, would you agree that I could use ws to implement soa? I mean, soa doesn't preclude ws, does it?

Also, I don't undedstand why you suppose that I haven't read or I don't undertand enterprise patterns ("you must read and understand "enterprise" design patterns"). I have been doing so since 1998 and I think I understand them quite well.

Now, going into matter, I also know and understand that "fine grained object antipattern" you mention. What you don't mention is that sometimes is tricky to define when an object is too fine grained. For instance, what if I end up with 10 operations that receive an offer as an argument (to inspect it, to cancel it, to see its history), will it still be too fine grained? I will be interested in some guidelines to identify this situation.

Also I think it worth to mention that even when soa != ws, web services has greatly (and badly) influenced many ideas regarding service orientation. One of the biggest influences is the statelessness (that is the lack of state) of web services, which is one of the main reasons many web services receive an object as argument (like in my example answer(Offer, Terms). This situation has change recently with the introduction (and growing acceptance) of WS-RF and WS-Transfer standards that allow statefull web services calls, something similar to distributed objects.

Now that you mention antipatterns, there is one I've been very interested in lately, I call it "dumb object", that is one object that has no responsability but to store data. You will agree that an object should have not only the data but also the resposability to act on this data.

From your response, I think that maybe one side effect of soa design is that it will lead to "dump objects", as now service's operations will act on DTOs (which are dumb).

My original posting was about object orientation vs service orientation and it seams from the responses that i wasn't copletely misleaded on the identification of the main "tensions" between them:
- fine grained vs coarse grained apporach
- Dumb objects vs self-sufficient objects

Are you aware of any other "tension"

Thanks to all for you comments


In any case, thanks for you comments

Pablo
Pablo Chacin Send private email
Wednesday, May 30, 2007
 
 
Pablo,

Sorry if I was mistakenly blunt - I tend to be B&W lately, which is not necessarily right.

Anyway, I keep throwing the SOA != ws because, based on how many times you mention ws, you design your interfaces and architecture with ws in mind, which is not quite right.

Then I mentioned enterprise patterns because - IMO - you don't use the accepted names (DTO, value objects, business delegate, etc); hence I easily conclude you don't know about them.

Also, if you make everything a ws you'll end-up in the "fine grained ..." anti-pattern. I'm already trying to fix a large server which was designed that way and I know - for a fact - that the performance totally sucks, the HW / licenses costs are huge for no reason and the whole damn thing cannot be easily re-factored.

About "dumb objects" anti-pattern (that would be I believe the "detached object" anti-pattern?), if you're using the facade correctly, you should not end up in this situation simply because the service model != object model. Services do not look the same nor do they behave the same as persistent object models or such.

Anyway, the work around for the "dumb object" / "detached object" is using the memento pattern (GoF) and layering your app as:

BO layer -> (Transfer/Memento Objects) -> DAO Layer

Cheers,
Dino
Dino Send private email
Wednesday, May 30, 2007
 
 
Hi Dino

Thanks for the clarifications.

Regarding the Dumb object, I don't beleive it is equivalent to a Detached Object (which by the way is not an anti-pattern , but a pattern).

Nothing, to my knowledge, says that the detached object has no other responsability than carrying data. It might perform local (or even remote) actions in the client side.

Finally, I tink that the Memento pattern could be a good option to consider because it will also help me to address the other problem I have: exposing framework implementation classes from in the facade. If I use memento objects (in my example, the memento of the order), then I don't care which concrete class this memento is related to!

I'll take a closer look at this.

thanks

Pablo
Pablo Chacin Send private email
Wednesday, May 30, 2007
 
 
Well Detached Object is both pattern / anti-pattern ... depending on how coarse they are and how often they change.

If they don't change much, great! But if they change a lot you may end up in a hard to solve contention problem (large portions of the object graph changing concurrently with an increased probability of collision).
Dino Send private email
Wednesday, May 30, 2007
 
 
I wasnt aware that OO was even comparable with SOA. 


OO is a metaphor for data and its behaviour.  I've always understood SOA to be based on RPC and distributed services.
AndyW Send private email
Saturday, June 02, 2007
 
 
"SOA is the practice of sequestering the core business functions into independent services that don’t change frequently. These services are glorified functions that are called by one or more presentation programs." - Uncle Bob (Robert Martin)

http://blog.objectmentor.com/articles/2007/04/11/what-is-soa-really
Dino Send private email
Monday, June 04, 2007
 
 
Dino, Andy

A common misunderstanding about SOA is to beleive that a service is just a remote function. It is not. Services are more related to components than to RPC.

Even when SOA != WS, WS is a SOA architecture (I agree, it is not the only one, but it is ONE of the many possible ways to implement it) Once said that, take a look at this definition of what a web service is:
http://www.w3.org/TR/ws-arch/#whatis

Other SOA models like OGSA (http://en.wikipedia.org/wiki/OGSA) follows this same idea.

Unfortunatelly, I don't have on hand other references that stress this concept that Service != function. I could find them if anyone is interested.

Pablo
Pablo Chacin Send private email
Wednesday, June 06, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz