aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Business Service Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Business Service" Watch "Business Service" New topic
Author

Business Service

Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

I was taking a read over this thread on RMI interfaces and I am wondering if I am missing something obvious here.

My thinking on the set up of my business service is that I want to be able to do this in my code:
Now, if I do this, then I have to be able to access the method that starts the server through the BusinessService interface e.g.
But this doesn't make any sense in the context of the LocalServiceImpl class where there is no server to start.

Am I missing something here?


SCJP (1.4 | 5.0), OCJP (6.0), OCMJD
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5539
    
  13

My business service does not have a startServer method, just the 2 business service methods that are required (find and book). I would not consider starting the RMI-server as a business service method. It's not something a CSR (or any other user) needs to do in order to use the application, but finding and booking rooms are. Therefore just these 2 methods in my business service.


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

That makes sense. But I am confused by the example in that thread that has a startServer method in it.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5539
    
  13

Sean Keane wrote:But I am confused by the example in that thread that has a startServer method in it.

Only the Server interface has a startServer-method in it, the BusinessModel interface has not.
Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

Ah, dead right! I missed that, thanks.
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2267
    
    3

Just one consideration, I always say that "ifs" might be from hell... I always think a lot about it. For now, the conclusion that I got to is that if an "if" is being used to control the data flow, then it's fine... but if it is being used to control object-orientation, then it is wrong. Sean, in your case, where are you using the code snippet you provided? Is it when the application starts or, say, in your main window?


Cheers, Bob "John Lennon" Perillo
SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

This is probably part of my problem - I haven't coded my client yet so I don't really know what I am talking about (haven't used Swing in years, I think I am subconsciouslly avoiding the client!!!).

I have just finished my db layer and my service layer. I created a simple GUI to work off the local implementation of my business service just to see that it all worked. Now I am moving on to the networking code. Then I will move on to my client GUI.

I haven't figured it out yet, but I'm guessing I will have something like this in the controller of my MVC
Then have
Sound OK?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5539
    
  13

I have something similar, so that would be fine
Sean Keane
Ranch Hand

Joined: Nov 03, 2010
Posts: 581

Cheers! With the lightening speed that Ixus has finished his assignment I think I need to spend less time investigating and just get it implemented . Although it is fun investigating and researching various approaches . I think I actually learned more from discussions on here and various investigations than I have from simply implementing it!
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2267
    
    3

Sean Keane wrote:Sound OK?


Well champ, I didn't have an explicit controller class... in my case, this role was played by ActionListeners. Here's how I would do if it was today:



This way, there wouldn't be an "if" deciding which class would have to be instantiated... the dialog displayed when the application starts in standalone mode would instantiate a local implementation for the business services class. The same thing for client mode: it would get it from the server's Registry and give it to the main window.
Ixus See
Ranch Hand

Joined: Jul 17, 2011
Posts: 160
you guys are making me worried again

I use a factory to create the connection for remote and local connection and assign it to IRoomService roomService. I will have a method to get the roomService, so there is no need to do IF-ELSE.

When the model gets the service, it will get the service that was initialized.

getDBManager returns IROOMSERVICE.
Ixus See
Ranch Hand

Joined: Jul 17, 2011
Posts: 160

is there anything wrong with my implementation.. what kind of pattern should I call it? I accidentally stumble on it while coding =x
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5539
    
  13

Ixus See wrote:you guys are making me worried again

I don't even have a IF ELSE.

That's what they call "software development": 1 problem, different solutions. So it's completely normal that your solution differs from what's discussed here. My solution was also different from the one Roberto has provided, but that does not mean it's wrong.
Ixus See
Ranch Hand

Joined: Jul 17, 2011
Posts: 160
well to me there is a norm way of coding.. basically follow standard, don't deviate from it.

A lot of developers like to code in their own manner and call it software development, different approach and whatever screw up reason they give.

I believe most problem should be coded the same way, and should not deviate from standard and design pattern. That is why I always make extra effort to find out the correct way of coding it even I already have the solution.
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
In my UrlyBird application GUI-clients comunicate with Data-level via Business-level.
The structure of Business-level is :
1) public interface Operations (suncertify.network.Operations) - extends Remote and is the server-interface in network-communications;
2) (non-public (package accessibility)) class BusinessOperations (suncertify.business.BusinessOperations) - contains 2 methods : the first implements find-logic, the second - book-logic;
3) public class BusinessOperationsLocal (suncertify.business.BusinessOperationsLocal) extends BusinessOperations (see "2)") - contains 2 methods that have only calls to corresponding methods of BusinessOperations-class (see "2)") and nothing else;
4) public class BusinessOperationsRemote (suncertify.business.BusinessOperationsRemote) extends BusinessOperations (see "2)") and implements Operations (see "1)") - contains 2 methods that have only calls to corresponding methods of BusinessOperations-class (see "2)") and nothing else;

can it be considered a good design ?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5539
    
  13

Dmitri Cherkas wrote:can it be considered a good design ?

I have to give this design but maybe I'm missing something in your design.

I'm missing a general business operations interface which is implemented by the local and remote class. Because now the method in your local business operations implementation is "bookRoom" (which calls BusinessOperations.book method) and the remote business operations implementation method could be called "makeRoomBooking" (which also calls BusinessOperations.book method). That's not something you want, because you want your GUI(Controller) to be unaware of the mode the application is running in.

Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
You are right - i'm not very satisfied with my design...
If i understand well, you propose the following architecture :

1) public interface Operations extends Remote ;
2) (package accessibility) class BusinessOperations - contains implementation logic;
3) public class BusinessOperationsLocal extends BusinessOperations implements SuperBusiness (uses implementation of class BusinessOperations);
4) public class BusinessOperationsRemote extends BusinessOperations implements Operations, SuperBusiness (uses implementation of class BusinessOperations).

The problem is that in your GUI you will still have something like this :


Therefore SuperBusiness is not used outside package "business" and only to have the same methods name in BusinessOperationsLocal and BusinessOperationsRemote ?
Or may be i miss something ?... For sure i'm missing something...
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5539
    
  13

That's not what you want at all in your gui (or controller).

You would expect you retrieve once the correct business service implementation based on the mode you are running. That happens for example in the constructor or in some initialize method. Then when you need to find rooms, just call service.findRooms(), when you want to book a room, that's service.book(). And that's where the SuperBusiness interface gives you advantage and doesn't clutter your code: the call in standalone mode and network mode will be exactly the same, the object on which you invoke the call will be different (but your gui will not know that)

And you might have a look at the rmi tutorial and this thread, because RMI expects some must-dos or otherwise it won't work (and you are violating some of them)
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Roel wrote : You would expect you retrieve once the correct business service implementation based on the mode you are running. That happens for example in the constructor or in some initialize method. Then when you need to find rooms, just call service.findRooms(), when you want to book a room, that's service.book(). And that's where the SuperBusiness interface gives you advantage and doesn't clutter your code: the call in standalone mode and network mode will be exactly the same, the object on which you invoke the call will be different (but your gui will not know that)

I comletely agree with you, Roel - the solution you write here clear, good and OO, but i still do not understand how to realize it... Or may be you try to say me : your SuperBusiness interface in effect is your Operations interface and BusinessOperationsLocal with BusinessOperationsRemote must implement Operations interface, but methods in BusinessOperationsLocal must not declare RemoteException ?

Roel wrote : And you might have a look at the rmi tutorial and this thread, because RMI expects some must-dos or otherwise it won't work (and you are violating some of them)

This phrase freeze my soul... The problem is I already finished application some days ago (now i only review the program, design and write docs) and networking works without problem (at least seems to work) on my computer and in my office network... But better late than never retrieve errors... what my networking approach violates ?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5539
    
  13

Dmitri Cherkas wrote:This phrase freeze my soul...

That was not my intention. Relax, don't panic If your application is working on the office network, I'm just wrong. I thought you needed a remote interface, but that seems not to be true (it's a long time since I used RMI)

Dmitri Cherkas wrote:I comletely agree with you, Roel - the solution you write here clear, good and OO, but i still do not understand how to realize it...

It's not that hard.

You have an interface with your business operations, let's call it BusinessService containing all business methods you want to invoke. This is the interface you will use in your GUI to call methods on. You have to create a special remote interface (RemoteBusinessService) which extends Remote and BusinessService (no other methods needed).
Then you can create an implementation for RemoteBusinessService and you could use that one for standalone mode as well. Or you can use the classes you already have: BusinessOperationsLocal implements BusinessService and BusinessOperationsRemote implements RemoteBusinessService (you can get rid of the Operations interface, it's unneeded).

Final step is changing your GUI. You have an instance member of type BusinessService in your MainWindow class which you initialize once with the appropriate business service (based on the application mode), something like this:

And when the user hits the search-button, you can simply do service.findRooms(room);. And if you want to take it one step further you can create a "service locator" class which takes care of retrieving the service implementations (so you meet the following design principle: each class should have one specific purpose)
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Yes, Roel, your suggestion is a good solution... My problem was : i thought that the following scheme is a indispensable scheme in implementing RMI server :
1) must be interface AA that extends Remote (is present in your solution);
2) interface AA must declare methods of implementing class and every declared method must have "throws RemoteException" in signature (is not present in your solution).

In you solution when gui-client calls "servise.findRooms(room);" you do not wrap the call in try-catch block, right ? Interesting...

Moreover... in your solution there are only :
1) interface BusinessService;
2) interface RemoteBusinessService extends BusinessService, Remote;
3) class BusinessOperations implements RemoteBusinessService.

and BusinessOperations class can be used as remote server and class in standalone mode, is it ?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5539
    
  13

in your interface every method will indeed have a "throws RemoteException" (besides any business exceptions). Otherwise you can't use the interface with RMI. How can you know it's not present in my solution if I didn't provide any method signature

You can use the BusinessOperations for both the local and networked mode.

And of course calls to any service method are wrapped with a try/catch/finally block to handle appropriately any business exceptions (and/or the RemoteException)
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Roel, excuse me, but i don't completely understand mentioned by you design... i'm sorry...

Step 1 :
Roel wrote : You have an interface with your business operations, let's call it BusinessService containing all business methods you want to invoke. This is the interface you will use in your GUI to call methods on.

Ok...

Step 2 :
Roel wrote :You have to create a special remote interface (RemoteBusinessService) which extends Remote and BusinessService (no other methods needed).

Ok... At this step we have empty RemoteBusinessService with no methods (method declaration is in BusinessService ).

Step 3 :
Roel wrote :Then you can create an implementation for RemoteBusinessService and you could use that one for standalone mode as well.

Ok !!! Until now all is extremely simple, clear and logic...

Roel wrote :...in your interface every method will indeed have a "throws RemoteException" (besides any business exceptions).

Here i have doubts... The only place where "throws RemoteException" can be declared is the top interface BusinessService (see the "Step 1").

Roel wrote :And of course calls to any service method are wrapped with a try/catch/finally block to handle appropriately any business exceptions.(and/or the RemoteException)

This phrase confirm my supposition...

Therefore : BusinessService interface (see the "Step 1") declares all methods with "throws RemoteException" in their signature. Am i right (see example below) ?
The overall design is :

It's very interesting, but logicaly (non programmatically) it is not separate remote and locale in package "business" (not "gui")... all is mixed, right ? And BusinessService's methods declare to throw RemoteException without any reason (BusinessService doesn't extend Remote).
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5539
    
  13

You have implemented the design as I explained, so everything is fine.

I'm a bit confused about what you don't understand Is it the "throws RemoteException" for every method declaration in BusinessService? You could always try to leave the RemoteException out from the interface and give your application a run. When I did my assignment I experimented a bit with RMI, because it was completely new to me. I started a thread with some remarks and I also tried to remove "throws RemoteException" from the method signatures (as you can read).

So you simply need them. And when you make a call in your gui to some method you have of course to handle (or declare) all checked exceptions (business and remote), because your guiis completely unaware of the service it's using. It could be the local one (no remote exception will be thrown at all), but it could also be the network one (and then you might have some remote exceptions being thrown).
In your gui a call to the find-method looks like:


In my solution I have 3 different packages: service (containing all business service interfaces and exceptions), direct (containing classes for standalone mode) and rmi (containing classes for network mode). But that's because the implementation of my business service for standalone mode and network mode are slightly different from each other. Your approach with the business package (or services or whatever you call it) is just fine.

Hope it helps!
Dmitri Cherkas
Ranch Hand

Joined: Mar 22, 2010
Posts: 40
Thank you Roel, now it clear to me.
Marcin Mroczkowski
Greenhorn

Joined: Apr 15, 2013
Posts: 17

Roel De Nijs wrote:
And you might have a look at the rmi tutorial and this thread, because RMI expects some must-dos or otherwise it won't work (and you are violating some of them)


I'm really disappointed by RMI. If you want to use it's goodies you need to make a hole in your abstraction and it's not a nice thing, but...

It's actually possible to archive pure abstraction and get rid off dreaded RemoteException:
- write delgate interface, bassicaly same as business interface, but throwing RemoteException
- write decorator implementing Remote and delegate interface, routing it's calls to decorated service implementation
- decorator can be exported in this state as remote object
- on client-side we need "un-decorator", which implements original service, and route interface calls to remote object, handling RemoteException as desired

Pros:
- pure, clean, shiny and lovely business abstraction at last !
- easy handling of RemoteException, in one class and on correct abstaction level

Cons:
- RMI implementation becoming EXTREMELY sensitive to business interface changes
- lot of boilerplate implementation
- code duplication smells very bad
- try to justify SCJD exam assessor this design choice :p

Don't get me wrong, im not crazy enough to apply this solution to real project and i doesn't recommend this to anyone. It's very fragile, but it archieves main goal.


OCJP 6, OCMJD 6
Rehan Zahoor
Ranch Hand

Joined: Jun 19, 2012
Posts: 34

I have a similar problem. In which all methods of my service interface DataAdapterInterface do not throw RemoteException or IOException (superclass of RemoteException) but I want to use these methods in my RMIClient(network layer). I don't want to make all my DataAdapterInterface methods throw RemoteException (This is not required at service layer).

I think a way around should be to use at network layer, an adapter class, that would be implementing an interface similar to DataAdapterInterface, except that it's methods would be throwing RemoteException. Thus Adapting our DataAdapter class for network layer.
The problem is that there would be no reuse of DataAdapterInterface. only reuse of DataAdapter class(both are at service layer)


**OCP, Java SE 6 Programmer**OCM, Java SE 6 Developer**
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Business Service