我正在开发一个编程游戏,玩家将可以访问抽象类并将其扩展以控制机器人的行为。因为这是一款编程游戏,所以我试图保护我的游戏基础架构,以便玩家不会惹上游戏,而不仅仅是我给他们的班级。为此,我将大部分课程final
进行CC_1,但现在我无法在我的单位测试中嘲笑它们(Mockito Testng)。
所以我想知道,我该如何解决这个问题?有没有办法可以将类非决赛的课程放在测试中,然后在构建周期的后期以某种方式自动" final
-ize"它们(如果Maven与答案相关,我正在使用Maven)。我不想添加另一个外部库或更改我的模拟库。
如果是不可能的,那么第二个问题是:正在制作一个类final
真的安全吗?我看到了一些可以从字节码中删除final
分类器的库可以从已经编译的类
首先,您不能通过宣布"最终"来阻止人们搞砸您的游戏。有反思技巧和整个代码生成库,这使得超越这一点只是有些不便。
因此,输掉决赛,然后您可以使用JMOCK或任何您喜欢进行模拟的库。
您始终可以使用委托而不是继承。
public interface Foo {
// ...
}
public final class FooImpl implements Foo {
// ...
}
public class MockFooImpl implements Foo {
private FooImpl delegate;
// ...
}
但是,在您的API中举办抽象课是不好的。接口会更好。
您最终可以尝试应用自动重构工具,例如Jackpot 3或RepactoringNG。我从未测试过它们,但如果采取重构的方式,它们不仅可以做您想做的事情。
另一种方法是使用允许嘲笑决赛和静态的PowerMock(即使我很难嘲笑静态,因为这表明您的设计中有问题)。
imo,类是最终标记的,以使其对象变得不可变。如果您想控制班级的行为,则将班级中的方法标记为私人,以免它们被覆盖。如果您受到保护,那么某人可以扩展您的课程,覆盖这些受保护的方法,并将扩展类的实例传递给您的API,以期望您的类对象作为参数,从而诱导修改后的行为。因此,您将标记您不想将其视为私人的方法。
您仅根据使用这些类别的客户的自定义行为来覆盖的受保护/公共方法的扩展点。
使大多数类final
是一个很好的做法,因为它们通常不是通过子分类而设计的。我知道建议这样做的所有有关API设计的书籍("有效的Java","实用API设计"," C 的API设计")。由于几个原因,这是有益的,包括API设计师意图的表达,API的安全演变以及预防死亡代码(例如,良好的IDE将检测到final
方法何时不使用其参数之一,或者永远不会在throws
子句中列出的检查异常 - 对于非最终方法是不可能的)。
对于嘲笑上述课程,您只需要使用适当的模拟工具,例如Jmockit(我开发了这是因为我想编写单元测试而不牺牲某些OO/API设计实践)。