Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. На Вашей 4-й точке;
Да я думаю, что сложный быстрый интерфейс может все еще быть быстрым.
я думаю, что быстрые интерфейсы являются своего рода компромиссом. (хотя хороший!) Было много исследования использования естественного языка для программирования, и обычно естественный язык не достаточно точен для выражения программ.
Быстрые интерфейсы создаются так, чтобы они записали как язык программирования, только маленькое подмножество того, что можно выразить на естественном языке, позволяется, но они читают как естественный язык.
при рассмотрении насмешек носорога, например, часть записи была сложной по сравнению с нормальной библиотекой. Я взял меня дольше для изучения главным образом из-за быстрого интерфейса, но он делает код намного легче читать. Поскольку программы обычно пишутся однажды и читают много несколько раз, это - хороший компромисс.
Так для квалификации моей точки немного. Быстрый интерфейс, который это сложно для записи, но легкий читать, может все еще быть быстрым.
Единственная самая сложная задача, которую я испытал как потребитель быстрых интерфейсов, - то, что большинство из них не является действительно быстрыми интерфейсами - вместо этого они - действительно экземпляры того, что я склонен называть 'четкими интерфейсами'.
А быстрый интерфейс подразумевает, что его основная цель состоит в том, чтобы помочь ГОВОРИТЬ его, тогда как четкий интерфейс подразумевает, что его основная цель состоит в том, чтобы быть легка СЧИТАТЬ его. Большинство быстрых интерфейсов только имеет тенденцию быть смехотворно трудным кодировать с, но с другой стороны невероятно легкий ЧИТАТЬ позже другими.
Assert().That().This(actual).Is().Equal().To(expected).
Except().If(x => x.GreaterThan(10));
... намного легче читать позже, чем это должно на самом деле сочинить в коде!
Вы поразите кирпич при использовании наследования наряду с быстрыми интерфейсами, потому что использование полиморфных методов повреждает цепочки вызовов, и Вы определенно не хотите делать свои интерфейсы небыстрыми при помощи ужасного кастинга и круглой скобки, где они не нужны. Я написал статью о шаблоне, который предоставляет Вам обходное решение с помощью универсальных разработчиков и универсальных дополнительных методов с универсальными ограничениями: http://liviutrifoi.wordpress.com/2009/02/16/fluent-interfaces-constraints-at-compile-time/
И по Вашему 2-му и 3-му вопросу;
Три быстрых шаблона я заметил
первое использование оператор использования (C# 2.0) выполнять код в определенном контексте, например:
using(var transaction = new Transaction())
{
// ..
// ..
}
Это использует конструктора и управляющего Транзакции для установки транзакции и затем выполняет код в этом контексте.
второе делает почти то же, но с лямбдой, это используется много в Насмешках Носорога, например.
(new Transaction()).Run( () => mycode(); );
самый известный быстрый интерфейс должен использовать типы возврата для объединения в цепочку вызовов метода. Главным образом методы возвращают это так, можно объединить запросы в цепочку к тому же объекту. Но можно также возвратить различные объекты изменить контекст в зависимости от названного метода. Если у Вас есть объект, который может только работать в транзакции (извините не может думать о различном примере), можно дать ему метод StartTransaction, который возвращает инициализированную транзакцию, куда можно выполнить выполненный вызов и stoptransaction в псевдокоде:
class Runner
{
Transaction StartTransaction()
{
return new Transaction(this);
}
}
class Transaction
{
Transaction Run()
Transaction StopTransaction()
}
, где вызов похож
var runner = new Runner();
runner
.StartTransaction()
.Run()
.StopTransaction();
, Конечно, необходимо добавить все виды обработки ошибок и т.д.
Moq скрывает неизведанные методы, такие как equals, ToString
и т. Д., Чтобы сделать их свободный интерфейс еще проще в использовании.
Скрытие системного объекта - статья, объясняющая преимущества этого.
Я тоже только начинаю учиться писать свободный интерфейс для небольшого приложения на работе. Я поспрашивал, немного исследовал и обнаружил, что хорошим подходом к написанию свободного интерфейса является использование «паттерна Builder», подробнее об этом здесь .
По сути, это то, как я начал мой:
public class Coffee
{
private bool _cream;
private int _ounces;
public Coffee Make { get new Coffee(); }
public Coffee WithCream()
{
_cream = true;
return this;
}
public Coffee WithOuncesToServe(int ounces)
{
_ounces = ounces;
return this;
}
}
Вот перекрестный пост на аналогичный вопрос , который у меня есть для реализации закрытия в свободном интерфейсе.
Некоторое время назад у меня были те же сомнения, что и у вас сейчас. Я провел некоторое исследование и сейчас пишу несколько постов, чтобы помочь в этих вопросах.
Загляните в мой блог:
Руководство по разработке плавного интерфейса на C# часть 1
А в следующих постах я расскажу о каждом из пунктов, которые вы упомянули.
С наилучшими пожеланиями Андре Вианна