Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将不同操作委托给不同类的设计模式_Java_Design Patterns - Fatal编程技术网

Java 将不同操作委托给不同类的设计模式

Java 将不同操作委托给不同类的设计模式,java,design-patterns,Java,Design Patterns,我有一个类ABC,它可以执行操作a()、b()和c()(操作==方法),这些都是密切相关的。我也有simimar的DE和FGH课程。将来,可能会添加带有附加操作的新类。类从不共享操作(例如,没有类ADF) 我的程序应该能够执行所有这些操作,并且计时是“一种随机的”,这意味着我事先不知道什么时候/多少次执行哪个操作 我通过创建一个包装类“OperationInvoker”来解决这个程序。我的程序只能访问这个调用程序,并且每个操作都有一个方法。这样做的好处是封装:如果创建或编辑了新操作或现有操作,则

我有一个类ABC,它可以执行操作a()、b()和c()(操作==方法),这些都是密切相关的。我也有simimar的DE和FGH课程。将来,可能会添加带有附加操作的新类。类从不共享操作(例如,没有类ADF)

我的程序应该能够执行所有这些操作,并且计时是“一种随机的”,这意味着我事先不知道什么时候/多少次执行哪个操作

我通过创建一个包装类“OperationInvoker”来解决这个程序。我的程序只能访问这个调用程序,并且每个操作都有一个方法。这样做的好处是封装:如果创建或编辑了新操作或现有操作,则只需编辑包装器类

我的问题是“巨大”包装器是否是解决此问题的最佳模式

我研究了观察者模式,我认为这不是一个合适的情况,因为类ABC,DE,FGH。。。从来没有任何共同利益。类似地,如果需要执行操作A,所有注册的类都将接收事件A,并且只有一个类(即ABC)实际对该事件感兴趣。所有其他已注册的类将放弃该事件。在所有的注册和观察过程中,这似乎是过度消耗/开销

委托模式也遇到了同样的问题:我没有很多类以不同的方式执行相同的操作,因此没有必要使用灵活的委托系统

是否还有其他更好的模式,或者这只是一个简单的委托包装器类的例子

编辑:有人问ABC到底做什么。嗯,我有一个描述soapweb服务的WSDL文件。我使用工具将此文件转换为java类。这意味着我无法控制这些类的内容,因为它们是自动生成的。因此,我编写了一个类WebServiceInvoker,它充当这些web服务的包装器。这个包装类有3个方法:DoWebServiceA、DoWebServiceB和DoWebServiceC

随着程序的扩展,越来越多的wsdl文件进入画面。当然,没有一个web服务做同样的事情。它们没有全部捆绑在一个大的wsdl文件中的唯一原因是,某些web服务在逻辑上不属于其他web服务。因此,我将学习以下课程:

  • 可以调用web服务A、B和C的包装器类
  • 一个可以调用web服务D,E
  • 可以调用webservice F、G和H的包装器类

将来可能会出现更多的wsdl(从而出现包装类)。在所有其他包装器周围都有一个附加包装器的原因是,每个服务都需要使用“会话id”进行调用。所以每个包装器都需要知道这些信息。因此,超级包装器保存这些信息,并可以调用所有web服务。这也是一个非常好的api:使用web服务的程序对服务一无所知,它只有一个公共方法可通过superwrapper用于每个web服务。程序当然知道每个web服务返回的内容(列表、字符串、nothing…。

为了便于代码维护,我建议将包装更改为以下内容:

public class Operations {
    private ABC abcInst;
    private DE deInst;
    private FGH fghInst;

    protected Operations(ABC abc, DE de, FGH fgh) {
        this.abcInst = abc;
        this.deInst = de;
        this.fghInst = fgh;
    }

    public ABC getABC() { return abcInst; }
    public DE getDE() { return deInst; }
    public FGH getFGH() { return fghInst; }
}

这样,这里就不需要维护(除非添加了一个新类),来自调用方的所有调用只需要额外的
.getABC().a()
,而不是
.a()
等。它强调操作由不同的类执行,但仍然允许通过传递
操作
-实例来访问所有功能。

看起来您有一个明确的体系结构,您试图避免泄漏到其他组件中。避免这种泄漏的自然方法是再增加一个分离度

本质上,如果你喜欢,你仍然可以保留一个巨大的包装,但是你需要考虑你想要暴露的东西,并且仅仅暴露它。看起来您想要公开的只是一个已知操作的列表,那么下面的内容怎么样:

// Your setup - trimmed down.
interface ABC {

    public void a();

    public void b();

    public void c();
}

interface DE {

    public void d();

    public void e();
}

interface FGH {

    public void f();

    public void g();

    public void h();
}

// Your current wrapper.
class AllOps {

    public ABC getABC() {
        return null;
    }

    public DE getDE() {
        return null;
    }

    public FGH getFGH() {
        return null;
    }
}

// One further degree of separation.
enum Op {

    A {

                @Override
                void op() {
                    ops.getABC().a();
                }

            },
    B {

                @Override
                void op() {
                    ops.getABC().b();
                }

            },
    C {

                @Override
                void op() {
                    ops.getABC().c();
                }

            },
    D {

                @Override
                void op() {
                    ops.getDE().d();
                }

            },
    E {

                @Override
                void op() {
                    ops.getDE().e();
                }

            },
    F {

                @Override
                void op() {
                    ops.getFGH().f();
                }

            },
    G {

                @Override
                void op() {
                    ops.getFGH().g();
                }

            },
    H {

                @Override
                void op() {
                    ops.getFGH().h();
                }

            };
    // Hide the huge wrapper.
    private static AllOps ops = new AllOps();
    // Only expose the operations.
    abstract void op();
}

public void test() {
    Op.A.op();
    Op.F.op();
}
不确定这将是什么模式,但如果您只公开枚举,我认为您已经实现了断开连接


可以添加其他操作作为新枚举,以任何方式实现
op
。他们甚至可能不使用巨大的包装器。

您想抽象出ABC和DE是由不同对象提供的这一事实吗?如果是这样,一个包装似乎不错。如果客户机知道ABC和DE是分开的,那么为什么不将它们传入(构造函数注入),可能是通过接口IABC和IDE?所有操作都需要一个共享参数:调用操作的用户的名称。包装器类似乎是存储此用户名的理想场所。我真的不需要我的程序不知道ABC和De是否是分开的,但我认为这也没有什么坏处(关注点的分离)。在我看来,ABC、De和FGH类做的事情非常不同。那么,共享处理真的有用吗?假设你有汽车、房子和比萨饼的课程。把它们一起处理是个好主意吗?或者,如果只区分类并单独处理每个类,会更容易吗?嗯,就我的想法。另一种可能适合的模式是使用代理,甚至可能是代理。@Korashen:每个操作都是一个web服务。每个web服务都有一个共享部分(创建soap主体,添加连接参数…),但每个都有很大的不同(有些返回真/假,有些有更复杂的响应,有些可能抛出错误…)。他们应该一起处理吗?在allOps类中,返回ABC以便调用方可以执行ABC.a()比在allOps中提供调用ABC.a()本身的方法a()有什么好处?@user1884155-根本没有-代码旨在