Note that there are some explanatory texts on larger screens.

plurals
  1. PODesign Decision: Communicating from a Method
    text
    copied!<p>This is a simple design decision that seems to have significant passions on each side. I am struggling to really understand which design has the least negative consequences.</p> <p>I have a method to add a banana:</p> <pre><code>public Banana AddBanana(string name) { // add the banana var _Banana = new Banana { Name = name }; this.Bananas.Add(_Banana); return _Banana; } </code></pre> <p>But in some cases I cannot add a banana, something like this:</p> <pre><code>public Banana AddBanana(string name) { // test the request if (this.Bananas.Count &gt; 5) return null; if (this.Bananas.Where(x =&gt; x.Name == name).Any()) return null; // add the banana var _Banana = new Banana { Name = name }; this.Bananas.Add(_Banana); return _Banana; } </code></pre> <p>Now I want to communicate back to the caller WHY they can't.</p> <p><strong>WHICH way is the better approach?</strong></p> <p>Approach 1: communicate with an exception</p> <pre><code>public Banana AddBanana(string name) { // test the request if (this.Bananas.Count &gt; 5) throw new Exception("Already 5 Bananas"); if (this.Bananas.Where(x =&gt; 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; } </code></pre> <p>Approach 2: communicate with a test</p> <pre><code>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 &gt; 5) return new CanAddBananaResult { Allowed = false, Message = "Already 5 Bananas" }; if (this.Bananas.Where(x =&gt; 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; } </code></pre> <p>In Approach 1, the consumer knows the problem based on the exception.Message.</p> <p>In Approach 2, the consumer can prevent the exception rather than catch it.</p> <p>Which approach is better overall?</p> <blockquote> <p>I read this: Design classes so that an exception is never thrown in normal use. For example, a FileStream class exposes another way of determining whether the end of the file has been reached. This avoids the exception that is thrown if you read past the end of the file. <a href="http://msdn.microsoft.com/en-us/library/seyhszts(v=vs.71).aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/seyhszts(v=vs.71).aspx</a></p> </blockquote> <p>But the "exceptional" approach seems to be less code. Does that mean simpler/better?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload