Il s'agit d'une décision de conception simple qui semble avoir des passions significatives de chaque côté. J'ai du mal à vraiment comprendre quel design a les conséquences les moins négatives.Décision de conception: Communiquer à partir d'une méthode
J'ai une méthode pour ajouter une banane:
public Banana AddBanana(string name)
{
// add the banana
var _Banana = new Banana { Name = name };
this.Bananas.Add(_Banana);
return _Banana;
}
Mais je ne peux pas ajouter dans certains cas, une banane, quelque chose comme ceci:
public Banana AddBanana(string name)
{
// test the request
if (this.Bananas.Count > 5)
return null;
if (this.Bananas.Where(x => x.Name == name).Any())
return null;
// add the banana
var _Banana = new Banana { Name = name };
this.Bananas.Add(_Banana);
return _Banana;
}
Maintenant, je veux communiquer à l'appelant Pourquoi ils ne peuvent pas.
Quelle est la meilleure approche?
Approche 1: communiquer avec une exception
public Banana AddBanana(string name)
{
// test the request
if (this.Bananas.Count > 5)
throw new Exception("Already 5 Bananas");
if (this.Bananas.Where(x => x.Name == name).Any())
throw new Exception("Banana Already in List");
// add the banana
var _Banana = new Banana { Name = name };
this.Bananas.Add(_Banana);
return _Banana;
}
Approche 2: communiquer avec un test
public Class CanAddBananaResult
{
public bool Allowed { get; set; }
public string Message { get; set; }
}
public CanAddBananaResult CanAddBanana(string name)
{
// test the request
if (this.Bananas.Count > 5)
return new CanAddBananaResult {
Allowed = false,
Message = "Already 5 Bananas"
};
if (this.Bananas.Where(x => x.Name == name).Any())
return new CanAddBananaResult {
Allowed = false,
Message = "Banana Already in List"
};
return new CanAddBananaResult { Allowed = true };
}
public Banana AddBanana(string name)
{
// test the request
if (!CanAddBanana(name).Allowed)
throw new Exception("Cannot Add Banana");
// add the banana
var _Banana = new Banana { Name = name };
this.Bananas.Add(_Banana);
return _Banana;
}
Dans l'approche 1, le consommateur connaît le problème sur la base Exception.Message.
Dans l'approche 2, le consommateur peut empêcher l'exception plutôt que de l'attraper.
Quelle approche est la meilleure dans l'ensemble? Je lis ceci: Classes de conception afin qu'une exception ne soit jamais levée en utilisation normale. Par exemple, une classe FileStream expose une autre façon de déterminer si la fin du fichier a été atteinte. Cela évite l'exception qui est levée si vous lisez après la fin du fichier. Mais l'approche "exceptionnelle" semble être moins le code. Cela signifie-t-il plus simple/meilleur?
n'est pas en mesure d'ajouter une banane un cas exceptionnel ou peut-il se produire en fonctionnement normal? – BrokenGlass
Ce n'est pas exceptionnel, regardez les tests. Dupliquer et limiter. Rien de trop exceptionnel à ce sujet. "Les exceptions sont pour des situations exceptionnelles" est une expression populaire, mais quel est le vrai point de décision ici? –