0

I am a novice programmer learning how to design API for my module. I thought of 2 types of service class to provide a API for other classes to use.

First example handles the logic by parameters, the second example handles by object way.

Which is a better approach / design for me to provide business methods for other classes to use?

As a general rule of thumb which should I use?

Example 1 - Service A

public class ServiceA {

    private SampleDAO dao =  new SampleDAO();
    private static final String DRAFT_STATUS = "DRAFT";
    private static final String APPROVED_STATUS = "APPROVED";
    private static final String SUBMITTED_STATUS = "SUBMITTED";


    public boolean isDocumentApprove(String documentId) {
        Document doc = getDocument(documentId);

        return (APPROVED_STATUS.equals(doc.getStatus()));
    }

    public boolean isDocumentDraft(String documentId) {
        Document doc = getDocument(documentId);

        return (DRAFT_STATUS.equals(doc.getStatus()));
    }

    public boolean isDocumentSubmited(String documentId) {
        Document doc = getDocument(documentId);

        return (SUBMITTED_STATUS.equals(doc.getStatus()));
    }


    private Document getDocument(String documentId) {
        return (dao.getByDocumentId(documentId));
    }
}

Example 2 - Service B

public class ServiceB {

    private SampleDAO dao =  new SampleDAO();
    private static final String DRAFT_STATUS = "DRAFT";
    private static final String APPROVED_STATUS = "APPROVED";
    private static final String SUBMITTED_STATUS = "SUBMITTED";


    public Document getDocument(String documentId) {
        return (dao.getByDocumentId(documentId));
    }

    public boolean isDocumentApprove(Document doc) {    
        return (APPROVED_STATUS.equals(doc.getStatus()));
    }

    public boolean isDocumentDraft(Document doc) {
        return (DRAFT_STATUS.equals(doc.getStatus()));
    }

    public boolean isDocumentSubmited(Document doc) {   
        return (SUBMITTED_STATUS.equals(doc.getStatus()));
    }

}
somesh
  • 589
  • 1
  • 5
  • 11
ilovetolearn
  • 2,006
  • 5
  • 33
  • 64
  • 1
    I fail to see the point of the second example. If the caller already has an instance of Document, why would it call a service to get the status of the document? Why not simply do `doc.isApproved()`? – JB Nizet Jan 31 '13 at 12:17
  • The caller will retrieve the document and pass it to the appropriate methods to check the status of the document etc. – ilovetolearn Jan 31 '13 at 12:25
  • I understand that. But it's unnecessarily complex. If you have a document, get its status directly by calling a method on the document rather than calling an additional method on the service. – JB Nizet Jan 31 '13 at 12:26
  • won't it be very repetitive for all other classes to repeat the same checks? – ilovetolearn Jan 31 '13 at 12:29
  • Why would it be too repetitive to always call `doc.isApproved()`, rather than `service.isApproved(doc)`? – JB Nizet Jan 31 '13 at 12:35
  • you might look at http://stackoverflow.com/q/3885675/217324, it might clarify the point of having a service layer. – Nathan Hughes Jan 31 '13 at 22:20

2 Answers2

1

If I had to choose, i would pick the the second example, because it contains less code duplication. In the first one, there is the same Document doc = getDocument(documentId); statement in every method. So, here the general principle is "don't repeat yourself".

Furthermore, in the first version you can pass any garbage as a string to the methods. Although you can pass null in the second version too, but it is easier to check for null than for invalid ids.

proskor
  • 1,382
  • 9
  • 21
0

Depends on the goal of your API.

Does the caller always have a DocumentID and never a Document instance?

  • ServiceA is the way to go (abstract the Document instance and only return a status).

Does the caller sometimes have a DocumentID and sometimes a Document instance?

  • ServiceB is the way to go as you offer the caller the ability to either get a document or get the status.
  • In this case you would be better off modifying your Document class to include a getStatus() method. That way if the caller has a Document instance they can call document.getStatus() instead of calling your service.
jeuton
  • 543
  • 3
  • 7