2

Vehicleと呼ぶ抽象クラスがあります。クラスディーゼル電気、およびガスは車両を拡張します。これらの3つのクラスには、独自のメソッドと変数、およびVehicleから継承したものがあります。

DieselElectric、およびGasオブジェクトの変数をデータベース内の同じテーブルに配置したいと思います。Electricオブジェクトから作成されたレコードには、 Dieselオブジェクトと同じ変数がない空の列がいくつかあるだけです。

行を挿入し、行を更新し、行を取得するメソッドを作成します。これらはすべて、これらのクラスのオブジェクトを引数として受け入れます。

私はそれが何であるかを私が知らないと思うので、私はこの問題に対する最良の解決策を探しています。これまでのところ、いくつかの解決策を考えることができますが、どれも好きではありません。

  1. 次の各メソッドを4つ作成します:挿入、更新、削除、および取得/選択。これにより、多くの重複コードが発生します。

    public void AddVehicle(Diesel diesel)
    public void AddVehicle(Electric electric)
    public void AddVehicle(Gas gas)
    
    public Electric ViewVehicles()
    public Diesel ViewVehicle()
    public Gas ViewVehicle()
    
    public void RemoveVehicle(Diesel diesel)
    public void RemoveVehicle(Electric electric)
    public void RemoveVehicle(Gas gas)
    
    public void UpdateVehicle(Diesel diesel)
    public void UpdateVehicle(Electric electric)
    public void UpdateVehicle(Gas gas)
    
  2. 任意のオブジェクトを受け入れることができるように各メソッドを作成します:(オブジェクトを取得するのではなく、取得できるオブジェクトのリストを指定する方法はありますが、それでもそのうちの1つのみを取得しますか?つまり、public void AddVehicle(Dieseldiesel | |電気||ガスガス)

    public void AddVehicle(Object vehicle)
    
    public Object ViewVehicle(Object vehicle)
    
    public void RemoveVehicle(Object vehicle)
    
    public void UpdateVehicle(Object vehicle)
    
  3. クラス(ディーゼル、電気、またはガス)のいずれかを含むことができる「マスター」クラスを作成します。このクラスは、挿入/更新/表示/削除メソッドに渡されます。(この「master」クラスを引数として受け入れるようにinsert / update / viewメソッドを設定します。)「master」クラスの不完全なコンストラクター:

    public MasterVehicle(Diesel diesel)
    public MasterVehicle(Electric electric)
    public MasterVehicle(Gas gas)
    
  4. 適切で、よりクリーンで、より理にかなっている他のソリューション。

しかし、#4は何でしょうか?

4

5 に答える 5

1

オプション2について:まず、DieselElectric、およびGasがVehicleを実装/拡張する限り 、 Objectの代わりにVehicleを使用できます。それは仕事をするべきです。

さらに、オプション 2 の ViewVehicle の場合:

public Object ViewVehicle(対象車両)

ジェネリック メソッドを使用して、常に同じ型を返すようにすることもできます。詳細はこちら: http://docs.oracle.com/javase/tutorial/extra/generics/methods.html ...メソッドから返されるメソッドにオブジェクトを送信しようとする理由が明確ではありません。

于 2012-12-24T01:40:44.067 に答える
1

あなたの質問の冒頭であなたが言ったように:

Vehicle と呼ぶ抽象クラスがあります。クラス Diesel、Electric、および Gas は Vehicle を実装します。

つまり、Vehicle がスーパークラスで、Diesel、Electric、Gas が Specialization です。

データベース上のテーブルは、このレイアウトを反映できます

Vehicle (id, brand, price, type) // type could help you selecting electric,gas,diesel

Electric(vehicle_id, volts, amp, ohms, other_specific_stuff)
Gas(vehicle_id, pressure, gas_type, other_specific_stuff) 
Diesel(vehicle_id, other_specific_stuff) 

車両を照会するときは、左外部結合を使用できます

select * from vehicle as v
    left outer join electric as e on (v.id = e.vehicle_id)
    left outer join gas as g on (v.id = g.vehicle_id)
    left outer join diesel as d on (v.id = d.vehicle_id)

次に、type フィールドを使用して特定のサブクラスにマップします。

データベースにオブジェクトを保存または更新する場合、共通部分を保存するメソッドが必要です。

void update(Vehicle v) { 
    // store v.* in Vehicle table
}

特定の車の残りを保存する方法

void update(Electric e) {
    update(v)
    // store e.* on Electric table
}

削除と挿入も同じです。

于 2012-12-24T01:44:34.783 に答える
1

幸いなことに、他の人もこの問題に対処しなければなりませんでした:)

ここには、実際には 2 つの問題があります。1つはあなたが特定したAPIの設計であり、もう1つはDBへの実際の保存/読み取りを処理する方法です。

最初の問題については、オブジェクト指向の設計原則に最もよく従っているので、オプション #2 を使用します。しかし、私はメソッドに を受け入れさせませんObject。代わりに、型を受け入れるようにしVehicleます。

2 番目の問題については、次のリンクを参照してください: Entity Inheritance Mapping Strategies。JPA (または任意の ORM フレームワーク) を使用しない場合でも、これらはおそらく検討したい戦略です。

上記のリンクで言及されている単一テーブル戦略の詳細な説明を次に示します。これはあなたに良いアイデアを与えるはずです --> 継承: 単一テーブル戦略

于 2012-12-24T01:46:09.183 に答える
1

Generic DAO は、あなたが興味を持っているかもしれないものです。長い答えを書くことを避けようとしているので、ここにリンクがあります。 jジェネリック

一般的な dao のバリエーションは、インターネット上で多数見つけることができます。

于 2012-12-24T01:51:47.423 に答える
1

オブジェクト指向モデル層 (Java) から永続化層 (リレーション データベース) を分離し、「CRUD」操作を忘れて、オブジェクトの動作についてもっと考えることをお勧めします。

のコレクションGarage実装するクラスがあると便利です。Vehicles

interface Garage extends Collection<? extends Vehicle> {
  Vehicle find(int id);
}

次に、次のように使用できます。

Garage garage = new GarageInSql(/* your persistence layer details */);
Electric vehicle = Electric.class.cast(garage.find(123));
int mileage = vehicle.mileage();
vehicle.rename("Chevrolet");
garage.remove(vehicle);

トランザクションを制御する必要がある場合は、もう 1 つのメソッドを導入してくださいGarage#commit()

于 2012-12-25T12:15:05.677 に答える