스파게티 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를 사용하는 대신 GetXXX
과 SetXXX
메소드를 사용해야한다고 일부 사람들은 말합니다. 어떤 경우에는 이것이 의미가 있음을 알 수 있습니다 (예 : 함께 설정해야하는 여러 값이있을 때 여러 매개 변수가있는 SetXXX
메서드).
그러나 내 예에서는 CountryName
과 같은 간단한 값이 있는데, 논리가없는 "멍청한"값입니다.한 클래스에 이런 것들이 10 개일 때 나는 각각에 대해 GetXXX
과 SetXXX
메소드를 생성하고 싶지 않습니다.
IsoCode
과 같은 항목이 있습니다. 다른 속성과 연결되어 있지 않으므로 (다른 속성과 함께 설정하려면 SetXXX
메서드를 사용할 필요가 없습니다). 하지만 몇 가지 유효성 검사가 포함되어 있으므로 을 SetXXX
메서드로 만들거나 setter에서 유효성 검사를 수행하고 잘못된 것이 있으면 예외를 throw 할 수 있습니다.
호출자에게 오류를 알리는 가장 좋은 방법조차 예외를 던지고 있습니까? Some say it's fine 및 some say that you should throw exceptions only for "exceptional" cases.
IMO 사람이 잘못된 ISO 코드를 입력해도 예외는 아니지만 오류가 발생한 정보 (사람이 읽을 수있는 오류 메시지 포함 !!)를 클라이언트에 어떻게 제공해야합니까? 오류 코드와 ErrorMessage
문자열 속성이있는 응답 개체를 사용하는 것이 더 좋습니까?
유효성 확인 : 지금 나는 viewmodel조차 가지고 있지 않습니다. (제가 질문의 시작 부분에서 말했듯이 : Access/VBA 스파게티 코드). 프론트 엔드는 Winforms 또는 WPF (아직 결정되지 않음) 일 가능성이 높지만 어쨌든 뷰 모델에 유효성 검사 로직을 사용하는 것이 좋지만 도메인 클래스에서 사용하는 것이 IMO보다 중요합니다. viewmodel에서 도메인 클래스 ** 및 **의 유효성 검사 논리를 다시 사용할 수있는 좋은 예가 있습니까? –
_ 도메인 클래스 및 뷰 모델에서 유효성 검사 로직을 다시 사용할 수있는 좋은 예가 있습니까? _ 다음을 수행하지 않으면 어떻게됩니까? 새로운 요구 사항 : "이 값 X를이 화면에 표시하십시오. " 문제 없어. 우리는 그 화면을위한 클래스 인 도메인 클래스 A를 가졌습니다. 도메인 클래스 B는 이미 X에 대한 복잡한 계산을 수행하여 다른 화면에 표시합니다. 그래서 A에서해야하는 것은 B를 인스턴스화하고 계산 방법을 호출하는 것입니다. 글쎄, B와 인스턴스가 너무 빡빡하게 결합 되었기 때문에 B를 인스턴스화 할 수 없습니다. webForm/screen과 다른 클래스들입니다. 그것을 고치는 데 3 개월이 걸렸습니다. – radarbob