2012-04-23 3 views
0

나는 매우 기본적인 질문을 가지고있다.단순한 다형성을 구현하는 방법을 찾는

일부 다형성을 시도하고 있습니다.

Public interface Iplugin 
{ 

    void doSomthing(string _str); 
} 

나는 또한 내가 메인 클래스가

public class plugin1:Iplugin 
{ 
    void doSomthing(string _str) 
    { 
     if (_str=="1") 
     { 
      // do somthing 1 
     } 
    } 
} 

public class plugin2:Iplugin 
{ 
    void doSomthing(string _str) 
    { 
     if (_str=="2") 
     { 
      // do somthing 2 
     } 
    } 
} 

public class plugin3:Iplugin 
{ 
    void doSomthing(string _str) 
    { 
     if (_str=="3") 
     { 
      // do somthing 3 
     } 
    } 
} 

그래서이 인터페이스를 implament 일부 플러그인 클래스를 가지고 있고 그것은 모두를 호출 할 수 싶습니다

는이 같은 인터페이스 봐 플러그인

그러나 OCP (Open-Closed Principle)를 저장하고 싶습니다. 앞으로 다른 플러그인 클래스를 추가하면 기본 클래스가 변경되지 않습니다.

이것은 당신은 당신의 플러그인을 저장하는 컬렉션을 추가 할 수 있습니다 메인 클래스

public class mainApp 
{ 
    Iplugin _context; 
    mainApp() 
    { 
    _context= new //new what?? 
    } 
    bool func(string str) 
    { 
     _context.doSomthing(str);//I would like it to invoke all the plug in and also a future plugins that I will add 
    } 
} 
+4

진짜 질문이 무엇인지 잘 모르시겠습니까?당신은 분명히 거기에 상속을 필요로하고 do something something virtual? – Ian

+0

플러그인을 만드는 것은 간단한 프로그래밍 작업이 아니며, 종종 많은 표준 사례를 따르지 않거나 따르지 않는 이유입니다. 프로그래밍에 대해 배워보기 위해 예제를 찾으려는 사람이라면 적어도 지금은 플러그인을 사용하지 않는 것이 좋습니다. 이것이 학문적 인 운동이 아니라면 나를 무시해도 좋습니다. – Servy

답변

0

여러분 모두 도와 주셔서 감사합니다.

나는 모든 조언을하고 난 다음 않았다

namespace Plugins 
{ 




public class plugin1 : Iplugin 
    { 
    void doSomthing(string _str) 
    { 
     if (_str == "1") 
     { 
      // do somthing 1 
     } 
    } 


} 

public class plugin2 : Iplugin 
{ 
    void doSomthing(string _str) 
    { 
     if (_str == "2") 
     { 
      // do somthing 2 
     } 
    } 


} 

public class plugin3 : Iplugin 
{ 
    void doSomthing(string _str) 
    { 
     if (_str == "3") 
     { 
      // do somthing 3 
     } 
    } 


} 
} 

그래서이 모든 플러그인의 주요 응용 프로그램

namespace Factory 
{ 
    public interface Iplugin 
    { 

    void doSomthing(string _str); 
    } 



class Program 
{ 
    static void Main(string[] args) 
    { 
     string @namespace = "Plugins"; 

     var q = from t in Assembly.GetExecutingAssembly().GetTypes() 
       where t.IsClass && t.Namespace == @namespace 
       select t; 
     q.ToList(); 

     List<Iplugin> myList = new List<Iplugin>(); 
     foreach (var item in q) 
     { 
      Iplugin temp=(Iplugin)Activator.CreateInstance(item); 
      myList.Add(temp);// a list with all my plugins 

     } 

     foreach (var item in myList) 
     { 
      item.doSomthing("string"); 

     } 

    } 
} 

}

지금

와 이름 공간
1

입니다. 컬렉션은 한 곳에서 채워질 수 있으며, 모든 플러그인을 반복하고 호출하는 다른 메소드로 전달 될 수 있습니다. 이렇게하면 컬렉션에있는 플러그인의 유형과 완전히 독립적입니다.

그리고 언급 한대로 doSomthingvirtual을 적절하게 작동시켜야합니다.

public class mainApp 
{ 
    mainApp() 
    { 
    List<Iplugin> plugins = new ArrayList<Iplugin>; 

    ... 

    plugins.add(new plugin1()); 
    ... 
    plugins.add(new plugin3()); 
    ... 
    func(plugins, "1"); 
    ... 
    func(plugins, "7"); 
    } 

    bool func(List<IPlugin> plugins, string str) 
    { 
    foreach (IPlugin plugin in plugins) { 
     plugin.doSomthing(str); 
    } 
    } 
} 

이 다형성의 한 잘 알려진 응용 프로그램입니다 Dependency Injection의 단순한 예이다 (물론, 다른 클래스로 func을 넣어한다, 그것은 실제 DI 만들기 위해). 코드의 유연성을 높이고 플러그인 생성을 사용 방법에서 분리하려면 다음과 같이 사용할 수 있습니다. Factory Method 또는 Builder.

2

특정 Iplugin을 만들려면 구현 유형을 알아야합니다. Factory Pattern을보십시오.

2

이런 경우에는 Factory Pattern을 사용하고 싶습니다. 당신은 쉽게 이제 공장 초기 속성에 대한 모든로드 된 어셈블리 및 검색의 모든 클래스를 확인하고 유형과 플러그인 문자열 식별자를 저장 가능한 플러그인

[PluginAttribute("myPlugin")] 
class MyPlugin : IPlugin 

의 저장소를 구축하는 몇 가지 특성 및 반사 마법이 결합 할 수 있습니다 사전에.

class PluginFactory 
{ 
    static Iplugin CreatePlugin(string aName) 
    { 
     return Activator.CreateInstance(sRegisteredPlugins[aName]); 
    } 

    private static Dictionary<string, Type> sRegisteredPlugins; 
} 
+0

안녕하세요, PluginAttribute가 필요한 이유는 무엇입니까? 무엇을 넣어야합니까? – MoShe

+0

@MoShe 저는이 속성을 사용하여 공장의 수업을 표시합니다. 그런 식으로 공장은 모든로드 된 어셈블리의 각 클래스를 확인하고 IPlugin 인터페이스를 구현하고 속성이 있는지 확인해야합니다. 추상 플러그인은 인터페이스 만 가질 수 있지만 속성을 가져서는 안됩니다. 둘 다 true이면 속성의 이름과 유형이 사전에 저장됩니다. 물론 Péter Töröks의 대답처럼 손으로 등록 방법을 만들 수도 있습니다. 그러나 나는이 자동적 인 방법을 선호한다. – dowhilefor

+0

내 대답에 대해 어떻게 생각하세요? 나는 그것이 ocp를 저장한다고 생각한다 – MoShe

관련 문제