D'innombrables jugements nuls dans le projet ont eu un très mauvais impact sur la qualité et la propreté du code. Nous appelons ce phénomène "désastre des jugements nuls".
Alors, comment gérer ce phénomène ? Vous avez peut-être entendu parler du pattern NullObject, mais ce n'est pas notre arme aujourd'hui, mais nous devons encore introduire le pattern NullObject.
Dans la programmation informatique orientée objet, un objet nul est un objet sans valeur référencée ou avec un comportement neutre (« nul ») défini. Le modèle de conception d'objet nul décrit les utilisations de ces objets et leur comportement (ou leur absence). .
L'analyse ci-dessus provient de Wikipédia.
Le modèle NullObject a été publié pour la première fois dans la série "Programming Pattern Language". Généralement, dans les langages orientés objet, vous devez utiliser une vérification nulle avant d'appeler des objets pour déterminer si ces objets sont nuls, car les méthodes requises ne peuvent pas être appelées sur des références nulles.
L'exemple de code est le suivant (le nom vient d'Internet, haha, comme tu es paresseux) :
Nullable est l'interface d'opération pertinente de l'objet vide, qui est utilisée pour déterminer si l'objet est vide, car dans le mode objet vide, l'objet sera empaqueté s'il est vide. Il devient un objet et devient un objet nul. Cet objet implémentera les implémentations nulles de toutes les méthodes de l'objet d'origine...
public interface Nullable { boolean isNull(); }
Cette interface définit le comportement de l'objet vide. objet métier.
<br>
public interface DependencyBase extends Nullable { void Operation(); }
Il s'agit de la vraie classe de l'objet, qui implémente l'interface de comportement métier DependencyBase et l'interface d'opération d'objet nul Nullable.
public class Dependency implements DependencyBase, Nullable { @Override public void Operation() { System.out.print("Test!"); } @Override public boolean isNull() { return false; } }
Il s'agit d'un objet vide, une implémentation vide du comportement de l'objet d'origine.
public class NullObject implements DependencyBase{ @Override public void Operation() { // do nothing } @Override public boolean isNull() { return true; } }
Lors de son utilisation, vous pouvez appeler l'objet vide via un appel d'usine, ou vous pouvez appeler l'objet via d'autres méthodes telles que la réflexion (cela prend généralement quelques millisecondes), qui ne seront pas décrites en détail ici.
public class Factory { public static DependencyBase get(Nullable dependencyBase){ if (dependencyBase == null){ return new NullObject(); } return new Dependency(); } }
Ceci est un exemple d'utilisation. Grâce à ce mode, nous n'avons plus besoin d'effectuer l'opération nulle de l'objet, mais pouvons utiliser l'objet directement sans nous soucier du NPE (NullPointerException).
public class Client { public void test(DependencyBase dependencyBase){ Factory.get(dependencyBase).Operation(); } }
NR Null Object est un plug-in Intellij pour Android Studio, IntelliJ IDEA, PhpStorm, WebStorm, PyCharm, RubyMine, AppCode, CLion, GoLand, DataGrip et autres IDEA. Il peut générer rapidement et facilement les composants requis pour son mode objet vide en fonction des objets existants. Ses fonctions incluent les suivantes :
Analyser les méthodes de la classe sélectionnée qui peuvent être déclarées comme interfaces. interface ;
Créer des objets vides et implémenter automatiquement des interfaces publiques ;
Convention de dénomination automatique des fonctions
Jetons un coup d'œil à un exemple d'utilisation :
Sélectionnez Préférences → Plugins → Parcourir les référentiels
Recherchez "NR Null Oject" ou "Null Oject" pour une requête floue, cliquez sur Installer à droite et redémarrez IDEA.FacultatifUne autre façon consiste à utiliser les fonctionnalités Facultatives de Java8 pour déterminer avec élégance la valeur nulle. L'introduction officielle de Facultatif est la suivante :
Un objet conteneur qui peut ou non contenir un objet non nul. value . Si une valeur est présente, isPresent() renverra true et get() renverra la valeur.
Un objet conteneur qui peut ou non contenir des valeurs non nulles. Si la valeur est présente, isPresent() renverra true et get() renverra la valeur.Sans plus attendre, laissez-moi vous donner un exemple.
Il y a le code suivant, qui doit obtenir les informations Info dans Test2, mais le paramètre est Test4. Nous devons appliquer couche par couche. Les objets obtenus à chaque couche peuvent être vides.
public String testSimple(Test4 test) { if (test == null) { return ""; } if (test.getTest3() == null) { return ""; } if (test.getTest3().getTest2() == null) { return ""; } if (test.getTest3().getTest2().getInfo() == null) { return ""; } return test.getTest3().getTest2().getInfo(); }
Mais après avoir utilisé Facultatif, tout est différent.
public String testOptional(Test test) { return Optional.ofNullable(test).flatMap(Test::getTest3) .flatMap(Test3::getTest2) .map(Test2::getInfo) .orElse(""); }
1.Optionnel.ofNullable(test), si le test est vide, un objet facultatif singleton vide est renvoyé. S'il n'est pas vide, un objet d'emballage facultatif est renvoyé. code >2. flatMap(Test::getTest3) détermine si le test est vide. S'il est vide, continuez à renvoyer l'objet facultatif singleton dans la première étape, sinon appelez la méthode getTest3 de Testpublic static <t> Optional<t> ofNullable(T value) { return value == null ? empty() : of(value); }</t></t>Copier après la connexion
public<u> Optional<u> flatMap(Function super T, Optional<u>> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Objects.requireNonNull(mapper.apply(value)); } }</u></u></u>
3、flatMap(Test3::getTest2)同上调用Test3的getTest2方法;
4、map(Test2::getInfo)同flatMap类似,但是flatMap要求Test3::getTest2返回值为Optional类型,而map不需要,flatMap不会多层包装,map返回会再次包装Optional;
public<u> Optional<u> map(Function super T, ? extends U> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Optional.ofNullable(mapper.apply(value)); } }</u></u>
5、orElse("");获得map中的value,不为空则直接返回value,为空则返回传入的参数作为默认值。
public T orElse(T other) { return value != null ? value : other; }
怎么样,使用Optional后我们的代码是不是瞬间变得非常整洁,或许看到这段代码你会有很多疑问,针对复杂的一长串判空,Optional有它的优势,但是对于简单的判空使用Optional也会增加代码的阅读成本、编码量以及团队新成员的学习成本。毕竟Optional在现在还并没有像RxJava那样流行,它还拥有一定的局限性。
如果直接使用Java8中的Optional,需要保证安卓API级别在24及以上。
你也可以直接引入Google的Guava。(啥是Guava?来自官方的提示)
Guava is a set of core libraries that includes new collection types (such as multimap and multiset), immutable collections, a graph library, functional types, an in-memory cache, and APIs/utilities for concurrency, I/O, hashing, primitives, reflection, string processing, and much more!
引用方式,就像这样:
dependencies { compile 'com.google.guava:guava:27.0-jre' // or, for Android: api 'com.google.guava:guava:27.0-android' }
不过IDEA默认会显示黄色,提示让你将Guava表达式迁移到Java Api上。
当然,你也可以通过在Preferences搜索"Guava"来Kill掉这个Yellow的提示。
将防御式编程代码完美包装
链式调用
有效避免程序代码中的空指针
流行性不是非常理想,团队新成员需要学习成本
安卓中需要引入Guava,需要团队每个人处理IDEA默认提示,或者忍受黄色提示
当然,Kotlin以具有优秀的空安全性为一大特色,并可以与Java很好的混合使用,like this:
test1?.test2?.test3?.test4
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!