2012-01-22 3 views
5

런타임에 winform 패널의 컨트롤을 동적으로 추가 및 바꾸는 중입니다.상속을 공장 패턴으로 인터페이스로 대체하는 방법은 무엇입니까?

모든 작업을 수행 할 수 있지만 baseUserControl에서 상속하는 것이 아니라 인터페이스를 구현해야한다고 들었습니다.

내가 인터페이스 내 공장을 코딩 할 방법

를 사용하여 동일한 결과를 얻을 수있는 방법을 참조 나는 모든 오전하지만 난 해달라고?

어떻게 개선하고 대신 인터페이스를 사용할 수 있습니까? 여기

//Simplified noddy example 

//Client code 
var controlA = ControlFactory 
    .Create("UserControlA") as UserControlA; 

panel1.Controls.Add(ControlA); 

//Factory 
public class ControlFactory 
{ 
    public static BaseUserControl Create(string name) 
    { 
     switch (name) 
     { 
      case "UserControlA": 
       var userControlA = new UserControlA(); 

       return userControlA; 

      case "UserControlB": 
       var userControlB = new UserControlB(); 
       return userControlB; 
     } 
     return null; 
    } 
} 
    //BaseUserControl 
    public partial class BaseUserControl : UserControl 
    { 
     public BaseUserControl() 
     { 
      InitializeComponent(); 
     } 

     public virtual void DoSomething() 
     { 

     } 
    } 

    public partial class UserControlA : BaseUserControl 
    { 
     public UserControlA() 
     { 
      InitializeComponent(); 
     } 

     public override void DoSomething() 
     { 
      //Do something here 
     } 
    } 

public partial class UserControlB : BaseUserControl 
{ 
    public UserControlB() 
    { 
     InitializeComponent(); 
    } 

    public override void DoSomething() 
    { 
     //Do something here 
    } 
} 
+0

이 http://codereview.stackexchange.com/ – GolfWolf

+3

이유에 대한 질문처럼 보인다? 기본 클래스보다 인터페이스를 사용하면 어떤 이점이 있습니까? – Oded

+0

이들은 독점하지 않습니다. IUserControl은 DoSomething()을 선언 할 수 있으며 IUserControl을 구현하여 BaseControl을 구현할 수 있습니다 (공장에서 IUserControl을 반환). – Joe

답변

7

당신이 그것을 할 수있는 방법은 다음과 같습니다

using System; 
using System.Windows.Forms; 
using System.ComponentModel; 

//Interface 
public interface IControl : IComponent 
{ 
    void DoSomething(); 
} 

//Factory 
public class ControlFactory 
{ 
    public static IControl Create(string name) 
    { 
     switch (name) 
     { 
      case "UserControlA": 
       var userControlA = new UserControlA(); 

       return userControlA; 

      case "UserControlB": 
       var userControlB = new UserControlB(); 
       return userControlB; 
     } 
     return null; 
    } 
} 

//BaseUserControl 
public partial class BaseUserControl : UserControl, IControl 
{ 
    public BaseUserControl() 
    { 
     InitializeComponent(); 
    } 

    public virtual void DoSomething() 
    { 

    } 
} 

public partial class UserControlA : BaseUserControl, IControl 
{ 
    public UserControlA() 
    { 
     InitializeComponent(); 
    } 

    public override void DoSomething() 
    { 
     //Do something here 
    } 
} 

public partial class UserControlB : BaseUserControl, IControl 
{ 
    public UserControlB() 
    { 
     InitializeComponent(); 
    } 

    public override void DoSomething() 
    { 
     //Do something here 
    } 
} 

당신이 UserControlAUserControlB에 공통적으로 어떤 기능이있는 경우가 BaseUserControl을 유지할 수 있습니다; 그렇지 않은 경우이를 제거하고 후자의 두 값을 UserControl에서 직접 파생시킵니다.

IControl 인터페이스 내의 파생 클래스에서 액세스해야하는 모든 구성원을 정의해야합니다. 여기에는 UserControl에서 상속받는 모든 회원이 포함됩니다. 그러나 구체적인 클래스 내에서 다시 구현할 필요는 없습니다.

//Interface 
public interface IControl : IComponent 
{ 
    void DoSomething(); 

    // To be inherited from UserControl. 
    Size Size { get; set; } 
    bool Focus(); 
    event EventHandler FontChanged; 
} 

는 Windows에 이러한 컨트롤을 추가해야하는 경우

Forms 응용 프로그램 - 일반적으로 Control.ControlCollection.Add 메소드 호출의 인수로 - 당신이 당신의 컨트롤에 해당하는 Control 인스턴스를 취득해야합니다. 현재 구현에서는 캐스팅을 통해 간단하게 달성 할 수 있습니다. 그러나 향후에 기본 구현을 변경하기로 결정한 경우이를 대비하여 인터페이스의 소비자로부터 격리되어야합니다. 따라서, 내가 사용합니다 :

//Interface 
public interface IControl : IComponent 
{ 
    void DoSomething(); 

    Control AsWindowsForms(); 
} 

//BaseUserControl 
public partial class BaseUserControl : UserControl, IControl 
{ 
    public BaseUserControl() 
    { 
     InitializeComponent(); 
    } 

    public virtual void DoSomething() 
    { 

    } 

    public Control AsWindowsForms() 
    { 
     return this as Control; 
    } 
} 

를 클라이언트 코드에서 :

var controlA = ControlFactory.Create("UserControlA").AsWindowsForms(); 
var controlB = ControlFactory.Create("UserControlB").AsWindowsForms(); 
panel1.Controls.Add(controlA); 
panel1.Controls.Add(controlB); 
+0

+1에 대한 AsWindowsForms() 통찰력 – radarbob

관련 문제