2014-12-10 4 views
3

OOP 구성에 관한 질문이 있습니다.OOP 구성

어머니의 어머니가 0 명과 어린이가 더 많고 어린이에게 생물학적 어머니가 하나 뿐인 경우를 가정 해 보겠습니다.

public class Mother : ObservableObject 
{ 
    // [...] 

    ObservableCollection<Child> Children {get; set;} 
} 

public class Child : ObservableObject 
{ 
    public Child(Mother mother) 
    { 
     this.Mother = mother; 

     // Adding the child to the mother's children collection 
     mother.Children.Add(this); 
    } 

    public Mother Mother {get; set;} 
} 

하지만 난 다음에 가야 경우 자동으로 어머니의 컬렉션에 아이를 추가 괜찮아, 또는 궁금 :

Mother mother = new Mother(); 

Child child = new Child(mother); 
mother.Children.Add(child); 

그것을 설명하기 위해 , 나는 다음과 같은 한

감사합니다 :)

+0

어머니가 아이들을 낳지 않습니까? – Jodrell

+2

'mother.GiveBirth (new Child());':) – crashmstr

+0

아마 어머니는 그 아이가 그녀의 콜렉션에 없었을 것입니다! – BenjaminPaul

답변

5

내가 원하는 것,

public class Mother : ObservableObject 
{ 
    // ... 

    public Child GiveBirth() 
    { 
     var newBorn = new Child(this); 
     this.Children.Add(newBorn); 
     return newBorn; 
    } 

    // ... 
} 
,
+0

당신은 더 빨랐습니다 :) 나는 많은 수의 Java/.NET 라이브러리와 프로젝트에서이 접근법을 보았습니다. – Gerino

+0

동의합니다. 생성자에 넣으면 어머니가 항상 아이를 갖게됩니다. 헌신적 인 도메인 방법을 사용하는 것이 더 깨끗합니다. 이제는 엄마가 아이를 갖기를 원합니다. :) 그러나, 아이가 엄마가 존재해야만한다면, 생성자가가는 길입니다! –

+0

나는이 옵션을 생각하지 않았다는 것을 인정한다. 고마워! – SeaSharp

2

나는 모델링이 약간 벗어난 것 같아요. MotherChild은 의미 적으로 서로 관련되어 있지만 동일한 객체의 인스턴스입니다. 둘 다 Person입니다.

Person의 생성은 Person에 의해 수행되는 연산입니다. 따라서 Person에는 public 생성자가 없어야하지만이 논리를 처리하는 팩토리 메소드가 있어야합니다. 이 같은 것은 :

public class Person : ObservableObject 
{ 
    private Person() 
    { 
     Children = new ObservableCollection<Person>(); 
    } 

    public Person Mother { get; private set; } 
    public ObservableCollection<Person> Children { get; private set; } 

    public Person Procreate() 
    { 
     var child = new Person(); 
     child.Mother = this; 
     this.Children.Add(child); 
     return child; 
    } 
} 

이 모델링은 여전히 ​​제한적입니다. 예를 들어 여기서는 무성 생식에 대해서만 이야기합니다. 그래서 우리는 인간을 효과적으로 모델링하지 못합니다. 아마도 우리는 아버지를 추가해야할까요?

public class Person : ObservableObject 
{ 
    private Person() 
    { 
     Children = new ObservableCollection<Person>(); 
    } 

    public Person Mother { get; private set; } 
    public Person Father { get; private set; } 
    public ObservableCollection<Person> Children { get; private set; } 

    public Person Procreate(Person father) 
    { 
     var child = new Person(); 
     child.Mother = this; 
     child.Father = father; 
     this.Children.Add(child); 
     father.Children.Add(child); 
     return child; 
    } 
} 

nulls 및 기타 등등을 확인하는 것이 좋습니다. 이제 성별을 지정해야한다는 사실을 발견했습니다. (가족 구조가 상당히 다를 수 있지만, 사람을 만드는 행위는 꽤 잘 성립됩니다.) 그래서 우리는 그런 특징을 계속 추가 할 수 있습니다. 어느 시점에서 실제로 이들을 서브 클래스화할 수 있지만이 서브 클래스는이 Person 수퍼 클래스의 하드 코딩 된 기본값을 갖는 거의 의미 론적 통과 객체가 될 가능성이 높습니다.

그러나 단지 재미를 위해, 확인

public class Person : ObservableObject 
{ 
    private Person(Sex gender, Person mother, Person father) 
    { 
     // TODO: Check for null mother and father 
     this.Gender = gender; 
     this.Mother = mother; 
     this.Father = father; 
     Children = new ObservableCollection<Person>(); 
    } 

    public Sex Gender { get; private set; } 
    public Person Mother { get; private set; } 
    public Person Father { get; private set; } 
    public ObservableCollection<Person> Children { get; private set; } 

    public Person Procreate(Person father) 
    { 
     // TODO: Check for null father, confirm gender of father 
     var child = new Person(PickRandomGender(), this, father); 
     this.Children.Add(child); 
     father.Children.Add(child); 
     return child; 
    } 

    private Sex PickRandomGender() { /.../ } 

    public enum Sex 
    { 
     Female, 
     Male 
    } 
} 

, 그건 재미 ... 이제 성별을 추가 해보자. 일부 논리를 생성자로 이동하여 조금 정리했습니다. 그러나 이제는 또 다른 문제가 있습니다. 아버지가 창궐 할 수 있습니다. 어떤 종류의 고통스러운 소리.

public class Person : ObservableObject 
{ 
    protected Person(Sex gender, Person mother, Person father) 
    { 
     // TODO: Check for null mother and father 
     this.Gender = gender; 
     this.Mother = mother; 
     this.Father = father; 
     Children = new ObservableCollection<Person>(); 
    } 

    public Sex Gender { get; private set; } 
    public Person Mother { get; private set; } 
    public Person Father { get; private set; } 
    public ObservableCollection<Person> Children { get; private set; } 

    protected Sex PickRandomGender() { /.../ } 

    public enum Sex 
    { 
     Female, 
     Male 
    } 
} 

public class Woman : Person 
{ 
    // TODO: Override Gender with a hard-coded value 

    public Person Procreate(Person father) 
    { 
     // TODO: Check for null father, confirm gender of father 
     var child = new Person(PickRandomGender(), this, father); 
     this.Children.Add(child); 
     father.Children.Add(child); 
     return child; 
    } 
} 

(우리는뿐만 아니라 Man를 서브 클래 싱해야 그것은 의미 청소기 보이지만, 어떤 작업이 또는 여자에 의해 공유되지 않는 사람에게 특정 속성 : 우리가 서브 클래스 준비가 것처럼 지금은 보인다? 아마도, 우리 모델은 아직 상세하지 않습니다.)

이 시점에서 MotherChild의 클래스는 제한적이며 근시안적인 것처럼 보입니다. 여자는 반드시 어머니가 아니며, 모든 사람들은 아이들입니다. 여러분이 상상할 수 있듯이,이 시스템에 추가 할 수있는 많은 기능이 있습니다. 그러나 이와 같은 도메인을 구축하는 일반적인 프로세스를 따라하면이를 수용해야합니다.

+0

@ J.Steen : 그것들은 어떻습니까? 그 부부는 아이를 키우는 것이 아니라 아이를 입양하는 것입니다. 우리는 (아직) 가족 구조를 모델링하는 것이 아니라 단지 아이를 만드는 물리적 인 행위입니다. 어느 것이 아주 잘 확립되고 널리 알려진 작업입니다. – David

+0

매우 좋은 답변과 설명을 해주셔서 감사합니다. – SeaSharp

+0

@ J.Steen : 도메인 모델은 현재 상당히 광범위합니다. 동의합니다. 추가 할 기능이 많이 * 있습니다. 젠장, 가능한 작업으로 복제에 대해서도 이야기 할 수있다. 그러나 비즈니스 모델에 의해 지원되지 않는다면 금 도금 일뿐입니다. 가치가있는 것을 위해, 전에 도메인 모델 관점보다는 데이터 모델 관점에서 비슷한 질문에 답했습니다 : http://stackoverflow.com/a/22114472/328193 – David