2011-03-24 9 views
2

그래서 구현이 아닌 인터페이스로 코드를 작성하려고합니다. 그래서 저는 Employee에서 파생 된 객체를 반환하는 팩토리를 가지고 있습니다. 그래서이 객체들은 Developer : Employee, Secretary : Employee 등과 같은 개발자 일 수 있습니다.파생 클래스에서 속성 추가

그래서 FirstName, LastName, Email 등의 모든 공유 속성을 기본 클래스 (Employee)에 넣습니다.

그리고 각 유형에 해당하는 모든 속성을 해당 유형에만 넣어야합니다. 그래서 개발자는 Skills, ProgrammingLanguages ​​등과 같은 속성을 가지지 만 구체적인 유형의 개발자를 사용하지 않으면 Employee 객체에서 이러한 속성에 액세스 할 수 없습니다.

Employee employee = new EmployeeFactory.CreateEmployee(EmployeeType.Developer); 
employee.ProgrammingLanguages = "C#, Java, C++"; <-- compile error 

이 문제를 해결하는 가장 좋은 방법은 무엇입니까? 반사...?

+0

이 경우에는 과제 전에 백업해야한다고 생각합니다. – asawyer

+0

그런 경우 파생 클래스에서 명시 적으로 속성에 액세스하고 있기 때문에 기본 클래스에 대해 코드를 작성하는 것은 의미가 없습니다 –

+0

리플렉션 방식으로 이동하려는 경우 .NET 4에서 dynamic 키워드를 사용할 수 있습니다. 코드를 더 깨끗하게 보일 것입니다. –

답변

2

왜 제네릭을 사용하고

T EmployeeFactory.CreateEmployee<T>() 
{ 
    return new T(); 
} 

같은 뭔가를 그리고 당신이 유형이 지정된 개발자로 끝날 것입니다 그런 식으로

var dev = EmployeeFactory.CreateEmployee<Developer>(); 

처럼 호출하지.

+0

이렇게하면 현재 코드에서는 필요하지 않은 컴파일 타임에 'Employee'유형을 알 필요가 있습니다. – Jon

+0

형식이 가변적이면이 코드는 작동하지 않지만 현재 코드는 형식을 더 많거나 적게 열거합니다 (열거 형). –

+0

나는 이것을 좋아한다. 어떻게 생성자에게 param을 보낼 수 있습니까? public static T EmployeeFactory () 여기서 T : Employee { string someParam = ""; return new T (someParam); } – Joe

4

명시 적으로 어떤 직원 유형을 사용할지 알려면 공장을 왜 귀찮게합니까?

대신

, 당신은 쓸 수 있습니다 :에, 같은

IList<Employee> theEmployees = GetEmployees(); 
theEmployees.Add(dev); // This is fine, since Developer is an Employee... 
+0

나는 귀하의 요점을 참조하십시오. 그렇다면 초기화 매개 변수를 얻기위한 모든 논리가 하나의 자리에있을 것이므로 파생 클래스 각각에 db 연결 문자열과 같은 일부 초기화를 전달할 수 있기 때문에 저는 공장을 좋아합니다. 나는 그것을 기본 클래스로 옮길 수 있다고 생각 하긴하지만 ... 이점이나 단점이 무엇인지는 확실치 않습니다. – Joe

+0

@Joe : 예 - 쉽게 기본 클래스에있을 수 있으며 생성자로 전달되었습니다. 실제 수업을 "숨겨야"않는 한 실제로 이점은 거의 없습니다. –

0

그것은 나에게 보인다

Developer dev = new Developer(); 
dev.ProgrammingLanguages = "C#, Java, C++"; // compiles fine 

나중에, 당신은 여전히 ​​즉, 직원의 목록에 "개발자"를 추가 할 수 있습니다 최소한이 특별한 경우에는 기본 유형을 사용해서는 안됩니다.

일반 Employee이 아닌 Developer과 관련된 특정 작업을 수행하므로 기본 유형 작업의 이점을 상실하게됩니다.

말했다되고 그건
Developer developer = new Developer(); 
developer.ProgrammingLanguages = "C#, Java, C++"; 

, 당신은 항상 더 많은 특정 유형에 다시 캐스팅을 시도 할 수 있습니다 : 당신의 코드에서

Employee employee = new EmployeeFactory.CreateEmployee(EmployeeType.Developer); 

Developer developer = employee as Developer; 
if(developer != null) developer.ProgrammingLanguages = "C#, Java, C++"; 
1

, 명확하게하려고 할 때이 경우, 단지 새로운 개발자를 만들 employee.ProgrammingLanguages을 알고 계신다면 employeeDeveloper입니다. 그래서 그냥 캐스팅 할 수 있습니다 더 아마도

Developer dev = new (Developer)EmployeeFactory.CreateEmployee(EmployeeType.Developer); 
dev.ProgrammingLanguages = "C#, Java, C++"; 

또는 :

Developer dev = new Developer(); // If you don't really need the factory. 
dev.ProgrammingLanguages = "C#, Java, C++"; 

을이 작업을 수행 할 수있는 경우 당신이 모르는 여부, 당신은 is 또는 as으로 테스트 할 수 있습니다 상황에서.

그 (것)들을 다루는 이해되는 수준에 것을 유지하십시오. 분명히 프로그래밍하지 못할 수도있는 사람의 프로그래밍 언어에 대해 이야기하는 것이 이치에 맞지 않으므로 Developer 수준의 계층 구조에서 작동합니다.공휴일과 급여를 처리하는 코드는 모든 직원에게 동일하거나 적어도 대체 할 가능성이있는 공통 인터페이스를 통해 작업해야하므로 계층 구조의 수준에서 Employee으로 작동합니다.

0

이 경우 가장 간단한 해결책을 제안 할 것입니다. 다음과 같이 직원 유형별로 하나의 메소드를 만듭니다.

public Developer CreateDeveloper(); 
public Secretary CreateSecretary(); 

왜 "못 생기는"솔루션입니까? 클라이언트 코드의 형식을 어느 쪽이든 알 필요가 있기 때문입니다. 그렇다면 제네릭/리플렉션을 복잡하게 만드는 이유는 무엇입니까? 단순 함은 신성합니다.

관련 문제