元の設計によると、ひどい解決策しかありません。
public class Customer
{
protected List<CustomerAddress> _customerAddresList
= new List<CustomerAddress>();
}
public class Worker : Customer
{
}
public class CustomerAddress
{
protected string _Address1;
public virtual string Address1
{
get { return "customer address: " + _Address1; }
set { _Address1 = value; }
}
}
public class WorkerAddress: CustomerAddress
{
public override string Address1
{
get { return "Worker Address: " + _Address1; }
}
}
エンティティインスタンスが継承されている場合、次のようになります。
// Inheriting instances
public class CustomerBL : Customer
{
public void AddAdress(CustomerAddress address)
{
_customerAddresList.Add(address);
}
}
public class WorkerBL: Worker
{
// Not inehritable, different signature
public void AddAdress(WorkerAddress address)
{
_customerAddresList.Add(address);
}
}
BLクラスを継承する場合、次のようになります。
// Inheriting BL
public class CustomerBL2 : Customer
{
public virtual void AddAdress(CustomerAddress address)
{
_customerAddresList.Add(address);
}
}
public class WorkerBL2 : CustomerBL2
{
public override void AddAdress(CustomerAddress address)
{
if (!(address is WorkerAddress))
throw new Exception();
base.AddAdress(address);
}
}
Genericsを使用する場合、これがあります
// Using generics
public class Generic<TAddress>
{
private List<TAddress> _addresList
= new List<TAddress>();
protected virtual List<TAddress> AddresList
{
get { return _addresList; }
}
}
public class CustomerG : Generic<CustomerAddress>
{
}
public class WorkerG : Generic<WorkerAddress>
{
}
問題は、間違いなく、2つの異なる継承チェーンがあることです。
そして、どちらがそれを実行するのが難しいかについて適切な決定を下すことは不可能です(実際、この設計では、それを正しく実行する方法はないと思います)。
エンティティとBLクラスを互いに独立させて、両方の継承チェーンを独立させ、そのチェーンで継承できるものと継承すべきものを決定できるようにすることをお勧めします。
public class Address
{
}
エンティティは相互に継承できます。わかりました、典型的なケース:
public class Person
{
public List<Address> Adresses;
}
public class Worker: Person
{
// inherits adresses
}
BLクラスの継承(気に入らない):
public class PersonBl
{
// Functionality which is common fot all the inheritance chain
public void PrintAdresses(Person person)
{
}
// Functionality that can be specialized for each inherited entity
public virtual void SaveAdresses(Person person)
{
// they're are treated differently in each case
}
// Functionality specific of person
public void DoSomethingWithPerson(Person person)
{
// TODO
}
}
public class WorkerBl : PersonBl
{
// Uses PersonBl PrintAdresses
public override void SaveAdresses(Person person)
{
// do it for worker
}
// Functionality specific of Worker
public void DoSomethingWithWorker(Worker worker)
{
// TODO
}
}
「他のBLクラスを使用するBLクラス」(それが私が好きな方法です):
public class Person2Bl
{
// Functionality which is common for all the inheritance chain of entities
public void PrintAdresses(Person person)
{
}
public void SaveAdresses(Person person)
{
// specific for person
}
// Functionality specific of person
public void DoSomethingWithPerson(Person person)
{
}
}
// doesn't inherit:
public class Worker2Bl
{
// Use the logic in PersonBl2
public void PrintAdresses(Worker worker)
{
// Really not necessary -> this could be done directly in the app code
Person2Bl bl = new Person2Bl();
bl.PrintAdresses(worker);
}
public void SaveAdresses(Worker worker)
{
// specific of Worker
}
public void DoSomethingWithWorker(Worker worker)
{
// specific of worker
}
}
実際、WorkerBl2とPersonBl2の両方で使用できるAddressB1がある方がよいでしょう。