Whats the benefit of adding Service in DAO pattern?

10101101 :

I am working on design of my JSF web app. I dont want to have business logic code inside my Beans classes. So I decided to use DAO pattern. Right now Beans data (repairs data) is stored in xml files. Now I want to extend it for database and use Hibernate.

But I am stuck with what should I put (if anything) inside my Service class.

If I have this DAO

public interface IRepairDao {

public Repairs fetchRepairs() throws RepairDaoException;
public Manufacturers fetchManufacturers() throws RepairDaoException;
public List<Model> fetchManufacturerModels(Manufacturer manufacturer) throws RepairDaoException;
public void saveRepairs(Repairs repairs) throws RepairDaoException;
}

And for example this DAO implementation

public class RepairXmlDao implements IRepairDao {

private Serializer xmlSer;
private final String repairsXmlPath = "E:\\WORK\\Mariusz\\repairs.xml";
private final String setupXmlPath = "E:\\WORK\\Mariusz\\setup.xml";

@Override
public Repairs fetchRepairs() throws RepairDaoException {
    try {
        xmlSer = new Persister();
        InputStream fis = new FileInputStream(repairsXmlPath);
        BufferedReader in = new BufferedReader(
                new InputStreamReader(fis, Charset.forName("UTF-8")));
        String str = "", s;
        while((s = in.readLine()) != null)
            str += s;
        Repairs repairs = xmlSer.read(Repairs.class, str);
        return repairs;
    } catch(Exception e) {
        throw new RepairDaoXmlExcpetion("Thrown when fetching repairs from xml", e);
    }
}

@Override
public Manufacturers fetchManufacturers() throws RepairDaoException {
    try {
    xmlSer = new Persister();
    InputStream fis = new FileInputStream(setupXmlPath);
    BufferedReader in = new BufferedReader(
            new InputStreamReader(fis, Charset.forName("UTF-8")));
    String str = "", s;
    while((s = in.readLine()) != null)
        str += s;
    Manufacturers manufacturers = xmlSer.read(Manufacturers.class, str);
    //models = manufacturers.getManufacturers().get(0).getModels();
    return manufacturers;
    } catch(Exception e) {
        throw new RepairDaoXmlExcpetion("Thrown when fetching manufacturers from xml", e);
    }
}

@Override
public List<Model> fetchManufacturerModels(Manufacturer manufacturer) throws RepairDaoException {
    List<Model> models = new ArrayList<>();
    Manufacturers manufacturers = fetchManufacturers();
    for(Manufacturer m : manufacturers.getManufacturers()) {
        if(m.getName().equals(manufacturer.getName())) {
            models = m.getModels();
            break;
        }
    }
    return models;
}

@Override
public void saveRepairs(Repairs repairs) throws RepairDaoException {
    try {
        xmlSer = new Persister();
        File result = new File(repairsXmlPath);
        xmlSer.write(repairs, result);
    } catch(Exception e) {
        throw new RepairDaoXmlExcpetion("Thrown when saving repairs to xml", e);
    }
}

}

And what is my real benefit of adding this Service to it ?

public class RepairService {

private IRepairDao repairDao;

public Repairs fetchRepairs() throws RepairDaoException {
    return repairDao.fetchRepairs();
}

public Manufacturers fetchManufacturers() throws RepairDaoException {
    return repairDao.fetchManufacturers();
}

public List<Model> fetchManufacturerModels(Manufacturer manufacturer) 
        throws RepairDaoException {
    return repairDao.fetchManufacturerModels(manufacturer);
}

public void saveRepairs(Repairs repairs) throws RepairDaoException {
    repairDao.saveRepairs(repairs);
}
}

I cannot see any true benefits for me. Although I do see disadventages, for example if I will need to modify my DAO, I will also have to modify my Service. Or maybe my service code is wrong, and it lacks some important pieces ? Thanks for any tips or suggestions.

EDIT

Are You suggesting to create Service hierarchy, similar way to my DAO design?

public abstract class ARepairService {

protected IRepairDao repairDao;

public ARepairService(IRepairDao repairDao) {
    this.repairDao = repairDao;
}

public abstract Repairs fetchRepairs() throws RepairDaoException;

public abstract Manufacturers fetchManufacturers() throws RepairDaoException;

public abstract List<Model> fetchManufacturerModels(Manufacturer manufacturer) 
        throws RepairDaoException;

public abstract void saveRepairs(Repairs repairs) throws RepairDaoException;
}

And this implementation for example

public class RepairServiceXml extends ARepairService {

public RepairServiceXml(IRepairDao repairDao) {
    super(repairDao);
}

@Override
public Repairs fetchRepairs() throws RepairDaoException {
    return repairDao.fetchRepairs();
}

@Override
public Manufacturers fetchManufacturers() throws RepairDaoException {
    return repairDao.fetchManufacturers();
}

@Override
public List<Model> fetchManufacturerModels(Manufacturer manufacturer) 
        throws RepairDaoException {
    return repairDao.fetchManufacturerModels(manufacturer);
}

@Override
public void saveRepairs(Repairs repairs) throws RepairDaoException {
    repairDao.saveRepairs(repairs);
}
}
Silviu Burcea :

A service is usually when you're bundling together your DAOs to form some business logic. Let's say you have something like this:

public interface CarService {
  public void repairCar(Car car);
}

In the implementation, you'd have to retrieve the repaired parts from the ManufacturerDao, update the car status and eventually bill the car's owner. e.g.

// skipped non-relevant parts(e.g. DAO injection) for brevity
public class CarServiceImpl implements CarService {

public ManufacturerDao manufacturerDao;
public BillingDao billingDao;
public CarDao carDao;

public void repairCar(Car car) {
    // get the car part
    Model model = car.getMissingPart();
    CarPart carPart = manufacturerDao.getNewCarPart(model);
    // install it and save the car
    car.installCarPart(carPart);
    car.setStatus(Status.REPAIRED);
    carDao.updateCar(car);
    // bill the owner
    billingDao.bill(car.getOwner());
}

}

The whole repairCar would have to be one transaction. Imagine if you're fixing the car and just when you want to bill the client, you get an exception! If the whole thing wasn't in a transaction, you'd have to pay your suppliers for the fixed car parts but ... you couldn't bill the customer. Both the business logic and the database status are broken without a transaction.

This is probably why you can't see the value of adding a service layer on top of the DAO layer. Your business logic is so easy that your service layer would be just delegating the calls to the DAO layer. For your use case, you can live without service layer until you need it. In the real world tho, business logic will not be as trivial and the service layer is a must-have.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=10201&siteId=1