Ao transformar o código Java em código do Ceilão, às vezes encontro alguns construtores de classe Java que confundem a verificação e a inicialização. Vamos usar um exemplo de código simples, mas artificial, para ilustrar o que quero explicar.
Algum código ruim
Considere a seguinte classe Java. (Cara, não escreva esse código em casa)
Public Class Período {Data final privada StartDate; Data final privada ENDDATE; // Retorna nulo se a string fornecida // não representa uma data válida Data privada parsedate (string date) {...} 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) lança new ilegalStateException (); retornar startDate; } public data getEndDate () {if (enddate == null) lança new ilegalStateException (); return enddate; }}Ei, eu já avisei antes, é artificial. No entanto, na verdade, não é incomum encontrar algo assim no código Java real.
O problema aqui é que, mesmo que a verificação dos parâmetros de entrada (no método oculto de parsedate ()) falhar, ainda teremos uma instância do período. Mas o período que obtemos não é um estado "válido". Estritamente falando, o que quero dizer?
Bem, se um objeto não puder responder significativamente a uma operação pública, eu diria que está em um estado não válido. Neste exemplo, getStartDate () e getEnddate () lançam uma exceção ilegalStateException, que é um caso que eu não acho que seja "significativo".
Olhando para este exemplo, por outro lado, ao projetar o período, falhamos em segurança de tipo aqui. Exceções desmarcadas representam uma "vazio" no sistema de tipos. Portanto, um design de tipo melhor de um período segura seria um não uso de exceções desmarcadas-neste exemplo, a ilegalStateException não é lançada.
(De fato, em código real, tenho mais probabilidade de encontrar um método getStartDate () que não verifique se há NULL, após essa linha de código, causará uma exceção de NullPointerException, que é ainda pior.)
Podemos converter facilmente a classe do período acima em uma classe de formulário do Ceilão:
período de classe compartilhada (string inicial, string end) {// retorna nulo se a string fornecida // não representar uma data válida? Parsedate (string date) => ...; valor maybestartdate = parsedate (start); valor talveznddate = parsedate (end); O válido booleano compartilhado => MayBestartDate existe && talvez exista existe; data compartilhada startdate {assert (existe maybestartdate); retornar maybestartdate; } data compartilhada enddate {assert (existe maybestartdate); retornar maybestartdate; } Data compartilhada ENDDATE {Assert (existe talveznddate); retornar talvezNDDate; }}Obviamente, esse código também encontrará os mesmos problemas que o código Java original. Dois símbolos afirmados gritaram para nós, houve um problema no tipo de segurança do código.
Torne o código Java melhor
Como melhoramos esse código em Java? Bem, aqui está um exemplo das exceções criticadas de Java que são muito razoáveis para resolver! Podemos modificar um pouco o período para lançar uma exceção verificada de seu construtor:
Public Class Período {Data final privada StartDate; Data final privada ENDDATE; // lança se a string fornecida // não representa uma data válida Parsedate (data da string) lança DateForMatexception {...} Public Period (string inicial, string end) lança DateForMatexception {startDate = parsedate (start); enddate = parsedate (end); } public date getStartDate () {return startDate; } public date getEndDate () {return enddate; }}Agora, com esta solução, não teremos um período em um estado não válido. O código que instancia o período será tratado pelo compilador para lidar com entradas inválidas, o que capturará uma exceção DateForMatexception.
tente {período p = novo período (start, fim); ...} Catch (DateFormatexception dfe) {...}Este é um uso agradável, perfeito e correto de exceções verificadas e, infelizmente, raramente vejo o código Java usando exceções verificadas como o acima.
Torne o código do Ceilão melhor
Então, que tal o Ceilão? O Ceilão não tem exceções verificadas; portanto, precisamos encontrar uma solução diferente. Normalmente, em uma situação em que Java chama uma função e lança uma exceção verificada, o Ceilão chama a função e retorna um tipo de união. Como a inicialização de uma classe não retorna nenhum tipo, exceto a própria classe, precisamos extrair alguma lógica de inicialização/verificação mista para torná -la uma função de fábrica.
// Retorna DateFormaterror se a string fornecida // não representar um datate válido | DateFormaterror Parsedate (string date) => ...; Período compartilhado | DateFormaterror ParsePeriod (String inicial, string end) {value startDate = parsedate (start); if (é dateFormaterror startDate) {return startDate; } value enddate = parsedate (end); if (é dateformaterror enddate) {return enddate; } Período de retorno (startDate, enddate);} período de classe compartilhado (startDate, enddate) {data compartilhada startDate; Data compartilhada ENDDATE;}De acordo com o sistema de tipos, o chamador é obrigado a lidar com o DateFormaterror:
valor p = parseperiod (start, end); if (é dateFormaterror p) {...} else {...}Ou, se não nos importarmos com o problema real com um determinado formato de data (o que é possível, assumindo que o código de inicialização em que trabalhamos está faltando essas informações), podemos usar nulo em vez de dataFormaterror:
// retorna nulo se a string fornecida // não representa um datado válido? Parsedate (data da string) => ...; Período compartilhado? parseperiod (string start, string end) => if (existe startDate = parsedate (start), existe enddate = parsedate (end)) então período (startdate, enddate) else nulo; período de classe compartilhada (startDate, enddate) {shared date startDate; Data compartilhada ENDDATE;}A abordagem para o uso de funções de fábrica é excelente, para dizer o mínimo, pois geralmente tem melhor isolamento entre a lógica de validação e a inicialização do objeto. Isso é especialmente útil no Ceilão, onde o compilador adiciona algumas restrições muito rigorosas à lógica de inicialização do objeto para garantir que todas as áreas do objeto sejam atribuídas apenas uma vez.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.