2010-04-05 4 views
8

이메일/웹 사이트 주소 확인이 필요한 현재 프로젝트에 몇 개의 클래스가 있습니다. 그렇게하는 방법은 모두 동일합니다.동일한 메소드를 사용하는 여러 클래스 - 가장 좋은 패턴

이 방법을 구현하는 가장 좋은 방법은 무엇일까 궁금했는데,이 방법을 복사하여 붙여 넣을 필요가 없었습니까?

클래스 자체는 반드시 관련이있는 것은 아니며 공통적으로 유효성 검사 방법 만 있습니다.

+0

수업에는 어떤 것이 있습니까? 명확성을 위해 클래스에는 단일 목적이 있어야합니다. FrustratedWithFormsDes의 솔루션은이 원칙을 따릅니다. – outis

답변

15

인터페이스 추가 및 확장 방법은 어떻습니까?

public interface IFoo { } 

public class A : IFoo {} 
public class B : IFoo {} 
public class C : IFoo {} 

public static class FooUtils { 
    public static void Bar(this IFoo foo) { /* impl */ } 
} 

그 방법 :

  • 불필요한 상속
+0

클래스 A 내부에서 Bar 메서드에 액세스 할 수 있습니까? –

+0

예 var aClass = new A(); aClass.Bar(); –

+2

은 확장 프로그램 악용 사례입니다. 왜 당신은 EmailUtils 클래스의 static 메소드를 호출하거나 EmailValidator 객체를 생성하고 Validate 메소드를 호출 할 수 있다면 (유효하지 않은) 인터페이스를 구현하고 확장 메서드 마법을 수행하기 위해 이메일 유효성 검사가 필요한 모든 클래스를 요구했을 것입니다. 그 위에)? 또한 클래스 내부에 전자 메일 유효성 검사 코드 만 필요하므로 인터페이스 구현이 필요하지 않아야합니다. – stmax

7

모든 유효성 검사 코드를 Validator 클래스에 넣은 다음 유효성 검사가 필요한 곳이면 어디에서나 해당 클래스를 사용할 수 있습니다. 유효성 검사에 대한 액세스는 단일 메서드 Validate(object Something) 일 수 있습니다. 나는 이것을 "Composition"이라고 부른다 (디자인 패턴이 진행되는 한).

나중에 특정 유형의 유효성 검사기를 사용하거나 다른 종류의 유효성 검사를 수행 할 수 있습니다.

유효성 검사가 필요한 모든 클래스가 유효성 검사의 90 %를 포함하는 기본 클래스 또는 추상 클래스를 확장 할 수도 있습니다.

+1

가장 좋은 용어는 패턴이 아닌 클래스 관계 (http://en.wikipedia.org/wiki/Class_diagram#Instance_Level_Relationships) 인 "연결"입니다. 패턴의 경우 전략 패턴 (http://en.wikipedia.org/wiki/Strategy_pattern)이 관련 될 수 있습니다. – outis

0

이 검증 로직 클래스와 인터페이스를 생성하고 코드에서 주입되는이 ... 그래서 별도에는 중복되지 다시 사용할 수 있도록 유효성 검사에서 논리 ...

1

유틸리티 만들기 y 클래스를 정의하고 이러한 메소드를 적절한 클래스/인터페이스의 확장 메소드로 정의하십시오.

2

예,이 코드를 복제하면 나쁜 냄새가 날 것입니다.이 메서드를 정적 메서드의 단일 Helper 클래스로 추출하거나 "Validator"인터페이스 클래스를 정의 할 수 있으며이 인터페이스를 사용하면 다양한 유효성 검사 메서드를 체인과 연결할 수 있습니다 책임 패턴. 그냥

public static class Utilities{ 
    public static bool validEmail(string email) 
    { 
     //Your code here 
    } 
} 
5

는 소리.
String 대신 클래스의 속성/매개 변수/반환 값으로 Email을 사용하십시오.
문자열을 전자 메일 주소로 확인하는 EmailValidator을 만듭니다.
유효한 전자 메일 주소가 전달되면 전자 메일을 반환하는 EmailFactory을 만들고 그렇지 않은 경우 null입니다.

(웹 사이트도 동일).

+1

+1 확장 메서드 오용 대신 단순함. – stmax

+1

+1 유틸리티 클래스가 여기에있는 것처럼 보입니다. 이메일을 검증하고, 웹 주소 및 다른 종류의 유효성 검사를하는 정적 메소드가있는 유틸리티 클래스를 가져야합니다. 그리고 이러한 메소드가 필요할 때마다이 유틸리티 정적 메소드를 호출하십시오. –

0

별도의 클래스로 Email 만들기 정적 방법으로 정적 클래스가 필요 같은

1

AoP (aspect oriented programming methodology)를 실제로 살펴볼 필요가 있습니다. Enterprise Library 4.1에는 Unity 차단이라는 AoP 구현이 있습니다.

http://msdn.microsoft.com/en-us/library/dd140045.aspx

이 프레임 워크는 전자 메일 확인을 위해 하나의 핸들러 클래스를 코딩 할 수 있습니다. 그래서 이것은 인증 코드가 더 이상 클래스의 일부가 아니라 핸들러 클래스로 들어간다는 것을 의미합니다. 다음으로 할 일은 차단 클래스를 표시하는 것입니다.

요구 사항에 따라 가로 채고 처리해야하는 원하는 메소드의 속성 설정을 포함하여 다양한 방법으로 클래스를 인터셉트 할 수 있습니다. 속성을 설정하는 것이 아마도 차단을하는 가장 쉬운 방법 일 것입니다.

0

IValidator 인터페이스를 만들고 다른 시나리오를 처리하는 여러 가지 유효성 검사기를 만드는 것이 좋습니다. 여기에 하나의 예입니다 :

public interface IValidator { 
    bool CanValidateType(string type); 
    bool Validate(string input); 
} 

CanValidateType() 메소드는 좀 더 복잡 할 수 있지만, 난 당신이 생각을 바랍니다. 기본적으로, 발리 데이터가 입력을 처리 할 수 ​​있을지 어떨지를 식별합니다.

public class UrlValidator : IValidator { 
    bool CanValidateType(string type) { 
     return type.ToLower() == "url"; 
    } 

    bool Validate(string input) { 
     /* Validate Url */ 
    } 
} 

public class EmailValidator : IValidator { 
    bool CanValidateType(string type) { 
     return type.ToLower() == "email"; 
    } 

    bool Validate(string input) { 
     /* Validate Email */ 
    } 
} 

지금 당신은 당신의 클래스로 종속성을 주입하는 생성자 주입을 사용합니다 : : 여기에 몇 가지 구현은 여러 유효성 검사기를 사용할 수있는 클래스가있을 때

public class SomeSimpleClass { 
    private IValidator validator; 

    public SomeComplexClass(IValidator validator) { 
     this.validator = validator; 
    } 

    public void DoSomething(string url) { 
     if (validator.CanValidateType("url") && 
      validator.Validate(url)) 
      /* Do something */ 
    } 
} 

CanValidateType 유용합니다. 이 시나리오에서는 목록 또는 유효성 검사기 배열을 생성자에 전달합니다.

public class SomeComplexClass { 
    private List<IValidator> validators; 

    public SomeComplexClass (List<IValidator> validators) { 
     this.validators = validators; 
    } 

    public bool ValidateUrl(string url) { 
     foreach (IValidator validator in this.validators) 
      if (validator.CanValidateType("url")) 
       return validator.Validate(url); 
     return false; 
    } 


    public bool ValidateEmail(string email) { 
     foreach (IValidator validator in this.validators) 
      if (validator.CanValidateType("email")) 
       return validator.Validate(email); 
     return false; 
    } 
} 

그런 다음 유효성 검사기의 필수 인스턴스를 어떻게 든 클래스에 전달해야합니다. 이것은 종종 Castle Windsor와 같은 IoC 컨테이너를 사용하거나 직접 처리합니다.

IValidator emailValidator = new EmailValidator(); 
IValidator urlValidator = new UrlValidator(); 
SomeSimpleClass simple = new SomeSimpleClass(urlValidator); 
SomeComplexClass complex = new SomeComplexClass(new List<IValidator> { emailValidator, urlValidator }); 

위의 코드는 독자적으로 수행하기가 번거롭기 때문에 IoC 컨테이너가 매우 편리합니다. 인터페이스의

SomeSimpleClass simple = container.Resolve<SomeSimpleClass>(); 
SomeComplexClass complex = container.Resolve<SomeComplexClass(); 

모든 매핑이 당신의 app.config 또는 Web.config의에서 이루어집니다 : IOC는 컨테이너를 사용하면 다음과 같은 일을 할 수 있습니다.

여기는 종속성 주입 및 Castle Windsor IoC 컨테이너의 an awesome tutorial입니다.

관련 문제