私は私のJSFのWebアプリケーションの設計に取り組んでいます。私は豆のクラス内のビジネス・ロジック・コードを持つようにしたいいけません。だから私は、DAOパターンを使用することにしました。今ビーンズデータ(修理データ)は、XMLファイルに格納されています。今私は、データベースとの使用にHibernateのためにそれを拡張したいです。
しかし、私は(どちらかといえば)私は私のサービスクラス内に置くべきであるものにこだわっています。
私はこの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を変更する必要があります場合は、たとえば、disadventagesを参照していますが、私も自分のサービスを変更する必要があります。それとも私のサービスコードが間違っている、そしてそれはいくつかの重要な部分が欠けていますか?任意のヒントや提案をお寄せいただきありがとうございます。
EDIT
あなたは、私の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層への呼び出しを委任されることをとても簡単です。あなたがそれを必要とするまで、あなたのユースケースに対しては、サービス層なしで生きることができます。現実世界のカントーでは、ビジネスロジックは些細なようではありませんし、サービス層が持っている必要があります。