Votre code peut avoir plus de problèmes que d'avoir besoin de vérifier les références nulles. Comme il est, vous êtes probablement à la violation de la Loi de Déméter.
La Loi de Déméter est l'un de ces heuristiques, comme Ne pas se Répéter, qui vous permet d'écrire facilement maintenable code. Il raconte les programmeurs de ne pas accéder à quoi que ce soit trop loin de la portée immédiate. Par exemple, supposons que j'ai ce code:
public interface BusinessData {
public decimal Money { get; set; }
}
public class BusinessCalculator : ICalculator {
public BusinessData CalculateMoney() {
// snip
}
}
public BusinessController : IController {
public void DoAnAction() {
var businessDA = new BusinessCalculator().CalculateMoney();
Console.WriteLine(businessDA.Money * 100d);
}
}
L' DoAnAction
méthode est contraire à la Loi de Déméter. Dans une fonction, il accède à une BusinessCalcualtor
, BusinessData
, et un decimal
. Cela signifie que si l'une des modifications suivantes sont apportées, la ligne devra être refait:
- Le type de retour d'
BusinessCalculator.CalculateMoney()
changements.
- Le type d'
BusinessData.Money
changements
Compte tenu de la situation à eu, ces changements sont plutôt susceptibles de se produire. Si le code comme c'est écrit tout au long de la base de code, de sorte que ces changements pourraient devenir très coûteux. En outre, il signifie que votre BusinessController
est couplé à la fois à l' BusinessCalculator
et de la BusinessData
types.
Une façon d'éviter cette situation est reécriture le code comme ceci:
public class BusinessCalculator : ICalculator {
private BusinessData CalculateMoney() {
// snip
}
public decimal CalculateCents() {
return CalculateMoney().Money * 100d;
}
}
public BusinessController : IController {
public void DoAnAction() {
Console.WriteLine(new BusinessCalculator().CalculateCents());
}
}
Maintenant, si vous effectuez l'une des modifications ci-dessus, vous n'avez qu'à refactoriser un plus de morceau de code, l' BusinessCalculator.CalculateCents()
méthode. Vous avez également éliminé BusinessController
's la dépendance de l' BusinessData
.
Votre code souffre d'un problème similaire:
interface IContact
{
IAddress address { get; set; }
}
interface IAddress
{
string city { get; set; }
}
class Person : IPerson
{
public IContact contact { get; set; }
}
class Test {
public void Main() {
var contact = new Person().contact;
var address = contact.address;
var city = address.city;
Console.WriteLine(city);
}
}
Si l'une des modifications suivantes sont apportées, vous aurez besoin de revoir la principale méthode que j'ai écrit ou le nul de vérifier que vous avez écrit:
- Le type d'
IPerson.contact
changements
- Le type d'
IContact.address
changements
- Le type d'
IAddress.city
changements
Je pense que vous devriez envisager un approfondissement de la refactorisation du code de la simple réécriture null vérifier.
Cela dit, je pense qu'il y a des moments où, à la suite de la Loi de Déméter est inapproprié. (Il est, après tout, une heuristique, pas difficile et rapidement la règle, même si elle est appelée "la loi".)
En particulier, je pense que si:
- Vous avez quelques classes qui représentent les enregistrements stockés dans la couche de persistance de votre programme, ET
- Vous êtes très sûr que vous n'aurez pas besoin de revoir ces classes dans l'avenir,
ignorant la Loi de Déméter est acceptable lorsque traitent spécifiquement de ces classes. C'est parce qu'ils représentent les données que votre application fonctionne avec, afin d'atteindre à partir d'un objet de données dans un autre est un moyen d'explorer l'information dans votre programme. Dans mon exemple ci-dessus, le couplage causés par la violation de la Loi de Déméter était beaucoup plus grave: j'ai atteint tout le chemin à partir d'un contrôleur de près le haut de ma pile à travers une logique d'entreprise de la calculatrice.
Je soulève cette exception à la Loi de Déméter car avec des noms comme Person
, Contact
, et Address
, vos classes regardent comme ils pourraient être données de la couche POCOs. Si c'est le cas et que vous êtes très sûr que vous n'aurez plus jamais besoin de revoir dans le futur, vous pourriez être en mesure de s'en sortir ignorant la Loi de Déméter dans votre situation spécifique.