문제

어떤 수업 디자인이 더 좋고 그 이유는 무엇입니까?

public class User
{
    public String UserName;
    public String Password;
    public String FirstName;
    public String LastName;
}

public class Employee : User
{
    public String EmployeeId;
    public String EmployeeCode;
    public String DepartmentId;
}

public class Member : User
{
    public String MemberId;
    public String JoinDate;
    public String ExpiryDate;
}

또는

public class User
{
    public String UserId;
    public String UserName;
    public String Password;
    public String FirstName;
    public String LastName;
}

public class Employee
{
    public User UserInfo;
    public String EmployeeId;
    public String EmployeeCode;
    public String DepartmentId;
}

public class Member
{
    public User UserInfo;
    public String MemberId;
    public String JoinDate;
    public String ExpiryDate;
}
도움이 되었습니까?

해결책

이 질문은 상속이 "IS-A" 관계를 모델로 하는 반면 멤버십은 "HAS-A" 관계를 모델로 한다는 점을 인식함으로써 간단하게 답할 수 있습니다.

  • 직원은 사용자입니다
  • 직원에게 사용자 정보가 있습니다

어느 것이 맞나요?이것이 당신의 대답입니다.

다른 팁

나는 둘 중 하나를 좋아하지 않습니다.누군가가 회원이자 직원인 경우에는 어떻게 되나요?

스스로에게 다음을 물어보세요:

  • 직원을 모델로 삼으시겠습니까? 이다 사용자?그렇다면 상속을 선택하세요.
  • 직원을 모델로 삼으시겠습니까? 가지다 사용자 정보?그렇다면 컴포지션을 사용하세요.
  • 사용자(정보)와 직원 사이에 가상 기능이 관련되어 있습니까?그렇다면 상속을 사용하세요.
  • 직원이 사용자(정보)의 여러 인스턴스를 가질 수 있습니까?그렇다면 컴포지션을 사용하세요.
  • Employee 개체를 User(정보) 개체에 할당하는 것이 합리적입니까?그렇다면 상속을 사용하세요.

일반적으로 코드 복잡성과 필요한 효율성의 제약 하에서 프로그램이 시뮬레이션하는 현실을 모델링하려고 노력하십시오.

나는 구성이 항상 상속보다 낫다고 생각하지 않습니다(보통 그렇습니다).직원과 회원이 실제로 사용자이고 상호 배타적이라면 첫 번째 디자인이 더 좋습니다.직원의 UserName에 액세스해야 하는 시나리오를 생각해 보세요.두 번째 디자인을 사용하면 다음과 같은 결과를 얻을 수 있습니다.

myEmployee.UserInfo.UserName

이는 나쁘기 때문에(데메테르의 법칙) 다음과 같이 리팩터링해야 합니다.

myEmployee.UserName

User 개체에 위임하려면 Employee에 대한 작은 메서드가 필요합니다.첫 번째 디자인에서는 이러한 모든 것을 방지합니다.

주의가 산만해지는 것을 피하기 위한 좋은 질문입니다. 오른쪽 그리고 잘못된 각 접근 방식의 장단점을 물어보는 것을 고려해 보겠습니다. 어느 것이 더 좋고 더 나쁘고 그 이유는 무엇인지에 대한 의미인 것 같습니다.그래도 ....

첫 번째 접근 방식(상속)

장점:

  • 다형성 동작을 허용합니다.
  • ~이다 처음에는 간단하고 편리합니다.

단점:

  • 5월 시간이 지남에 따라 복잡해지거나 서툴러짐 만약에 더 많은 행동과 관계가 추가됩니다.

두 번째 접근 방식(구성)

장점:

  • 관계형 테이블, 구조적 프로그래밍 등과 같은 비-oop 시나리오에 잘 매핑됩니다.
  • (반드시 편리하지는 않더라도) 간단합니다. 점진적으로 관계와 행동을 확장합니다.

단점:

  • 다형성이 없으므로 관련 정보 및 동작을 사용하는 것이 덜 편리합니다.

다음과 같은 목록 + 질문 존 림잡 언급된 내용은 결정을 내리고 시작하는 데 도움이 됩니다. 그런 다음 오른쪽 대답은 다음과 같았어야 했습니다 ;-)

Employee를 다음과 같이 생각할 수도 있습니다. 역할 사용자(사람)의.사용자의 역할은 시간이 지남에 따라 변경되거나(사용자가 실직할 수 있음) 동시에 여러 역할을 가질 수 있습니다.

상속은 있을 때 훨씬 더 좋습니다. 진짜 "is a" 관계(예: Apple - Fruit)하지만 매우 조심하세요.원 - 타원은 실제 "is a" 관계가 아닙니다. 왜냐하면 원형은 타원보다 "자유도"가 낮기 때문입니다(원은 a입니다). 상태 타원) - 참조: 원 타원 문제.

실제 질문은 다음과 같습니다.

  • 사용자 뒤에 숨은 비즈니스 규칙과 사용자 스토리는 무엇입니까?
  • 직원 뒤에 숨겨진 비즈니스 규칙과 사용자 스토리는 무엇입니까?
  • 회원 뒤에 숨은 비즈니스 규칙과 사용자 스토리는 무엇입니까?

이들은 전혀 관련이 없는 세 가지 엔터티일 수 있으며, 이에 따라 첫 번째 디자인이나 두 번째 디자인이 작동할지 또는 완전히 다른 디자인이 적합한지 여부가 결정됩니다.

어느 쪽도 좋지 않습니다.변경 가능한 상태가 너무 많습니다.유효하지 않거나 부분적으로 초기화된 상태에 있는 클래스의 인스턴스를 생성할 수 없어야 합니다.

즉, 두 번째 방법은 상속보다 구성을 선호하기 때문에 더 좋습니다.

요구 사항/사양을 명시하면 '최고의 디자인'에 도달하는 데 도움이 될 수 있습니다.
귀하의 질문은 현재 너무 '독자 해석의 대상'입니다.

고려해야 할 시나리오는 다음과 같습니다.

동일한 사용자가 직원이자 회원일 수 있는 경우 구성(두 번째 예)이 바람직합니다.왜?동일한 사용자를 나타내는 두 인스턴스(직원 및 구성원)의 경우 사용자 데이터가 변경되면 두 위치에서 업데이트할 필요가 없습니다.User 인스턴스에만 모든 User 정보가 포함되어 있으며 업데이트만 하면 됩니다.Employee 및 Member 클래스 모두 동일한 User 인스턴스를 포함하므로 두 클래스 모두 자동으로 업데이트된 정보를 포함합니다.

세 가지 추가 옵션:

  1. 가지고 User 클래스에는 직원과 회원 모두에 대한 추가 정보가 포함되어 있으며 사용되지 않은 필드는 비어 있습니다( ID 특정의 User 사용자가 직원인지, 회원인지, 둘 다인지 등을 나타냅니다.

  2. 가지고 User 에 대한 참조를 포함하는 클래스 ISupplementalInfo, 어디 ISupplementalInfo 에 의해 상속됩니다 ISupplementalEmployeeInfo, ISupplementalMemberInfo, 등.작업할 수 있는 모든 사용자에게 적용 가능한 코드 User 클래스 객체와 코드 User 참조는 사용자의 추가 정보에 접근할 수 있지만 이 접근 방식을 사용하면 변경이 필요하지 않습니다. User 향후에 보충 정보의 다른 조합이 필요한 경우.

  3. 위와 같지만 User 클래스에는 일종의 컬렉션이 포함되어 있습니다. ISupplementalInfo.이 접근 방식은 사용자에게 런타임에 속성을 추가하는 것을 용이하게 한다는 이점이 있습니다(예:왜냐하면 Member 채용되었습니다).이전 접근 방식을 사용하는 경우 다양한 속성 조합에 대해 다양한 클래스를 정의해야 합니다."회원"을 "회원+고객"으로 전환하려면 "직원"을 "직원+고객"으로 전환하는 것과 다른 코드가 필요합니다.후자 접근 방식의 단점은 중복되거나 일관되지 않은 속성(예: Dictionary<Type, ISupplementalInfo> 추가 정보를 보관하는 것은 효과가 있을 수 있지만 약간 "부피"해 보일 수 있습니다.

나는 직접적인 상속보다 미래의 확장을 더 잘 허용한다는 점에서 두 번째 접근 방식을 선호하는 경향이 있습니다.단일 개체가 아닌 개체 컬렉션을 사용하여 작업하는 것은 약간 부담스러울 수 있지만 이러한 접근 방식은 다른 접근 방식보다 변화하는 요구 사항을 더 잘 처리할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top