2010-01-29 2 views
2

명령 패턴을 이해하면 '1 개의 가상 메서드'execute() '가 있고 구현에있을 수있는 모든 종속성이 생성자에 삽입되거나 설정 구현에 삽입됩니다 (예 : 논의 된 here).명령 패턴 및 매개 변수 디자인

그러나 패턴의 WPF 구현에서 나는 일반 인수를 execute() 함수에 전달하는 것으로 나타났습니다 (here 설명).

이 인터페이스에 오염이있는 것 같습니다. 일반 매개 변수를 execute() 함수에 추가하려는 동기는 무엇입니까?

답변

1

데이터 바인딩 용입니다. 예를 들어 목록의 모든 객체에 명령을 바인딩하면 현재 인스턴스가 execute 메서드로 보내 지므로 현재 인스턴스를 직접 추적 할 필요가 없습니다.

그렇다고해서 WPF 명령 개념이 명령 패턴 구현이 아니라고 생각합니다. 그들은 단지 용어를 공유합니다. 명령이 무엇을 필요로하는지 가 실행되는 알고, 그리고 발신자 - -이 명령을 실행해야 할 때 을 알고

1

해당 매개 변수 뒤에 이유는 명령의 창조자 사이의 분리이다.

일부 명령에서는 실행에 필요한 일부 정보를 작성자가 사용할 수 없습니다. 호출자는 실행할 매개 변수를 전달하여 공백을 채 웁니다. 예 : 작성자는 몇 가지 기준에 따라 레코드 목록을 필터링하는 명령을 작성합니다. 이 목록은 응용 프로그램에 많은 종류의 목록이 있으므로 작성 사이트에서 사용할 수 없습니다.

호출자는 매개 변수로 전달하여 필터링해야 할 목록을 지정합니다.

+0

예를 들어, 목록에서 작업하는 명령에 대한 특정 인터페이스가 필요합니다.이 인터페이스는 목록 (또는 목록의 인터페이스)을 매개 변수로 사용하며 일종의 일반 매개 변수가 아닙니다. – eli

+0

@ eli.work : 매개 변수가 일반화되어야한다고 말하지 않았습니다. 방금 명령 개체가 생성 된 사이트에서 실행에 필요한 데이터를 항상 사용할 수있는 것은 아니라고 말했습니다. –

+0

제 질문에 대한 질문이 좀 더 명확해야합니다. 제가 궁금해하는 일반적인 매개 변수의 동기입니다. 내 질문을 업데이트하고 답장을 보내 주셔서 감사합니다! – eli

1

우리는 약간 변경된 명령 패턴을 사용하므로 Execute 메소드 외에 Request와 Response의 두 가지 속성이 있으며 다형성을 사용하여 매개 변수를 매개 변수화합니다.

3

표준 명령 패턴은 일반적으로 훌륭한 자체 포함 명령으로 설명됩니다. 명령에 필요한 모든 정보가 Command 객체 인스턴스 내에 숨겨져 있습니다 (일반적으로 매개 변수화 된 생성자를 통해).

그러나 일부 경우 Execute에 필요한 매개 변수가 명령 작성시 사용 가능하지 않을 수도 있습니다 (런타임에만 알려짐). 예 : SignOutCommand(username)을 상상해보십시오. 사용자 이름은 먼저 로그인 한 후 SignOut 버튼을 클릭 할 때 결정됩니다.

따라서 사용자 이름은 Command.Execute()의 일반 매개 변수로 전달됩니다. 각 명령은 자유롭게 입력을 정의하고 이에 따라 캐스트 할 수 있습니다. 임의의 명령은 5 개의 매개 변수를 object []로 요구할 수 있습니다.

+0

별도의 인터페이스를 정의하지 않거나 IUserNameGetter와 같은 다른 곳에서 사용자 이름을 가져 오는 명령 구현을 만드는 것이 어떨까요? – eli

+0

@ eli.work 단순함과 우아함 사이의 상반 관계입니다. IUserNameGetter를 사용하면이 새로운 유형의 인스턴스를 만들어 Command 객체에 저장해야합니다. 모든 Execute 호출과 함께 명령 객체는 다시 GUI에서 사용자 이름을 검색하기 위해 메시지를 다시 보냅니다. 입력 내용을 전달하는 것보다 더 수다스러운 이야기. 또한 WPF에서 GUI를 생성 한 스레드에서 GUI에 액세스하는 경우 IUserNameGetter impl에서 스레드 확인 및 전환이 필요할 수 있습니다 (예 : Command.Execute가 작업자 스레드에서 호출되는 경우). – Gishu

1

문제의 새로운 기능 : 이제

public class DeleteCommand : BaseCommand 
{ 
    private Dictionary<string, object> parameters; 

    public DeleteCommand(Dictionary<string, object> parameters) 
    { 
    this.parameters = parameters; 
    } 

    public void Execute() 
    { 
    var person = (Person)parameters["Person"]; 
    var salary = System.Convert.ToDouble(parameters["Salary"]); 

    // etc. 
    } 
} 

당신이 매개 변수를 수집하는 컨트롤러가있는 경우 당신은 당신의 명령을 통해 사람들을 전달할 수 있습니다.

+1

Dictionary를 Execute 메서드에 전달해도 Action 자동화 프레임 워크에서 유사한 접근 방식을 사용 했으므로 Action 개체는 상태 비 저장되어 캐시 될 수 있습니다. –