我可以调用执行类似功能的不同类(具有不同的方法和类型)吗?

发布于 2024-10-16 01:45:20 字数 1421 浏览 1 评论 0原文

我有很多方法(在本例中,来自网络服务,但这可能没有影响?)可以调用。它们已经是固定的发布版本并且不会改变,由我来适应它们。我的项目中已经有了代理,事实上,我已经调用了它们,并且项目正常。

该类的 main 方法获取一些输入参数(交易类型和包含交易数据的 XML 字符串)。基于TransactionType,我知道我应该调用哪个类和方法。我还必须为其提供一个它期望的类型变量,该变量已经从提供的 XML 构建。今天的情况是这样的(我这里没有代码,所以请原谅我的任何语法错误),大约是:

public class MyClass ()
{
  public void MyMethod( string TransactionType, string XML )
  {
    switch( TransactionType ) {
       case "1":
         type1VO type1Object = ( new Deserializer<Type1>() ).XML2Object( XML );
         ws = new WSProxy1();
         string response = ws.Method1( type1VO );
         //
         // lots of other lines of code that use type1VO, type1Object, the response, etc.
         //
         break;
       case "2":
         type2VO type2Object = ( new Deserializer<Type2>() ).XML2Object( XML );
         ws = new WSProxy2();
         string response = ws.Method2( type2VO );
         //
         // same structure here, but handling types specific for "case 2"
         //
         break;
    }
    ...
  }
}

并且它会继续下去。今天,这段代码已经可以运行,可以处理大约 15 种不同的交易类型,但它是按照上面看到的方式开发的。当我即将更改它时(将此代码移至其自身的库,因为其他系统需要此逻辑),我认为它可以从一些代码细化中受益。另外,上面的代码相当减少:有更多的行来处理每种情况的特定类型,我只是举了一个例子。

由于它正在工作,我并不那么担心,但它对我来说似乎并不那么“优雅”。给我的印象是某种设计模式可以处理这个问题,并且我可以使用单个块处理任何交易,而不是对每种交易类型重复它。也许我错了,这是不可能做到的,我只是通过查看重复代码“感觉”它可以。

它是 .NET v2.0 上的 C#,但我不介意是否有涉及其他版本或语言的答案。我更关心其中涉及的概念。我感谢你们提供的任何提示,它们总是很棒。

I have a lot of methods (in this case, from web services, but maybe this has no impact?) to call. They're already fixed release versions and won't be changed, it's up to me to adapt to them. I already have the proxies on my project, and in fact, I already call them and the project is ok.

This class main method gets some input parameters (transaction type, and a XML string containing the transaction data). Based on TransactionType, I know which class and method I should call. I also must provide it with a type variable it expects, already built from the provided XML. Here's how it is today (I don't have the code right here, so pardon me for any syntax errors), approximately:

public class MyClass ()
{
  public void MyMethod( string TransactionType, string XML )
  {
    switch( TransactionType ) {
       case "1":
         type1VO type1Object = ( new Deserializer<Type1>() ).XML2Object( XML );
         ws = new WSProxy1();
         string response = ws.Method1( type1VO );
         //
         // lots of other lines of code that use type1VO, type1Object, the response, etc.
         //
         break;
       case "2":
         type2VO type2Object = ( new Deserializer<Type2>() ).XML2Object( XML );
         ws = new WSProxy2();
         string response = ws.Method2( type2VO );
         //
         // same structure here, but handling types specific for "case 2"
         //
         break;
    }
    ...
  }
}

And it goes on and on. Today, this code is already working, handling about 15 different transaction types, but it was developed in the way you see above. As I'm about to change it (will move this code to a library of itself, 'cause other systems need this logic), I thought it could benefit from some code refinement. Also, the above code is pretty reduced: there are more lines that handle the specific types for each case, I just gave an example.

As it's working, I'm not so worried, but it doesn't seem so "elegant" to me. Gives me the impression that some kind of design pattern could handle this, and that I could handle any transaction with a single block, instead of repeating it for every transaction type. Maybe I'm wrong and this can't be done, I just "felt" it could by looking at the repeating code.

It's C# on .NET v2.0, but I don't mind if there are answers involving other versions or languages. I care much more about the involved concept. I thank you all for any hints you could provide, they're all always great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

静水深流 2024-10-23 01:45:20

您可以尝试结合使用适配器模式策略模式

创建一个用于调用该方法的接口,并为支持该接口的每个代理编写适配器。适配器应该封装特定于它所适应的对象的任何行为。您还可以让接口返回它们支持的事务类型,以在运行时启用切换。

一个例子可能是:

public interface IExecuteStrategy
{
    string TransactionType {get;}
    void Execute( string xmlData );
}

public class WsProxy1Adapter : IExecuteStrategy
{
    public string TransactionType
    {
        get { return "1"; }
    }

    public void Execute(string xmlData)
    {
        Type1 type1Object = ( new Deserializer<Type1>() ).XML2Object( XML );
        var ws = new WSProxy1();
        string response = ws.Method1( type1Object );
        //
        // lots of other lines of code that use type1VO, type1Object, the response, etc.
        //
    }
}

public class WsProxy2Adapter : IExecuteStrategy
{
    public string TransactionType
    {
        get { return "2"; }
    }

    public void Execute(string xmlData)
    {
        Type2 type2Object = ( new Deserializer<Type2>() ).XML2Object( XML );
        var ws = new WSProxy2();
        string response = ws.Method1( type2Object );
        //
        // lots of other lines of code that use type1VO, type1Object, the response, etc.
        //
    }
}

public class MyClass
{
    private static Dictionary<string, IExecuteStrategy> _transactionHandlers;

    static MyClass()
    {
        _transactionHandlers = new Dictionary<string,IExecuteStrategy>();

        IExecuteStrategy obj = new WsProxy1Adapter();
        _transactionHandlers.Add(obj.TransactionType, obj);

        obj = new WsProxy2Adapter();
        _transactionHandlers.Add(obj.TransactionType, obj);
    }


    public void MyMethod( string TransactionType, string XML )
    {
        _transactionHandlers[TransactionType].Execute( XML );
    }
}

You can try a combination of the Adapter Pattern and Strategy Pattern.

Create an interface for calling the method and write adapters for each of your proxies that support this interface. The adapters should encapsulate any behavior that is specific to the object it is adapting. You can also have the interface return the transaction type that they support to enable switching at runtime.

An example might be:

public interface IExecuteStrategy
{
    string TransactionType {get;}
    void Execute( string xmlData );
}

public class WsProxy1Adapter : IExecuteStrategy
{
    public string TransactionType
    {
        get { return "1"; }
    }

    public void Execute(string xmlData)
    {
        Type1 type1Object = ( new Deserializer<Type1>() ).XML2Object( XML );
        var ws = new WSProxy1();
        string response = ws.Method1( type1Object );
        //
        // lots of other lines of code that use type1VO, type1Object, the response, etc.
        //
    }
}

public class WsProxy2Adapter : IExecuteStrategy
{
    public string TransactionType
    {
        get { return "2"; }
    }

    public void Execute(string xmlData)
    {
        Type2 type2Object = ( new Deserializer<Type2>() ).XML2Object( XML );
        var ws = new WSProxy2();
        string response = ws.Method1( type2Object );
        //
        // lots of other lines of code that use type1VO, type1Object, the response, etc.
        //
    }
}

public class MyClass
{
    private static Dictionary<string, IExecuteStrategy> _transactionHandlers;

    static MyClass()
    {
        _transactionHandlers = new Dictionary<string,IExecuteStrategy>();

        IExecuteStrategy obj = new WsProxy1Adapter();
        _transactionHandlers.Add(obj.TransactionType, obj);

        obj = new WsProxy2Adapter();
        _transactionHandlers.Add(obj.TransactionType, obj);
    }


    public void MyMethod( string TransactionType, string XML )
    {
        _transactionHandlers[TransactionType].Execute( XML );
    }
}
我的黑色迷你裙 2024-10-23 01:45:20

您应该创建一个抽象类来了解处理事务类型的基本流程。然后为每种交易类型创建一个子类,用于填充特定于类型的代码。根据您提供的代码,这可能是您的基类的开始:

abstract class Base<T, U>
{
  private U _obj;
  public Base(string xml)
  {
    _obj = (new Deserializer<T>()).XML2Object(xml);
  }

  public abstract void process();
  protected abstract String getResponse();
}

然后创建一个简单的工厂以根据事务类型返回正确的子类。然后,这允许您的大型案例声明变成这样:

public void MyMethod(string transactionType, string xml)
{
    Base.getByTransactionType(transactionType).process();
}

You should make an abstract class that understands the basic flow how you work on a transaction type. Then make a child class for each transaction type, that fills in the type specific code. This could be a start to your base class based on the code you gave:

abstract class Base<T, U>
{
  private U _obj;
  public Base(string xml)
  {
    _obj = (new Deserializer<T>()).XML2Object(xml);
  }

  public abstract void process();
  protected abstract String getResponse();
}

Then make a simple factory to return the correct child class based on the transaction type. This then allows your large case statement into something like this:

public void MyMethod(string transactionType, string xml)
{
    Base.getByTransactionType(transactionType).process();
}
ゝ杯具 2024-10-23 01:45:20

看看策略模式。
策略模式

Take a look at the strategy pattern.
Strategy Pattern

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文