При преобразовании кода Java в Цейлонский код, иногда я сталкиваюсь с некоторыми конструкторами класса Java, которые путают проверку и инициализацию. Давайте используем простой, но искусственный пример кода, чтобы проиллюстрировать, что я хочу объяснить.
Какой -то плохой код
Рассмотрим следующий класс Java. (Человек, не пишите такой код дома)
Период открытого класса {частная окончательная дата StartDate; Частная окончательная дата конечный дат; // Возвращает NULL, если заданная строка // не представляет действительную дату частной даты Parsedate (строка дата) {...} public Period (String Start, String end) {startDate = parsedate (start); enddate = parsedate (end); } public boolean isvalid () {return startDate! = null && enddate! = null; } public date getStartDate () {if (startDate == null) бросить new allogalStateException (); вернуть StartDate; } public Date getEndDate () {if (endDate == null) бросить new allodalStateException (); вернуть конец; }}Эй, я предупреждал это раньше, это искусственно. Тем не менее, на самом деле нередко находить что -то подобное в реальном коде Java.
Проблема здесь заключается в том, что даже если проверка входных параметров (в методе Hidden Parsedate ()) не удастся, мы все равно получим экземпляр периода. Но период, который мы получаем, не является «действительным» состоянием. Строго говоря, что я имею в виду?
Что ж, если объект не может значительно реагировать на публичную операцию, я бы сказал, что он находится в невалентном состоянии. В этом примере getStartDate () и getEndDate () бросают исключение по нелегальностиксации, которое, как я не считаю «значимым».
Глядя на этот пример, с другой стороны, когда мы проектируем период, мы не смогли в безопасности. Здесь. Неконтролируемые исключения представляют собой «недействительность» в системе типов. Следовательно, лучшим дизайном, безопасным для типа периода, будет неиспользование неконтролируемых исключений-в этом примере allectalStateException не бросается.
(Фактически, в реальном коде я с большей вероятностью столкнусь с методом getStartDate (), который не проверяет NULL, после этой строки кода это вызовет исключение NullPointerException, что еще хуже).
Мы можем легко преобразовать вышеупомянутый период класса в класс формы Цейлона:
Общий период класса (String Start, String End) {// Возвращает NULL, если данная строка // не представляет дату допустимой даты? Парсированное (строка дата) => ...; значение maybestartdate = parsedate (start); Значение может быть врожденое = parsedate (end); Shared Boolean Valid => MayBestartDate существует &&, может быть, существует; Общая дата startDate {assert (существует MayBestartDate); вернуть MayBestartDate; } Общая дата EndDate {assert (существует MayBestartDate); вернуть MayBestartDate; } Общая дата EndDate {assert (существует может быть,); вернуть может быть }}Конечно, этот код также столкнется с теми же проблемами, что и исходный код Java. На нас кричали два символа Assert, была проблема в безопасности типа кода.
Сделайте код Java лучше
Как улучшить этот код в Java? Ну, вот пример критикованных проверенных исключений Java, которые очень разумны для решения! Мы можем немного изменить период, чтобы выбросить проверенное исключение из его конструктора:
Период открытого класса {частная окончательная дата StartDate; Частная окончательная дата конечный дат; // бросает, если заданная строка // не представляет собой действительную дату частную дату Парсированное (дата строки) THRES DATEFORMATEXCEPTION {...} Общественный период (String Start, String End) Throws DateFormateXception {startDate = parsedate (start); enddate = parsedate (end); } public date getStartDate () {return startDate; } public date getEnddate () {return enddate; }}Теперь, с этим решением, мы не получим период в невалентном состоянии. Код, который создает период периода, будет обрабатываться компилятором для обработки недействительных входов, которые поймают исключение DateFormateXception.
try {период p = новый период (начало, конец); ...} catch (dateformatexception dfe) {...}Это хорошее, идеальное и правильное использование проверенных исключений, и, к сожалению, я редко вижу код Java, используя проверенные исключения, как приведенное выше.
Сделайте Цейлонский код лучше
Так как насчет Цейлона? Цейлон не имеет проверенных исключений, поэтому нам нужно найти другое решение. Как правило, в ситуации, когда Java вызывает функцию и бросает проверенное исключение, Цейлон вызывает функцию и возвращает тип союза. Поскольку инициализация класса не возвращает какой -либо тип, кроме самого класса, нам необходимо извлечь некоторую смешанную логику инициализации/проверки, чтобы сделать ее фабричной функцией.
// возвращает dateformaterror, если заданная // строка не представляет собой допустимый датированный if (is dateformaterror startDate) {return startDate; } value enddate = parsedate (end); if (is dateformaterror enddate) {return enddate; } Период возврата (startDate, endDate);} Shared Class Period (StartDate, EndDate) {Shared Date StartDate; Общая дата конечная дата;}В соответствии с системой типа, абонент обязан обрабатывать dateformaterror:
значение p = parseperiod (start, end); if (is dateformaterror p) {...} else {...}Или, если мы не заботимся о фактической проблеме с данным форматом даты (что возможно, предполагая, что код инициализации, над которым мы работаем, отсутствует эта информация), мы можем использовать NULL вместо DateFormaterRor:
// возвращает NULL, если заданная строка // не представляет собой допустимый датированный? Парсированное (строка дата) => ...; общий период? parseperiod (String start, String end) => if (существует startDate = parsedate (start), существует enddate = parsedate (end)), затем период (startDate, endDate) else Null; Shared Class Period (startDate, endDate) {общая дата startDate; Общая дата конечная дата;}Подход к использованию заводских функций превосходен, если не сказать больше, так как обычно он имеет лучшую изоляцию между логикой проверки и инициализацией объекта. Это особенно полезно на Цейлоне, где компилятор добавляет очень строгие ограничения в логику инициализации объекта, чтобы гарантировать, что все области объекта назначаются только один раз.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.