让我们从基础开始,关于类你必须知道的最重要的事情,子类总是超类的完整实例。因此,如果您在超类中定义字段变量,则始终在创建子类的实例时创建此字段。您可以使用 super.getVariable() 在子类中获取该变量以重用字段(类变量、字段、标志,这在 OO 编程中都是一样的)。但是您也可以只从外部调用 subclassInstance.getVariable() 并且您将获得相同的字段(无需通过子类更改它)。所以你通常根本不需要在你的子类中调用“super”,因为你通常只想从外部获取/设置它的超类(包括抽象类!)的一个字段。由于您应该始终将字段变量设置为私有,因此我始终建议不要调用“super”来访问任何字段变量(因为即使使用 super 您也可以protected
super.getField() 之类的方法,虽然很烦人但很有必要)。
现在让我们从数据模型开始:您有模型A 和模型B。您可以从超类或仅从 Object 继承它们。但是如果你只继承Object,你可以定义一个简单的(Java!)接口,并将这个接口实现到modelA和modelB中。然后您只需通过接口处理这两个类(它们都是“接口对象”并且可以通用处理)。如果您的模型C 由模型A 和模型B 组成,您只需在模型C 中使用两个模型的实例(有时也称为“取消引用”),不需要更多代码。因此,您可以选择尽可能小且简单的模型(“bean”)。基于组件的实现,这是数据结构的常用方式。
如果您有 GUI 或表单,它看起来会有所不同。您可能有很多共同的代码,并且您不想将这些代码拆分为几十个不同的类,然后将这些组件放在一个控制器/演示器类中。因此,您可以定义一个抽象类,其中包含所有共享字段/标志以及访问和更改它们的几种方法。然后,您从 formA 和 formB 中调用这些常用方法并重用代码。
集合论对你说了什么吗?你有两个圆,A 和 B,以及 A 和 B 的交集。抽象类是交集,子类 formA 和 formB 是集合差异。学习编写正确的程序……就是理解集合论。;-)
用你的话来说:Foo形式的大部分代码都在一个抽象超类Foobar中,这个类将能够处理A和B。然后你从它继承表单Foo和表单Bar,虽然C可能大部分仍然是Foobar的一个子集,但你在Bar中添加了处理C的能力,这就是设置的区别。
最后,Bar在任何时候都不会是Foo,它们都将只是Foobar。你有一些新的共享字段/标志?没问题,您将他们的代码迁移到Foobar中,您可以在两个子类中使用它!
但是,如果有一天您需要与Foo略有不同的第三个组件FooToo怎么办?没问题,让FooBarFoo成为扩展FooBar的抽象类,然后创建Foo和FooToo作为子类。最终结果将是一个类树,其中根(通常)是抽象类,叶子是真正的类,这种结构提供了代码的最大化重用(并且不会更改类名,因此您不需要更改任何其他代码已经使用Foo类)。
您说您将在您的表单(或其演示者)中实现 setter/getter?然后您还必须使用模型modelA和modelB(但没有 modelC 因为C仅用于Bar而不是Foo)。这些模型用作包装器在Foo和Bar之间传输数据。并且此数据流应由演示者控制,而不是由Foo或Bar控制。
所以你的问题最终是这样的:主持人到底是什么?实际上,presenter 是运行 GUI 组件和数据模型的代码。它是“框架”,一方面使用 GUI 组件,另一方面使用数据模型的 getter/setter。它是GUI层和数据层两层之间的中间件,甚至是不同GUI组件和不同数据模型之间的中间件。
所以通常只有两种方法可以做到这一点:没有演示者/控制器或使用它。如果没有,您将需要将大量的摆动组件代码复制粘贴到您的演示者类中。所以呢?是的,当你使用挥杆组件时,你总是已经使用 (M)VP 模式,不可能做到不同!
所以说,要创建一个框架,你需要使用组件设计,因为你想为使用你的框架的程序员提供最大的灵活性。但是生产系统与框架不同,这是许多框架程序员认为的错误。因此,如果框架程序员告诉您“基于组件的实现就是一切”,那么他可能错了。仅仅因为他正在为他的框架编写组件,这并不意味着您需要为您的演示者做同样的事情!
这就是我们开始讨论 GUI 组件与 GUI 表示的时候。可以创建“尽可能多的演示者组件”,因为您可以使用“include(...)”方法创建一个简单的 HTML 站点并从中创建数十个 PHP 站点。但我可以向你保证,基于组件的设计并不总能提高代码的可维护性!如果我可以只用一节课做某事,而且我可以做到清晰易读,我宁愿上一节课,而不是十节课。一位演示者 = 一节课,或者更具体地说:一个 GUI 框架/选项卡 = 一节课。
同样,如果您有 2 个相似的框架/标签,但它们不一样,该怎么办?将共享代码迁移到抽象类中,并创建 2 个子类,对吗?不,您首先需要考虑那些 GUI 的份额。他们有共享旗帜吗?所以将标志移动到一个抽象超类中。但他们只是表现不同吗?好吧,您只需在同一个类中实现两个不同的方法,并在需要时调用它们。这是最重要的。
用你的话来说:GUI Pres1完全使用Foo、Bar、A、B和C。并且 GUI Pres2仅在具有不同标志的情况下才属于另一个类。否则,您将设置一个标志Pres1和一个标志Pres2并在您的方法中检查此标志。由if(flag="Pres1"){} else if(flag="Pres2"){}
. 像这样,您将获得最大的灵活性和代码可重用性。
不要将 Java 类视为不灵活、不可重用、不可更改的东西。如果您是一名优秀的程序员,一旦需要,您将直观地更改程序的结构。您不需要考虑人为的概念,您只需要了解面向对象的编程模式即可。
“组件”总是意味着“带有构造函数的东西”。但是,有时您只会使用方法而不是组件来做某事!因此,如果有人告诉您“组件设计就是一切”,他会告诉您“基于构造函数的设计就是一切”。但是要创建构造函数,您需要有字段变量/标志!没有字段变量,仅仅为了它而创建一个新类完全是无稽之谈。
注意:“组件”不是方法。很明显,您将在您的 GUI 类中使用很多方法来非常容易地处理事情,所以最后您只需调用几个方法。所以不要混用组件和方法!我总是建议一个强大的面向方法的设计,因为这一切都是为了使用更少的代码行。因此,尽可能多地定义方法……但也要尽可能少地定义类/组件。