Heredar miembros de múltiples clases

He estado aprendiendo a diseñar con OOD y atorado con un escenario.

Tengo una clase User que extiende una clase abstracta Person . La clase Person tiene un miembro con el tipo Address . User solo tiene nombre de usuario y contraseña, y dirección tiene algunos campos de cadena.

Ahora, deseo agregar una clase Client que puede ser una Person o una Organization (para ser agregada). Client también tendrá algunos datos.

Pensé en las interfaces, pero solo pueden tener métodos. ¿Alguien puede ayudarme con lo que será el diseño adecuado?

No estoy siguiendo ningún patrón y codificación con C# .NET.


Actualizar

I think I could not explain the scenario properly. Sorry for that. Please, have a look on the diagram. Here, the Client class is what I want to add. Incomplete class diagram of my scenario

0
Las interfaces no están limitadas a métodos, también pueden tener propiedades getter setter y eventos. prefiero las interfaces aquí
agregado el autor Saghir A. Khatri, fuente
"Pensé en interfaces, pero solo pueden tener métodos". No, también pueden tener propiedades y eventos ... Aunque no está del todo claro para mí lo que intentas modelar ...
agregado el autor Jon Skeet, fuente
@SergeyBerezovskiy Es la clase Client que puede heredarse de Person o Organization .
agregado el autor Raihan, fuente
Además, supongo que Organization s también tienen una Address . Así que tal vez Address debería estar en Client y Person y Organization debería derivar de Client ?
agregado el autor CompuChip, fuente
De su pregunta no puedo elegir una clase que debe ser heredada de múltiples clases
agregado el autor Sergey Berezovskiy, fuente
¿El cliente necesita ser un usuario? Si So Client debe heredar de User, mueva la dirección al usuario y entonces también tendrá la dirección. Tal vez deberías agregar que debe reemplazar la propiedad de solo lectura "Tipo de usuario" a la clase de usuario que se reemplaza en las subclases. Las subclases definen qué tipo de UserTypes son.
agregado el autor Mino, fuente

1 Respuestas

Intenta trabajar con la composición. Una persona y una organización no son necesariamente usuarios, aunque ambos pueden TENER una dirección o una cuenta de usuario. En realidad, es muy probable que tengan más de uno de los dos.
Si piensa más en términos de HAS A y menos en términos de IS A, puede encontrar opciones más sostenibles. Por ejemplo, puedes tener un

class Address {
  public string street {get; private set;}
  public string city {get; private set;}
  public AddressTypes AddressType {get; private set;}//an enum to differentiate 
                                                     //"home address", "legal address"
  ...
}

ahora, si necesita modelar el hecho de que tanto una Person como una Organization son cosas que deben tener Address es, puede crear una interfaz

interface IAddressable {
   IEnumerable
{get;} }

y tener tanto Person como Organization implementarlo. Lo mismo se puede hacer con una clase Cuenta </​​code> que contiene Nombre de usuario y Contraseña .

Ahora Person y Organization no necesitan ser User s, pero ambos pueden tener cuentas, direcciones y cualquier otra cosa que necesite. Y puede obligarlos a tener estas cosas a través de interfaces, como se muestra arriba.

En cuanto a Client , puedo ver su problema. Está tentado a decir que "una Persona (o una Organización) ES un Cliente". Pero en su diseño "una Persona ES ya un Usuario" y no puede hacer que la Persona herede de dos clases base diferentes.

Sin embargo, tenga en cuenta que una Persona no es necesariamente un cliente. No estoy seguro de qué es exactamente un Cliente en su modelo, pero supongamos que es una persona con una Dirección y una Cuenta que puede ser una Persona o una Organización (y desea saber si es una u otra). Puedes hacer esto de varias maneras, pero uno podría ser:

abstract class Client : IAddressable, IWithAccount {
  //implement IAddressable and IWithAccount
}

class PersonClient : Client
{
    public PersonClient(Person person)
    {
       //make the Client's address refer to the Person's address
       //make the Client's account refer to the Person's account
    }
}

class OrganizationClient : Client
{
    public OrganizationClient(Organization organization)
    {
       //make the Client's address refer to the Organization's address
       //make the Client's account refer to the Organization's account
    }
}

las ventajas son que:

  • no tiene que cambiar su código existente para adaptar un rol (Cliente) como una clase base de entidades existentes (Persona, Organización).
  • si su empresa comienza a tener, por ejemplo, estados como clientes, puede agregar un StateClient sin cambiar las piezas existentes
0
agregado
Gracias por un buen consejo. Agregué la clase User solo para los usuarios del sistema. No es necesario que sean personas . Pero pueden tener detalles personales.
agregado el autor Raihan, fuente
Person es una clase abstracta. ¿Cómo puedo crear una instancia de eso?
agregado el autor Raihan, fuente
Cuando quiero obtener todos los clientes, hay un problema con su diseño. Tengo que llamar a PersonClient.GetAll() y OrganizationClient.GetAll() .
agregado el autor Raihan, fuente
@Raihan No estoy seguro de entender tu pregunta, pero necesitarás una clase concreta heredando de Persona si es una clase abstracta.
agregado el autor Paolo Falabella, fuente
@Raihan mi código era solo un ejemplo. Puede hacer que el Cliente sea una clase no abstracta si lo necesita de esa manera. Y si los tipos de clientes no van a extenderse en el futuro, puede tener una enumeración en Cliente que especifique el tipo de cliente, como hice para AddressType en la clase Address, en lugar de las subclases PersonClient y OrganizationClient.
agregado el autor Paolo Falabella, fuente