2013-02-24 2 views
2

스파게티 VBA 코드가있는 MS Access 앱을 C# 및 OOP에 이식하려고하는데 도메인 클래스에 도메인 로직을 추가하는 가장 좋은 방법을 찾기 위해 고심하고 있습니다.도메인 클래스에서 도메인 논리를 표현하는 방법은 무엇입니까?

간단한 예제로 Country 클래스를 사용합니다. 그것은 다른 비즈니스 규칙 세 가지 속성이 있습니다 :

    국가가 만들어지면 그
  • CountryName 언제든지 변경할 수있는 국가를 사용하는 타사 응용 프로그램에 문제가 발생할 것이기 때문에
  • CountryCode는 더 이상 변경할 수 없습니다 어떤 기본 논리 또는 비즈니스 규칙없이
  • IsoCode 언제든지 변경할 수 있지만
    (IsoCode 실제로 더 규칙이 정확히 2 자 여야하지만,이 예제에서는 그냥 "정확히 2 자 여야합니다"고 가정하자입니다 유일한 규칙, 단순화를 위해)

두 개의 약간 다른 버전의 클래스를 만들었습니다.
나는 객체 지향 프로그래밍에서 매우 미숙 한, 그래서 내가 도움이 결정해야

  • 나는 어떤을 사용하는 방법 문제를 않습니다를?
  • 그 중 하나 (또는 ​​둘 다)에 내가 볼 수없는 문제가 있습니까?
  • 다른 방법이 있습니까?

내 접근 방식은 모두 나에게 잘 어울리지 만 나중에 문제가 발생할 수 있는지 여부는 알지 못합니다 (문제의 앱은 10 년이며 오랫동안 계속 사용하게 될 것입니다).


버전 1 :

public class Country1 
{ 
    public string CountryCode { get; private set; } 
    public string CountryName { get; set; } 
    public string IsoCode { get; private set; } 

    public Country1(string countryCode, string countryName, string isoCode) 
    { 
     this.CountryCode = countryCode; 
     this.CountryName = countryName; 
     SetIsoCode(isoCode); 
    } 

    public void SetIsoCode(string isoCode) 
    { 
     if (isoCode.Length != 2) 
     { 
      throw new ArgumentException("must be exactly 2 characters!"); 
     } 

     this.IsoCode = isoCode; 
    } 
} 

버전 2 :

public class Country2 
{ 
    public Country2(string countryCode, string countryName, string isoCode) 
    { 
     this.countrycode = countryCode; 
     this.CountryName = countryName; 
     this.isocode = isoCode; 
    } 

    private readonly string countrycode; 
    private string isocode; 

    public string CountryCode 
    { 
     get { return this.countrycode; } 
    } 

    public string CountryName { get; set; } 

    public string IsoCode 
    { 
     get { return this.isocode; } 
     set 
     { 
      if (value.Length != 2) 
      { 
       throw new ArgumentException("must be exactly 2 characters!"); 
      } 

      this.isocode = value; 
     } 
    } 
} 

이유에 대해 좀 더 배경 나는 이것을 묻고 있는데 내가 알고 싶은 것은 :

나는 "올바른 OOP 방식"에 관해 많은 의견을 읽었다.
게터와 세터를 전혀 노출시키지 말아야한다고 말하는 사람들도 있습니다. 나는 이것이 setter에게 나쁜 생각 인 이유를 이해한다. 그래서 CountryCode은 생성자에서만 설정할 수있다.

getter와 setter를 사용하는 대신 GetXXXSetXXX 메소드를 사용해야한다고 일부 사람들은 말합니다. 어떤 경우에는 이것이 의미가 있음을 알 수 있습니다 (예 : 함께 설정해야하는 여러 값이있을 때 여러 매개 변수가있는 SetXXX 메서드).
그러나 내 예에서는 CountryName과 같은 간단한 값이 있는데, 논리가없는 "멍청한"값입니다.한 클래스에 이런 것들이 10 개일 때 나는 각각에 대해 GetXXXSetXXX 메소드를 생성하고 싶지 않습니다.

IsoCode과 같은 항목이 있습니다. 다른 속성과 연결되어 있지 않으므로 (다른 속성과 함께 설정하려면 SetXXX 메서드를 사용할 필요가 없습니다). 하지만 몇 가지 유효성 검사가 포함되어 있으므로 SetXXX 메서드로 만들거나 setter에서 유효성 검사를 수행하고 잘못된 것이 있으면 예외를 throw 할 수 있습니다.

호출자에게 오류를 알리는 가장 좋은 방법조차 예외를 던지고 있습니까? Some say it's finesome say that you should throw exceptions only for "exceptional" cases.
IMO 사람이 잘못된 ISO 코드를 입력해도 예외는 아니지만 오류가 발생한 정보 (사람이 읽을 수있는 오류 메시지 포함 !!)를 클라이언트에 어떻게 제공해야합니까? 오류 코드와 ErrorMessage 문자열 속성이있는 응답 개체를 사용하는 것이 더 좋습니까?

답변

1

내가 단일 값의 차에 대한 속성을 사용하는 경향이 nges 및 SetXXX 메서드는 거의 한 번에 설정해야하는 둘 이상의 값을 포함하는 규칙이있는 경우 거의 없습니다 (Andy Skirrow가 말했듯이).

SetXXX 모든 메서드는 일반적인 "Javaish"규칙 (C#과 같은 setter 및 getter가없는 여러 언어로 사용됨)입니다.

사람들은 어떤 언어에 대해 배웠던 좋은 습관을 그들이 할 수있는 모든 언어로 강요하려고합니다. 그렇지 않으면 반드시 잘 맞는 것이 아니거나 더 나은 대안이 있습니다.

"OOP maniac"가되지 않도록 노력하십시오. 이것은 당신에게 머리가 아플뿐입니다. OOP는 종교가 아닙니다 (심지어 종교도 광신자가 아닙니다. 그러나 이것은 다른 이야기입니다). 위로 점

두 가지 접근 방식은 기능적인 차이가없고, 미래에 어떤 해가 발생하지 않습니다에

. 코드를 읽기 쉽고 즐겁게 작성하는 방법을 택하십시오. 이것은 많은 사람들이 일을하는 "더 나은 방법"에 대한 자체 정의를 가지고 있기 때문에 "정확한 OOP 방식"보다 훨씬 중요합니다.

검증

당신이 MVC 같은 일부 구조 또는 아키텍처 패턴을 사용하는 경우 클라이언트 측 유효성 검사도 시행하는 데 사용 데이터 주석이 프레임 워크에 따라, 및 검증을 시행 속성 사용할 수 있습니다 .

@Andy Skirrows의 답변 링크를 참조하십시오.

2

개인적으로 나는 속성과 메서드 구현 사이에 많은 차이가 있다고 생각하지 않습니다. 값을 독립적으로 설정할 수있을 때 속성을 사용하는 것이 좋습니다. setter 메서드를 사용하여 값이 서로 어떤 식으로도 (예 : 정수 x 및 y를 설정하고 y가 x보다 클 수 없음) 의존하는 동시에 두 개 이상의 값을 모델에 제공하도록합니다.

유효성 검사를 사용자 인터페이스에 더 가깝게 묶을 수 있으므로보기 모델에서 간단한 유효성 검사 논리 (예 : 필수 필드, 필드 길이)를 사용하는 것이 좋습니다. (예 : 그것이 채워진 후 무효였다). WPF 검증을위한

내가 강하게 조건의 종류 던지는 좋은 후보를 만드는 것에 대해 에릭 Lippert의에 의해이 문서를 권하고 싶습니다/잡기 예외 :

http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx

+0

유효성 확인 : 지금 나는 viewmodel조차 가지고 있지 않습니다. (제가 질문의 시작 부분에서 말했듯이 : Access/VBA 스파게티 코드). 프론트 엔드는 Winforms 또는 WPF (아직 결정되지 않음) 일 가능성이 높지만 어쨌든 뷰 모델에 유효성 검사 로직을 사용하는 것이 좋지만 도메인 클래스에서 사용하는 것이 IMO보다 중요합니다. viewmodel에서 도메인 클래스 ** 및 **의 유효성 검사 논리를 다시 사용할 수있는 좋은 예가 있습니까? –

+0

_ 도메인 클래스 및 뷰 모델에서 유효성 검사 로직을 다시 사용할 수있는 좋은 예가 있습니까? _ 다음을 수행하지 않으면 어떻게됩니까? 새로운 요구 사항 : "이 값 X를이 화면에 표시하십시오. " 문제 없어. 우리는 그 화면을위한 클래스 인 도메인 클래스 A를 가졌습니다. 도메인 클래스 B는 이미 X에 대한 복잡한 계산을 수행하여 다른 화면에 표시합니다. 그래서 A에서해야하는 것은 B를 인스턴스화하고 계산 방법을 호출하는 것입니다. 글쎄, B와 인스턴스가 너무 빡빡하게 결합 되었기 때문에 B를 인스턴스화 할 수 없습니다. webForm/screen과 다른 클래스들입니다. 그것을 고치는 데 3 개월이 걸렸습니다. – radarbob

관련 문제