这是一遍又一遍重复的规则之一,这令我感到困惑。 空是邪恶的,应尽可能避免。 但是,但是-出于我的天真,让我尖叫-有时可能会有意义地缺乏价值! 请让我在一个示例中问这个问题,该示例来自我目前正在研究的此反模式缠身的可怕代码。从本质上讲,这是一个基于多人网络回合的游戏,其中两个玩家的回合都同时运行(例如在Pokemon中,与Chess相反)。 每次转动之后,服务器都会广播客户端JS代码的更新列表。Update类: public class GameUpdate { public Player player; // other stuff } 此类被序列化为JSON并发送到连接的播放器。 大多数更新自然都会有一个与之相关的玩家-毕竟,有必要知道哪个玩家在此回合中做出了哪个动作。但是,某些更新无法使Player有意义地与它们相关联。示例:游戏被强行捆绑,因为超出了没有动作的回合限制。我认为,对于此类更新,让播放器为空是有意义的。 当然,我可以利用继承来“修复”此代码: public class GameUpdate { // stuff } public class GamePlayerUpdate : GameUpdate { public Player player; // other stuff } 但是,由于两个原因,我看不到有什么改进: 现在,JS代码将简单地接收不带Player的对象作为已定义的属性,这与它为null相同,因为两种情况都需要检查该值是否存在。 如果将另一个可为空的字段添加到GameUpdate类中,则我必须能够使用多重继承来继续进行此设计-但是MI本身是邪恶的(根据经验更丰富的程序员),更重要的是,C#不会有它,所以我不能使用它。 我有一个暗示,这段代码是经验丰富的优秀程序员惊骇地尖叫的其中之一。同时,我看不到这个null会如何伤害任何事物,而应该怎么做。 你能向我解释这个问题吗?
我们的网络应用程序正在使用将ExceptionMapper某些异常映射到Response。我们记录异常消息,然后引发新异常,如下所示: catch (SomeException ex) { LOG.error(ex.getMessage()); throw new MyException(ex.getMessage()); } 我们不会再次抛出相同的异常,所以我的问题是,是否将其视为Log and Throw反模式。因此,最好删除相似位置的日志并将它们移至以下几个ExceptionMapper类: @Provider public class MyExceptionMapper implements ExceptionMapper<MyException> { // bla bla @Override public Response toResponse(final MyException ex) { LOG.error(ex.getMessage()); return Response.status(400).entity("something").build(); } }
我正在阅读Martin Fowler的《重构》一书中的常见代码气味。在这种情况下,我想知道我在代码库中看到的一种模式,并且可以客观地将其视为一种反模式。 模式是一种将对象作为参数传递给一个或多个方法的模式,所有这些方法都会更改对象的状态,但是没有一个返回对象。因此,它依赖于C#/。NET(在这种情况下)的按引用传递特性。 var something = new Thing(); // ... Foo(something); int result = Bar(something, 42); Baz(something); 我发现(尤其是方法名称不正确时),我需要研究此类方法以了解对象状态是否已更改。由于我需要跟踪调用堆栈的多个级别,因此这会使代码理解更加复杂。 我想建议改进此类代码,以返回具有新状态的另一个(克隆的)对象,或在调用站点更改该对象所需的任何操作。 var something1 = new Thing(); // ... // Let's return a new instance of Thing var something2 = Foo(something1); // Let's use out param to 'return' other info about the operation …