网站开发合同知识产权,长春制作网站定制,wordpress登录之后强制绑定邮箱,黑龙江建设网站示例问题 当我创建Java :: Geci抽象类AbstractFieldsGenerator和AbstractFilteredFieldsGenerator我遇到了一个不太复杂的设计问题。 我想强调一下#xff0c;对于某些人来说#xff0c;这个问题和设计可能看起来很明显#xff0c;但是在我最近与一位初级开发人员#xff0… 示例问题 当我创建Java :: Geci抽象类AbstractFieldsGenerator和AbstractFilteredFieldsGenerator我遇到了一个不太复杂的设计问题。 我想强调一下对于某些人来说这个问题和设计可能看起来很明显但是在我最近与一位初级开发人员我的儿子Mihály的交谈中我的文章比我的英语要好得多意识到这个话题可能仍然有价值。 无论如何。 我有这两个类字段和过滤字段生成器。 第二堂课扩展了第一堂课 abstract class AbstractFilteredFieldsGenerator extends AbstractFieldsGenerator {... 添加额外的功能同时应为具体实现提供相同的签名。 这是什么意思 这些生成器有助于使用反射为特定类生成代码。 因此他们处理的输入信息是Class对象。 字段生成器类具有一个抽象方法process() 该方法将为每个字段调用。 它是从一个实现的方法调用的该方法遍历字段并分别对每个字段进行调用。 当具体类extends AbstractFieldsGenerator并由此实现此抽象方法时它将被调用。 当更改相同的具体类以使其extends AbstractFilteredFieldsGenerator 将仅对过滤后的方法调用具体方法。 我想要一个设计以便在具体课程中唯一需要的更改是更改名称。 问题定义 类 以更抽象的方式描述相同的问题有两个抽象类A和F以便F extends A和F提供一些额外的功能。 两者都声明了具体类应实现的抽象方法m() 。 当具体的类C声明从C extends A到C extends F到C extends F时方法m()的调用应更改但类C不应有其他更改。 从类A定义的方法p()调用方法m() 。 如何设计F 这是什么问题 可以通过两种明显不同的方式来扩展A F覆盖m()使它混凝土在实施额外的功能m()并调用新的抽象方法说mx() F使用提供额外功能的版本覆盖方法p() 在上面的示例中进行过滤并调用仍然抽象的方法m() 第一种方法不能满足由具体类C实施的签名应保持相同的要求。 第二种方法将A的已经实现的功能扔到垃圾桶上并以不同的方式重新实现它。 在实践中这是可能的但是肯定会进行一些复制/粘贴编程。 这是有问题的让我不解释原因。 问题的根源 在工程中当我们面对这样的问题时通常意味着问题或结构没有得到很好的描述解决方案位于完全不同的区域中。 换句话说有些假设驱动我们的思维方式是错误的。 在这种情况下问题在于我们假设抽象类提供了一个扩展“ API”来对其进行扩展。 请注意API不仅可以调用。 对于抽象类扩展该抽象类时要实现的API。 正如库可以为不同的使用方式提供不同的APIJava 9 HTTP客户端可以send()以及sendAsync() 抽象实际上也是非抽象的类也可以提供不同的扩展方式用于不同的目的。 如果不修改A就无法编码F达到我们的设计目标。 我们需要一个A版本该版本提供不同的API来创建具体的实现而另一个版本不一定要是正交的可以创建一个仍然抽象的扩展。 在这种情况下API之间的区别在于具体实现的目标是在调用链的末尾而抽象扩展要挂接到链的最后一个元素。 A的实现必须提供要挂接到调用链的最后一个元素上的API。 这已经是解决方案。 解 我们在类F实现了方法ma() 我们希望p()调用ma()而不是直接调用m() 。 修改A我们可以做到。 我们在A定义ma() 然后从p()调用ma() p() 。 在A实现的ma()版本应毫不费力地调用m() 以为A具体实现提供原始的“ API”。 F中的ma()实现包含额外的功能在示例中为过滤然后调用m() 。 这样任何具体的类都可以扩展A或F并可以使用完全相同的签名实现m() 。 我们还避免了复制/粘贴编码只是调用m()是在ma()的两个版本中相同的代码。 如果我们希望类F具有更多抽象类可扩展性则F::ma实现不应直接调用m() 而应调用m()的新mf() m() 。 这样新的抽象类可以覆盖mf()从而再次提供新功能并调用抽象m() 。 带走 对抽象类进行编程非常复杂有时很难清楚地了解谁在调用谁以及哪种实现。 如果您意识到这可能是一件复杂的事情则可以克服这一挑战。 记录可视化讨论可以帮助您的任何方式。 当您不能解决问题时在示例中如何对F进行编码您应该挑战环境我们隐式地认为问题A的类A是不变的“如何实现F ”。 避免复制/粘贴编程。 面食包含大量CH使您的代码变胖动脉被阻塞最后应用程序的心脏将停止跳动。 尽管在本文中没有详细介绍但是请注意抽象层次越深要清楚地了解谁来呼叫谁就越困难另请参见第1点。 在https://github.com/verhas/abstractchain中找到示例演示应用程序 在https://github.com/verhas/javageci中找到具有这种模式的原始的稍微复杂的应用程序 翻译自: https://www.javacodegeeks.com/2019/06/extending-abstract-classes-with-abstract-classes-in-java.html