首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >面向对象设计-基因组类/变异类

面向对象设计-基因组类/变异类
EN

Software Engineering用户
提问于 2019-07-25 14:02:19
回答 3查看 331关注 0票数 2

上下文

我正在和我的朋友争论如何开始实现一种叫做called (增强拓扑的NeuroEvolution)的遗传算法。

方法1

我赞成有两个类别,一个是基因组类,一个是突变类。这种突变类将提供突变基因组的方法,方法是以基因组为输入,并返回突变的基因组。此外,该实现还将为每个过程设置类,如选择、交叉等。

Pros

  • 这样,我们以后就可以选择从突变类中派生出各种类型的突变。
  • 我认为它也将有助于更好的单元测试。

Cons

  • 更多的课程
  • 不模拟真实生活(例如,人类可以像基因组突变一样行走)

方法2

我的朋友只想有一个类别,基因组类。在这个实现中,突变将是基因组类的一种方法,它将返回一个突变的基因组作为输出。

Pros

  • 这将有助于降低复杂性。
  • 它还将模拟一个基因组可以变异,就像人类可以行走一样。
  • 它还将遵循惯例(从已经实现的解决方案中看到代码)。

Cons

  • 因此,较少的分离关注,更难的单元测试。
  • 当需要添加不同种类的突变时,以后很难扩展。
EN

回答 3

Software Engineering用户

回答已采纳

发布于 2019-07-26 03:34:00

我还有第三种选择:基因组就是数据。不过,让我先谈谈你的利弊。

关于方法1的

这样,我们以后就可以选择从突变类中派生出各种类型的突变。

您正在考虑从突变类派生的想法向我表明,您希望基因组对象接受一个突变对象(强迫您传递突变类的对象或派生的对象)。

那里面什么?Genome类可以将数据传递给突变类,以便为新实例创建数据,然后由Genome类创建数据。如果你这么做,基因组和突变是紧密耦合的。

在这里,接口IMutation会更好吗?也许吧。然而,问题的根源不是产生不同的突变,而是突变需要在基因组中的数据上工作。如果不改变突变(或IMutation ),就很难改变基因组的实现细节。

我认为它也将有助于更好的单元测试。

接口将更好地用于单元测试。

更多的课程

不要担心课程的数量。担心单一责任原则和耦合。

如果你需要更多的课程,那就这样吧。

不模拟现实生活(例如,人类可以像基因组突变一样行走)

我认为这并不重要。

这并不是说适度的现实是没有用的。它很有用,它使代码更容易理解,从而更易于维护。然而,当建模现实变得与维护适得其反时,请不要再担心现实了。

关于方法二的

这将有助于降低复杂性。

阿格里,是的。较少的移动部件意味着较少的复杂性。这也意味着更难测试和维护。在这种情况下,我仍然认为它是专业的。

它还将模拟一个基因组可以变异,就像人类可以行走一样。

这更像是一种哲学观点:你正在分配基因组代理。他们还活着吗?

好吧,我们不要去那里。从计算机科学的角度来看,基因组是一系列属性。当我们使用遗传算法来进化--例如,汽车的设计--时,这并不是模拟现实。

另外..。建模现实并不是最重要的。

它还将遵循惯例(从已经实现的解决方案中看到代码)。

这是有原因的。突变需要访问基因组的数据。如果将突变代码放入基因组类中,则不必中断封装或具有紧密耦合的类。

拥有数据的行为是OOP的方式。如果您的目标是坚持OOP,请遵循此方法。

我建议的第三种方法

有一种有价值的基因组类型。如果可以,将遗传算法实现为模板/泛型类型。需要一个TGenome和一个IMutation<TGenome>之类的.

有一个运行算法的类。它不需要知道基因组是如何表示的。你用变异来初始化它。把它想象成一个战略模式。你可以实现对不同类型的基因组有效的突变。

它很容易测试。它使代码完全解耦。

事实上,如果你能执行它,让它的基因组是不可变的!(它是不变的)。突变实际上会产生一个副本。它将是"ImperfectClonation“。除了使用接口之外,使用不可变类型还可以帮助您进行测试。

封装?看:物体是一种思维方式。他们很适合模拟现实。然而,有时这并不是最佳的工作工具。如果没有真的,其他编程范例就不会兴旺发达。

值类型具有对象一般不具备的其他优点。其中之一是跨系统移动它们的方便性。它们很容易序列化、通过网络发送或承诺永久存储。

如果您正在创建一个库,您不知道开发人员需要在哪种类型的属性上运行遗传算法。这个选项提供了多功能性。

不过,想想吧。也许不是TGenome,而是TGene[]

票数 2
EN

Software Engineering用户

发布于 2019-07-25 15:05:22

在方法1中,您可以应用策略模式来支持不同类型的变异。

康氏多类

这并不是真正的缺点。类组织实例成员。在这两种方法中,您可能有相同数量的实例成员。我们不应该以合并概念为代价来最小化类。

缺点不模拟现实生活(例如,人类可以像基因组突变一样行走)

我们通常不试图直接使用类来“模拟现实生活”。我们试图在整个系统中建模所需的概念、它们的关系和行为,但不想用类来建模现实生活1:1 --考虑到我们的一些编程语言不支持多重继承,而“现实生活”生物学确实支持多重继承(即父母),但我们仍然可以对使用这些编程语言所需的任何东西进行建模。

在方法2中,你可以应用子类来覆盖突变行为。这表明基因组的实例和它们的突变之间存在" is -a“关系,我会说这是假的。因为在大多数语言中,我们不能改变实例的类,所以必须将基因组克隆到另一个类中才能应用不同的突变。(这是可行的,但看起来像不必要的复杂性)。

专业人士这将有助于降低复杂性。

软件中的一切都只能在一个类中完成,但这并不能降低复杂性。

专业人士它还将模拟一个基因组可以变异,就像人类可以行走一样。

你需要能够变异基因组,但这不一定需要自我变异的基因组。

让我们考虑一下生命周期。基因组类的有用性/实用性很可能独立于突变。突变可以暂时应用,但基因组可能会在软件中的许多其他场景中使用,而不会与突变能力相关。在这里,我指的是其他消费者,以及他们是否也需要突变。

如果有任何与突变相关的状态,那么两种不同的生命周期被合并在一起似乎是双重的。每当我们在实例字段中有不同的生命周期时,这就意味着将多个概念分开。

命名事物很难。在方法1中,我认为另一个名称可能更适合突变。它是一种突变种类、方法、原因或策略,而不是突变本身。“突变”一词在口语上是指将突变原因(对基因组)应用的结果。

票数 5
EN

Software Engineering用户

发布于 2019-07-25 20:17:07

方法2是基于最基本的面向对象原则的默认设计,即行为应该驻留在数据所在的位置。它也是最可维护的,最简单的。

所以,我会继续,直到方法1是绝对需要的。你可以稍后再重构。因此,首先采用最简单的设计,只有在获得即时利益的情况下,才会引入间接/分离。

票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/395196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档