gpt4 book ai didi

c# - 关于具有许多不同子类的类型切片的设计问题

转载 作者:行者123 更新时间:2023-11-30 15:50:49 25 4
gpt4 key购买 nike

我经常遇到的一个基本问题,但曾经找到一个干净的解决方案,是一个你想要为公共(public)基类或接口(interface)的不同对象之间的交互编写行为的代码。为了使它更具体一些,我将举一个例子;

Bob 一直在编写一款支持“炫酷地理效果”的策略游戏。这些四舍五入到简单的约束,例如如果部队在水中行走,他们会减速 25%。如果他们在草地上行走,他们会减速 5%,如果他们在人行道上行走,他们会减速 0%。

现在,管理层告诉鲍勃他们需要新的部队。会有吉普车、小船和气垫船。此外,他们希望吉普车在驶入水中时能够受到伤害,并且气垫船会忽略所有三种地形类型。也有传言说他们可能会添加另一种地形类型,其功能比减慢单位速度和受到伤害还要多。

一个非常粗略的伪代码示例如下:

public interface ITerrain
{
void AffectUnit(IUnit unit);
}

public class Water : ITerrain
{
public void AffectUnit(IUnit unit)
{
if (unit is HoverCraft)
{
// Don't affect it anyhow
}
if (unit is FootSoldier)
{
unit.SpeedMultiplier = 0.75f;
}
if (unit is Jeep)
{
unit.SpeedMultiplier = 0.70f;
unit.Health -= 5.0f;
}
if (unit is Boat)
{
// Don't affect it anyhow
}
/*
* List grows larger each day...
*/
}
}
public class Grass : ITerrain
{
public void AffectUnit(IUnit unit)
{
if (unit is HoverCraft)
{
// Don't affect it anyhow
}
if (unit is FootSoldier)
{
unit.SpeedMultiplier = 0.95f;
}
if (unit is Jeep)
{
unit.SpeedMultiplier = 0.85f;
}
if (unit is Boat)
{
unit.SpeedMultiplier = 0.0f;
unit.Health = 0.0f;
Boat boat = unit as Boat;
boat.DamagePropeller();
// Perhaps throw in an explosion aswell?
}
/*
* List grows larger each day...
*/
}
}

如您所见,如果 Bob 从一开始就有可靠的设计文档,情况会更好。随着单位数量和地形类型的增加,代码的复杂性也随之增加。 Bob 不仅需要担心弄清楚哪些成员可能需要添加到单元界面,而且他还需要重复很多代码。新的地形类型很可能需要额外的信息,这些信息可以从基本的 IUnit 界面获得。

每次我们在游戏中添加另一个单位时,每个地形都必须更新以处理新单位。显然,这会造成大量重复,更不用说确定正在处理的单元类型的难看的运行时检查了。在此示例中,我选择了对特定子类型的调用,但这些类型的调用是必须进行的。 一个例子是,当一艘船撞上陆地时,它的螺旋桨应该会损坏。并非所有单位都有螺旋桨。

我不确定这种问题叫什么,但它是一个多对多的依赖关系,我很难解耦。我不希望 ITerrain 上的每个 IUnit 子类都有 100 次重载,因为我想通过耦合来清理。

有关此问题的任何线索都备受追捧。也许我正在考虑一起脱离轨道?

最佳答案

地形有一个地形属性

地形属性是多维的。

单位有推进力。

推进力与地形属性兼容。

单位通过以推进力作为参数的地形访问移动。这被委托(delegate)给推进器。

作为访问的一部分,单位可能会受到地形的影响。

单位代码对推进一无所知。地形类型可以改变而不改变任何东西,除了地形属性和推进力。Propuslion 的 builder 保护现有装置免受新的旅行方式的影响。

关于c# - 关于具有许多不同子类的类型切片的设计问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com