在 DAO 模式中添加服务有什么好处?
Whats the benefit of adding Service in DAO pattern?
我正在设计我的 JSF 网络应用程序。我不想在我的 Beans classes 中包含业务逻辑代码。所以我决定使用 DAO 模式。现在 Beans 数据(修复数据)存储在 xml 文件中。现在我想为数据库扩展它并使用 Hibernate。
但是我不知道应该在我的服务中放入什么(如果有的话)class。
如果我有这个 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;
}
例如这个 DAO 实现
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);
}
}
}
添加此服务给我的真正好处是什么?
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);
}
}
我看不到对我有任何真正的好处。尽管我确实看到了缺点,例如,如果我需要修改我的 DAO,我也将不得不修改我的服务。或者也许我的服务代码是错误的,它缺少一些重要的部分?感谢您提供任何提示或建议。
编辑
您是否建议创建服务层次结构,类似于我的 DAO 设计?
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;
}
例如这个实现
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);
}
}
服务通常是指将 DAO 捆绑在一起以形成一些业务逻辑。假设您有这样的事情:
public interface CarService {
public void repairCar(Car car);
}
在实施中,您必须从 ManufacturerDao
检索维修过的零件,更新汽车状态并最终向车主收费。例如
// 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());
}
}
整个 repairCar
必须是一笔交易。想象一下,如果你正在修车,而当你想给客户开账单时,你会得到一个例外!如果整件事情不在交易中,您将不得不向供应商支付固定汽车零件的费用,但是……您无法向客户开具账单。没有事务,业务逻辑和数据库状态都坏了。
这可能就是您看不到在 DAO 层之上添加服务层的价值的原因。您的业务逻辑非常简单,您的服务层只需将调用委托给 DAO 层即可。对于您的用例,您可以在没有服务层的情况下生活,直到您需要它。然而在现实世界中,业务逻辑不会那么微不足道,服务层是必须具备的。
我正在设计我的 JSF 网络应用程序。我不想在我的 Beans classes 中包含业务逻辑代码。所以我决定使用 DAO 模式。现在 Beans 数据(修复数据)存储在 xml 文件中。现在我想为数据库扩展它并使用 Hibernate。
但是我不知道应该在我的服务中放入什么(如果有的话)class。
如果我有这个 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;
}
例如这个 DAO 实现
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);
}
}
}
添加此服务给我的真正好处是什么?
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);
}
}
我看不到对我有任何真正的好处。尽管我确实看到了缺点,例如,如果我需要修改我的 DAO,我也将不得不修改我的服务。或者也许我的服务代码是错误的,它缺少一些重要的部分?感谢您提供任何提示或建议。
编辑
您是否建议创建服务层次结构,类似于我的 DAO 设计?
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;
}
例如这个实现
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);
}
}
服务通常是指将 DAO 捆绑在一起以形成一些业务逻辑。假设您有这样的事情:
public interface CarService {
public void repairCar(Car car);
}
在实施中,您必须从 ManufacturerDao
检索维修过的零件,更新汽车状态并最终向车主收费。例如
// 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());
}
}
整个 repairCar
必须是一笔交易。想象一下,如果你正在修车,而当你想给客户开账单时,你会得到一个例外!如果整件事情不在交易中,您将不得不向供应商支付固定汽车零件的费用,但是……您无法向客户开具账单。没有事务,业务逻辑和数据库状态都坏了。
这可能就是您看不到在 DAO 层之上添加服务层的价值的原因。您的业务逻辑非常简单,您的服务层只需将调用委托给 DAO 层即可。对于您的用例,您可以在没有服务层的情况下生活,直到您需要它。然而在现实世界中,业务逻辑不会那么微不足道,服务层是必须具备的。