Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.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

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_Constructor - Fatal编程技术网

Java 一种面向构造函数的设计模式

Java 一种面向构造函数的设计模式,java,design-patterns,constructor,Java,Design Patterns,Constructor,我受到了一个设计问题的挑战,我将在下面描述这个问题 假设一个类(称为a)有一个带有一组参数的构造函数。由于在每个实例化中编写所有这些参数既累又脏,我编写了另一个类,称之为StyleSheetA,它封装了所有这些参数,是A的构造函数的唯一参数。这样,我可以准备一些默认StyleSheetA模板供以后使用,如果需要,我可以修改它们 在这一点上,我需要扩展A。假设B扩展A。B将有自己的样式表,即样式表B。我认为StyleSheetB扩展StyleSheetA是合适的,因此使用一个stylesheet参

我受到了一个设计问题的挑战,我将在下面描述这个问题

假设一个类(称为a)有一个带有一组参数的构造函数。由于在每个实例化中编写所有这些参数既累又脏,我编写了另一个类,称之为StyleSheetA,它封装了所有这些参数,是A的构造函数的唯一参数。这样,我可以准备一些默认StyleSheetA模板供以后使用,如果需要,我可以修改它们

在这一点上,我需要扩展A。假设B扩展A。B将有自己的样式表,即样式表B。我认为StyleSheetB扩展StyleSheetA是合适的,因此使用一个stylesheet参数,B的构造函数也可以构造它的超类A。但是我担心这种设计可能有缺陷。例如,如果我决定为样式表添加一个getter/setter,该怎么办?有没有一种新颖的方法来处理所有这些情况?我错了吗?对于那些感到困惑的人,我在此附上一些代码:


    class A
    {
        StyleSheetA ss;

        A(StyleSheetA ss)
        {
            this.ss = ss;
            // Do some stuff with ingredients of styleSheet
        }
    }
    class StyleSheetA
    {
        int n1;
        int n2;
        // :
        // :
        int n100;
    }

    class B extends A
    {
        B(StyleSheetB ss)
        {
            super(ss);
            // Do some stuff with ingredients of styleSheet
        }
    }
    class StyleSheetB extends StyleSheetA
    {
        int n101;
        int n102;
        // :
        // :
        int n200;
    }
谢谢你的帮助或建议,任何批评你的人都将不胜感激


编辑:我使用java me开发,因此没有泛型支持。

您是否考虑过使用IoC容器(如StructureMap)来管理构造函数依赖关系?这可能会使这些东西变得更容易。

在我看来,您只是将参数过多的问题从class
a
转移到class
StyleSheetA

为了说明我的观点,想一想这个问题:您将如何实例化
StyleSheetA
?无论如何,可能使用接受所有这些参数的构造函数。此设计可能给您带来的唯一好处是,如果您拥有一组由
样式表a
对象封装的相同参数值,您将在
a
的多个实例中重用这些参数值。如果是这样的话,请记住,尽管有不同的
A
实例,但它们共享相同的参数,因此这不是一个好的选择

我建议您尝试重构类
A
本身。试着把它分成几个小班。如果需要,尝试创建子类以避免条件分支等


现在,我不知道你的类
A
是什么样子,但是如果你这样做的话,你可能会有几个类,每个类都有自己的参数集。如果其中任何一个参数是一个鉴别器(意味着它决定了类的“类型”),您将能够摆脱它,只需使用子类,并依赖内置的类型系统来代替它。

关于getter和setter问题的思考:


“B”中的构造函数表示类的操作需要额外的参数(n101+)。如果您只是用一个完整的参数列表来扩展这个类,那么在
B
中就有n101…n200的getter和setter,在
a
中就有n1…n100的getter和setter。这意味着可能没有
StylesheetB
extend
StylesheetA
,而是让类B的构造函数成为
B(StylesheetA,StylesheetB)
,这样就可以在类
a
中为其参数设置一个setter,对于
StylesheetB

B
样式表,是否继承了这一点,并将其放入
B
中?人们使用IoC容器的一个主要原因是帮助简化构造函数依赖关系。相反,你可以从我这里获得投票权,我是IoC的忠实粉丝,即使它可能无法解决这个特殊的问题;)我同意@Adam的观点:否决投票而不解释是不好的。它也不能帮助任何人理解为什么答案没有帮助。它仍然只是将问题从类转移到IoC容器(不是我:)。但是,如果大多数时候对大多数参数使用一些默认值,而只对其中一些参数使用特殊值,那么这种方法可能非常有用。然后,您可以从容器中注入所有默认值,并通过setter另外设置几个不同的默认值。这确实会将问题转移到IoC,但该代码通常包含在程序入口点的一些引导配置代码中。问题的前提之一是,他制作了这些电子表格类,将所有参数封装到A和B中。通过IoC,您可以配置哪些参数与哪些类一起使用,以及这些参数是如何创建的,并让您的IoC完成这些脏活。当然,因为他使用的是Java,所以他可能不会使用StructureMap,但我相信Java有很多很好的IOC可用:)使用复合类封装一组相关参数是一种很好的做法,而且还可以提高性能(即使只是一点点)。@Morton:如果它们确实相关,那么我同意你的看法。我只是不同意仅仅为了拥有一个输入参数而不是许多输入参数而编写人工容器类。@Morten:您必须提供一些性能改进的解释或证据@Goran正确地说,这一切所做的就是将问题从A转移到StyleSheetA:参数和变量赋值的数量将保持完全相同,另外还有一个额外的任务:实例化StyleSheetA对象。也就是说,除非您将同一样式表A对象重复用于A的多个实例化,并得到一大堆可能的副作用。此外,它还产生了一个需要担心的依赖性。我认为这根本不是一个好的做法。阅读了我在写作时添加的注释后:封装相关字段是有意义的,即使只是为了清理代码。我给你这个;)调用方法不是一个固定时间操作。参数a被推到调用堆栈上,并在调用完成时释放,因此参数较少的方法性能更好。当然,要从中受益,您需要多次调用它。此外,当使用多个参数时