2012-03-24 4 views
0

확실히 이것이 최고의 제목이 아닙니다. 수학 문제를 생성하는 시스템을 만들고 있습니다. 개발자는 다음 두 인터페이스를 구현해야합니다.두 클래스 간의 통신을 유지하는 방법은 무엇입니까?

  • Problem : 생성 된 문제가 필요한 속성이 포함되어 있습니다.
  • Configuration : Problem을 생성하는 범위 매개 변수입니다.

이는 인터페이스입니다 :

public abstract class Problem 
{ 
} 

public abstract class Configuration 
{ 
} 

enter image description here

그리고 여기가 BinaryProblem 하나의 예이다.

public class BinaryProblem : Problem 
{ 
    public decimal X { get; set; } 
    public decimal Y { get; set; } 

    public BinaryProblem(decimal x, decimal y) 
    { 
     this.X = x; // Number 1 
     this.Y = y; // Number 2 
    } 
} 

public class BinaryProblemConfiguration : Configuration 
{ 
    // Range for X 
    public int XMin { get; set; } 
    public int XMax { get; set; } 

    // Range for Y 
    public int YMin { get; set; } 
    public int YMax { get; set; } 

    public BinaryProblemConfiguration() { } 
} 

문제와 구성 사이의 줄을 볼 수 있습니까? 나는이 두 인터페이스를 구현하는 많은 모듈을 넣어야한다.

그래서 생성 할 방법이 필요합니다.

  • protected static Random을 : 거의 모든 구성이 번호 (즉 random.Next(X1, Y1);)를 생성하는 임의의 클래스를 필요로 나는 포함하는 경우 추상 클래스를 만들 수있는 생각했다. 그리고 항상 같은 씨앗을 사용하여 숫자를 만들 필요가 있기 때문에 정적이어야합니다.
  • public abstract TProblem Generate(TConfiguration config); // where : TProblem : Problem, new(), TConfiguration : Configuration

그리고 각 문제 유형이 추상 클래스를 구현합니다.

내 질문은 :이 솔루션을 해결하기 시작하는 좋은 방법입니까, 아니면 다른 솔루션을 사용해야합니까?

편집 : 내가하려고 한 하나의 예는 다음과 같습니다

이 내 추상 클래스, 내 생각은이 클래스를 실체화 할 때, 당신은 일반적인 값을 지정 의미 :

public interface IProblemFactory 
{ 
    Problem CreateProblem(); 
} 

public abstract class ProblemBaseFactory<TProblem, TConfiguration> : IProblemFactory 
    where TProblem : Problem 
    where TConfiguration : Configuration 
{ 
    private const int SEED = 100; 
    protected TConfiguration _config; 
    protected static Random _random; 

    public ProblemBaseFactory(TConfiguration config) 
    { 
     _config = config; 

     if (_random == null) _random = new Random(SEED); 
    } 

    public void SetSeed(int newSeed) 
    { 
     _random = new Random(newSeed); 
    } 

    public Problem CreateProblem() 
    { 
     return CreateProblem(_config); 
    } 

    public abstract TProblem CreateProblem(TConfiguration config); 
} 

public class BinaryProblemFactory : ProblemBaseFactory<BinaryProblem, BinaryProblemConfiguration> 
{ 
    public override BinaryProblem CreateProblem(BinaryProblemConfiguration config) 
    { 
     var x = GenerateValueInRange(_config.Range1); 
     var y = GenerateValueInRange(_config.Range2); 
     return new BinaryProblem(x, y, Operators.Addition); 
    } 

    private decimal GenerateValueInRange(Range<int> range) 
    { 
     return _random.Next(range.MinValue, range.MaxValue); 
    } 
} 
+0

Sorr, 나는 'Problem'과 'Configuration'에서 파생 된 클래스가 어떻게 사용되는지 이해하지 못합니다. 사용 예를 추가 할 수 있습니까? – MiMo

+0

X, X1 및 Y1의 범위와 Y, X2, Y2의 범위가 이유는 무엇입니까? 예! XMin과 XMax 등을 사용하십시오. –

+0

새로운 정보를 추가했습니다 :) –

답변

2

을 내가 함께 사용 집계 값에 좋은 것 같아요. 귀하의 경우 개체 범위 유용 할 것입니다. (< = 최대 분 검증없이) 식으로 뭔가 :

public class Range<T> 
{ 
    public Range(T min, T max)   
    { 
     Min = min; 
     Max = max; 
    } 

    public T Min { get; private set; } 
    public T Max { get; private set; } 
} 

그 BinaryProblemConfiguration 후에는 다음과 같이됩니다 : 당신이 실제로 구현하는 제품 공장입니다

public class BinaryProblemConfiguration 
{ 
    public Range<int> XRange { get; set; } 
    public Range<int> YRange { get; set; } 
} 

. 그래서 중개자는 그 이름을 잘 나타내지 못합니다.

public interface IProblemFactory 
{ 
    Problem CreateProblem(); 
} 

각 유형의 제품에 대해 공장을 만드십시오. 각 공장은 그것이 생산하는 제품의 유형과 필요한 유형의 구성을 알고 있습니다. 예컨대 :

public class BinaryProblemFactory : IProblemFactory 
{ 
    private BinaryProblemConfiguration _config; 
    private Random _random; 

    public BinaryProblemFactory(BinaryProblemConfiguration config) 
    { 
     _config = config; 
     // or you can use const seed here 
     _random = new Random(DateTime.Now.Millisecond); 
    } 

    public override Problem CreateProblem() 
    { 
     var x = GenerateValueInRange(_config.XRange); 
     var y = GenerateValueInRange(_config.YRange); 
     return new BinaryProblem(x, y); 
    } 

    private decimal GenerateValueInRange(Range<int> range) 
    { 
     return _random.Next(range.Min, range.Max); 
    } 
} 

공장 제작 :

BinaryProblemConfiguration config = new BinaryProblemConfiguration(); 
config.XRange = new Range<int>(0, 100); 
config.YRange = new Range<int>(-50, 50); 

IProblemFactory problemFactory = new BinaryProblemFactory(config); 

패스 생성 문제 공장 어딘가에 IProblemFactory 등 : 또한이 구성 개체에 대한 특별한 필요

Problem problem = problemFactory.CreateProblem(); 

. 나는 제품의 창조자가 제품을 만드는 법을 알고 있어야한다고 생각한다. 그래서 저는 XRange와 YRange 속성을 공장에 추가하려고합니다 :

BinaryProblemFactory binaryProblemFactory = new BinaryProblemFactory(); 
binaryProblemFactory.XRange = new Range<int>(0, 100); 
binaryProblemFactory.YRange = new Range<int>(-50, 50); 
+0

예, 그게 내가 찾고있는 것입니다! 공장 패턴. 한 가지 어리석은 의심, 나는 정말로 모든 공장이 랜덤 속성의 동일한 인스턴스를 구현할 필요가 있습니다. 랜덤 속성에 대해이 인터페이스를 기본 클래스 (추상)로 변환하면 불편한 점이 있습니까? –

+0

물론 보호 된 임의 필드가있는 추상 ProductFactory를 생성하십시오. 또한 모든 구체적인 팩토리에 필요할 경우 GenerateNewValueInRange 메서드를 추상 팩터 리로 이동할 수 있습니다. 조언을 주신 덕분에 –

+0

. 게시물을 업데이트하고 현재 디자인의 최종 세트로 설정했습니다. 나는 매우 편하지 않을 것 같아서 당신을 보여주고 싶습니다. 아마도 IFINTory와 FactoryBase 클래스에서 지침을 따르지 않거나 이해할 수 없을지도 모릅니다. 어떻게 생각하세요? –

0

당신의 질문을 이해한다면 잘 모르겠습니다 만, 어쨌든 제 의견을 말씀 드리려고합니다. 희망이 도움이됩니다.

나는 당신이 잘못된 접근법을 선택했다고 생각합니다. - 두 클래스가 있지만 전혀 통신하지 않습니다. - 예, 파생 클래스를 만들었지 만이 특별한 경우에는 이유가 표시되지 않습니다. 그들은 아무 것도 정의하지 않으며, 수업을 이끌어내는 어떤 논리도 강요하지 않습니다. 인터페이스를 생성 할 때 인터페이스를 구현할 누군가가 필요합니다. 빈 클래스/인터페이스는 실제로 구현할 수 없습니다.

첫째,이 문제를 해결할 것을 제안합니다. 구현할 때 특정 메소드 나 특성이 필요한 인터페이스를 작성하십시오. 이 방법을 사용하면 다른 개발자가 어떤 문제를 만들었더라도 자신이 사용할 수있는 특정 방법으로 인터페이스를 구현해야한다는 것을 알 수 있으므로 주 응용 프로그램을보다 쉽게 ​​개발할 수 있어야합니다. 빈 인터페이스를 구현하도록 허용하면 실제로 결과가 무엇인지 예상 할 수 없습니다. 당신은 그 (것)들에 좋게 행동하기 위하여 의지 할 수 없다 (또는 적어도 should not는).

둘째, 알고 계실지 모르겠지만 모듈을 사용할 때 (문제 + 구성을 하나의 모듈로 사용) 각각을 별도의 .cs 파일에 배치하십시오. 그렇게하면 사실상 무한한 수의 앱을 유지하면서 앱을 쉽게 유지 관리 할 수 ​​있습니다.

셋째,이 같은 몇 가지 인터페이스를 사용하여 이러한 클래스 사이에 관계 (통신)을 건의 할 것입니다 :

public interface IProblem 
{ 
    IProblemConfiguration Config; 

    // other needed methods or properties 
} 
관련 문제