2011-04-22 3 views
0

아래 코드는 내 디자인 문제를 자세히 설명합니다. 나는 여러 유형의 반복 패턴을 가질 수있는 데이터베이스에 작업 테이블을 가지고있다. 작업 테이블에는 가능한 각 되풀이 패턴 필드에 대한 열이 있습니다. 그러나 Task 개체가 db에있는 패턴을 기반으로 적절한 패턴을 만들길 원합니다. 아래의 코드는이 작업을 수행하지만 문제는 호출 코드가 항상 어떤 작업을 수행하기 전에 반환되는 되풀이 유형을 확인해야한다는 것입니다.OO 모델에 플랫 DB 모델 매핑

var t = new Task(); 
var pattern = t.Recurrance; 

호출 코드에는 어떤 재연 유형이 생성되는지 알지 못합니다.

이것을 모델링하는 더 좋은 방법은 무엇입니까?

class Task 
{ 
    private int recurrenceType = 0; //pulled from the db 
    public Task() 
    { 
     //determine recurrence type from database 
     switch (recurrenceType) 
     { 
      case 0: 
       Recurrance = new RecurrenceDaily(); 
       break; 
      case 1: 
       Recurrance = new RecurrenceMonthly(); 
       break; 
      case 2: 
       Recurrance = new RecurrenceWeekly(); 
       break; 
     } 
    } 
    public RecurrenceBase Recurrance { get; set;} 
} 

abstract class RecurrenceBase 
{ 
    public int Frequency { get; set; } 
} 

class RecurrenceDaily : RecurrenceBase 
{ 
    public bool Weekends { get; set; } 
} 

class RecurrenceWeekly : RecurrenceBase 
{ 
    public DaysOfWeekFlagsEnum DaysOfWeek { get; set; } 
} 

class RecurrenceMonthly : RecurrenceBase 
{ 
    public byte DayOfMonth { get; set; } 
    public WeekEnum Week { get; set; } 
    public DayOfWeekEnum DayOfWeek { get; set; } 
} 

답변

0

글쎄,이 코드에는 여러 가지 문제가 있습니다. 처음에는 Recurrance를 생성하기 전에 RecurranceType을 설정할 방법이없는 생성자에서 Recurrance를 생성하기 때문에 RecurranceDaily가 항상 RecurranceDaily가됩니다. 오브젝트의 데이터를 설정하기 전에 오브젝트를 작성해야합니다. 생성자 자체에 해당 데이터를 설정하지 않으면 항상 기본 상태 (int는 0이고 사용자가 0으로 초기화 됨)가됩니다.

둘째, recurranceType에 대한 설정자가 없으며 값이 private이므로 구성 후 설정 방법이 없습니다.

셋째로, Recurrance 회원은 getter 만있는 속성이지만 생성자에서는 값을 설정합니다. 설정이 없으므로 컴파일되지 않습니다.

+0

감사합니다. 반복 속성에 설정을 추가하여 문제를 해결했습니다. –

+0

다른 전화를 사용하고 싶지 않으면 개인 설정자로 지정할 수 있습니다. 아직도, 당신은 나의 처음 두 점을 언급하지 않았다. –

0

디자인 방향에 대한 지적인 제안을하기에 충분한 정보를 제공했는지 확신 할 수 없지만 반복 유형에 따라 다른 유형의 작업 (예 : DailyTask, WeeklyTask, MonthlyTask)을 고려하는 것이 좋습니다. .

그런 다음 적절한 논리를 작업 하위 클래스에 배치 할 수 있습니다. 예를 들어.

var task = db.GetTaskById(15); 
task.Schedule(startDate); 

데이터베이스 코드는이 WeeklyTask, 예를 들어, 그 안에서 적절한 재발을 설정할 수 있다고 파악, id로 작업을 얻을 것입니다. 그런 다음 startDate에서 시작하는 주간 작업에 적합한 Schedule 메서드가 있습니다.

public interface ITask 
{ 
    public void Schedule(DateTime startDate); 
} 

public abstract class TaskBase : ITask 
{ 
    // common methods... 
    public abstract void Schedule(DateTime startDate); 
} 

public class WeeklyTask : TaskBase 
{ 
    public override void Schedule(DateTime startDate) 
    { 
     var startWeek = GetStartOfWeek(startDate); 
     var firstDate = startWeek.AddDays(DaysOfWeek[0]); 
     ... 
    } 
} 
+0

또한 작동 할 수 있습니다. 다른 재귀 패턴 대신 differnt 유형의 작업을 반환합니다. 그러나 문제는 여전히 남아 있습니다 ...이 호출은 기본 클래스를 반환해야하므로'var task = db.GetTaskById (15); '호출로 바로 이동합니다. 호출자가 반환되는 객체 유형을 확인하는 유일한 방법은 반환 된 객체에 대한 유형 검사를 수행하는 것입니다. –

+0

@pmaroun -하지만 다른 부분은 특정 작업 하위 클래스로 작업을 이동하는 것입니다. 즉, 각 작업에는 작업 할 코드가 포함되어 있습니다. 인터페이스를 통해 작업을 노출합니다. 이 예제에서는 하나의 'Schedule' 메소드를 사용했지만 태스크에서 수행 할 다른 모든 작업은 비슷하게 처리됩니다. 이런 식으로 호출하는 코드는 인터페이스 계약에 대해서만 알 필요가 있으며 각 태스크 유형에 대해 다른 코드를 가지지 않아야합니다. 이는 캡슐화의 기본적인 OO 원칙입니다. 각 클래스에는 데이터 ** 및 **에 해당 데이터를 처리하는 코드가 있어야합니다. – tvanfosson

0

은 분명히 여기에 눈에 보이는 것보다 시나리오에 더있다,하지만 난 SO About Inversion of Control And Dependency Injection에서이 답변에 보일 것이다. 그런 다음 The Martin Fowler Article으로 이동하십시오. IoC와 DI를 사용하면 RecurrenceBase를 "DoSomething"이벤트와 같은 IRecur 인터페이스와 같은 것으로 추상화하여 공통점을 만들 수 있습니다. 아마도 일정을 캡슐화하는 "RecurrenceEventArgs"클래스 일 수 있습니다.

나는 이것이 올바른 방향으로 향하게되기를 바랍니다.

0

상속 계층 구조 (OO 구조)를 만들었지 만 표시되는 클래스는 동작이없고 데이터 만 노출하기 때문에 분명히 객체 지향이 아닙니다.

이것은 상속을 부적절하게 사용하고 고통의 원인이되는 부분의 일부입니다.

상속을 받으면 부모 클래스와 동일한 계약으로 하위 클래스를 사용할 수 있다고 명시하고 있습니다.여러분이 보여주고있는 수업과 그것을 사용하는 방식으로, 이것은 사실이 아닙니다.

관련 문제