在Smalltalk中在运行时向对象添加特征

在Smalltalk中在运行时向对象添加特征,smalltalk,traits,Smalltalk,Traits,对于一个小型大学项目,我需要用Smalltalk编写一个应用程序,模拟颁奖典礼。在这里,艺术家和乐队可以被提名获奖。然而,一位艺术家也可以成为陪审团成员,为提名人投票 为了强制不在陪审团中的艺术家不能投票,我想在每个艺术家对象加入陪审团后,动态地为他们添加一个特征。这就允许我适当地处理方法类 我现在的问题是,是否可以动态地向对象添加特征?我已经看过了,但不是我真正想要的 问候 更新1 在类端添加该方法后,这就起作用了。然而,当我希望指派一位艺术家担任陪审团成员时,我会写下如下内容: kurt_c

对于一个小型大学项目,我需要用Smalltalk编写一个应用程序,模拟颁奖典礼。在这里,艺术家和乐队可以被提名获奖。然而,一位艺术家也可以成为陪审团成员,为提名人投票

为了强制不在陪审团中的艺术家不能投票,我想在每个艺术家对象加入陪审团后,动态地为他们添加一个特征。这就允许我适当地处理方法类

我现在的问题是,是否可以动态地向对象添加特征?我已经看过了,但不是我真正想要的

问候

更新1 在类端添加该方法后,这就起作用了。然而,当我希望指派一位艺术家担任陪审团成员时,我会写下如下内容:

kurt_cobain juryMemberOf: aJury.
然后在方法
juryMemberOf
中,我将(投票)艺术家添加到列表中(以跟踪他所属的所有陪审团成员):

当我检查juryList时,我确实看到我在列表中添加了VotingArtister对象。但是,我工作区中的原始艺术家对象尚未更改为VotingArtist。不确定这是否可行,但稍后我需要具备以下能力:

kurt_cobain votesFor: justin_bieber.
此时,我收到了一条
消息NotUnderstanding
,用于方法
votesFor
,这很正常,因为kurt_cobain仍然是一个艺术家的对象。

这很不正常。您的问题可以通过使用经典继承来解决(因为这是家庭作业,所以我在这里不打算详述)。拥有投票权的艺术家只是一个子类或
artist
。当您想要授予艺术家投票权时,请更改类别,例如,
VotingArtist from:self
,其中
VotingArtist
artist
的子类<代码>#from:可以实现为

VotingArtist class>>from: anArtist
    ^ self new copyFrom: anArtist
那太不像话了。您的问题可以通过使用经典继承来解决(因为这是家庭作业,所以我在这里不打算详述)。拥有投票权的艺术家只是一个子类或
artist
。当您想要授予艺术家投票权时,请更改类别,例如,
VotingArtist from:self
,其中
VotingArtist
artist
的子类<代码>#from:可以实现为

VotingArtist class>>from: anArtist
    ^ self new copyFrom: anArtist
那太不像话了。您的问题可以通过使用经典继承来解决(因为这是家庭作业,所以我在这里不打算详述)。拥有投票权的艺术家只是一个子类或
artist
。当您想要授予艺术家投票权时,请更改类别,例如,
VotingArtist from:self
,其中
VotingArtist
artist
的子类<代码>#from:可以实现为

VotingArtist class>>from: anArtist
    ^ self new copyFrom: anArtist
那太不像话了。您的问题可以通过使用经典继承来解决(因为这是家庭作业,所以我在这里不打算详述)。拥有投票权的艺术家只是一个子类或
artist
。当您想要授予艺术家投票权时,请更改类别,例如,
VotingArtist from:self
,其中
VotingArtist
artist
的子类<代码>#from:可以实现为

VotingArtist class>>from: anArtist
    ^ self new copyFrom: anArtist

不要从向对象添加行为的角度来考虑问题。考虑一下你将如何使用这种行为

在代码中的某个时刻,您需要说

kurt_cobain votesFor: justin_beiber    "How is this even possible?"
在这个时候,你怎么知道kurt_cobain是一个能够投票的对象?您是否需要首先测试是否是这种情况

kurt_cobain canVote ifTrue: [kurt_cobain votesFor: justin_beiber]
如果你在任何地方都这样做,你就一直在有效地进行类测试。类测试是一种代码气味,表明您缺少对象

请考虑使用VoTrink艺术家的建议。无论何时你使用一个投票艺术家,你都会知道你在谈论一个可以投票的人。没有必要测试这个类。投票艺术家将引用该艺术家,还可以跟踪该投票艺术家提名或投票给谁。也许这个活动有一批艺术家和另一批艺术家。你永远不会要求一位艺术家投票,也不会要求一位投票艺术家表演。然而,投票艺术家可以引用艺术家


所以,现在的问题是,这位艺术家是否应该回应与这位艺术家相同的信息?在你希望使用艺术家的情况下,你会使用一个VotingArtist吗?答案很可能是否定的。一位投票艺术家投票并提名。艺术家演奏音乐。如果您想发送与表演音乐相关的消息,并且您知道您有一位VotingArtist,只需向VotingArtist询问其艺术家,并将其用于表演音乐行为。VotingArtist和Artist之间可能根本没有行为重叠,所以甚至没有子类关系。如果两者都不能互换使用,那么两者之间就不需要层次关系。

不要考虑向对象添加行为的问题。考虑一下你将如何使用这种行为

在代码中的某个时刻,您需要说

kurt_cobain votesFor: justin_beiber    "How is this even possible?"
在这个时候,你怎么知道kurt_cobain是一个能够投票的对象?您是否需要首先测试是否是这种情况

kurt_cobain canVote ifTrue: [kurt_cobain votesFor: justin_beiber]
如果你在任何地方都这样做,你就一直在有效地进行类测试。类测试是一种代码气味,表明您缺少对象

请考虑使用VoTrink艺术家的建议。无论何时你使用一个投票艺术家,你都会知道你在谈论一个可以投票的人。没有必要测试这个类。投票艺术家将引用该艺术家,还可以跟踪该投票艺术家提名或投票给谁。也许这个活动有一批艺术家和另一批艺术家。你永远不会要求一位艺术家投票,也不会要求一位投票艺术家表演。然而,投票艺术家可以引用艺术家

那么现在曲