If .Create () cannot create an instance, should it return an empty object, null, or an exception?

I want to be able to instantiate any object in my application using this code:

SmartForm smartForm = SmartForm.Create("id = 23"); Customer customer = Customer.Create("id = 222"); 

Now I am discussing what Create () should return if this object does not exist.

  • if Create () returns an empty object , then this is a kind of "zero template", and I can still pass this object around my application and call the call methods on it, which makes programming with this model convenient and easy

  • if Create () returns null , then I need to check after each instance if the object is zero or not, which makes programming more tedious, but more explicit. The problem is that if you forget to check for zero, your application can run for a long time, not knowing that you are not checking for zero, and then suddenly crash

  • if Create () throws an exception , it's basically the same as returning null, but makes programming even more tedious by trying, then finally a block for each instance, but you can use different types of exceptions (which you cannot use with a null solution) that could bubble up so you can more clearly handle deep errors in the user interface, so I would think that this is the most reliable solution, although it will produce try / catch code bloat

So, it looks like lightness / reliability . Does anyone have any experience making a decision in accordance with these lines where you have encountered advantages or disadvantages due to this decision?

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestFactory234.Models { public class SmartForm : Item { public string IdCode { get; set; } public string Title { get; set; } public string Description { get; set; } public int LabelWidth { get; set; } public SmartForm() { } private SmartForm(string loadCode) { _loadCode = loadCode; TryToInstantiateFromDatabase(); } public static SmartForm Create(string loadCode) { SmartForm smartForm = new SmartForm(loadCode); if (!smartForm.IsEmpty()) { return smartForm; } else { return null; } } } } 
+3
source share
6 answers

It depends - if it fails because something is definitely wrong, then the exception makes programming easier - you don't write try / catch around every call, you just let the exception bubble up. Compare this to checking for a null / net return value and then throwing an exception.

This sounds like the right time to use ArgumentException , IMO.

If you find yourself creating a try / catch "bloat", see why you really need to catch exceptions, not just let them bubble.

+6
source

If it returns an empty object, then you will consider it valid - or you need to perform some kind of complex test to see if it is empty or not. If it returns null, you will always need to check for null (and maybe that's for sure). I would prefer it to throw an exception - assuming your code is designed so that it doesn't. If this is a normal scenario, then zero might be the best choice.

+2
source

When the default behavior is to create an instance, then the exceptional behavior occurs with an error during creation -> Exception

What would you do with EmptyObject? You say that you can still pass it on - does it really make sense? What do the methods do when you call them?

Perhaps you should implement the second TryCreate () method.

I would use the Exception option, but it depends on what behavior you need.

+2
source

Your sample code calls the "try downloading from the database" method, and the "Create" agreement is very similar to the "ActiveRecord Lock" object . Why not split up the Get / Create database operation, let the framework do the work, and rely on their conventions?

 [ActiveRecord("Forms")] public class SmartForm : Item { [PrimaryKey("Id")] public string IdCode { get; set; } [Property] public string Title { get; set; } [Property] public string Description { get; set; } [Property] public int LabelWidth { get; set; } } 

You get / create instances like this

 SmartForm entity = ActiveRecordMediator<SmartForm>.Find(1); SmartForm otherEntity = ActiveRecordMediator<SmartForm>.FindFirst(/* criteria */); 

There are many other methods for finding instances. I think you will find that ActiveRecord defaults regarding throw exceptions that return zero or in the case of collections, an empty collection, are very consistent and well implemented.

+1
source

If you create a factory form, you are better off passing an enumeration rather than a string (unless, of course, this is a plug-in architecture).

0
source

If it is possible that the creation may fail, but a lot of application code expects it to work, you really must implement two versions of the creation method, one of which must either succeed or throw an exception, and the other of which should indicate the expected failures in some ways except throw exceptions, and throw an exception only for failures that the caller probably does not expect (for example, CpuIsOnFireException). The general scheme for this is for the TryCreate method to return a boolean indicating success by storing the generated argument with the by-ref argument. I do not like this template, because it gives no indication of anything other than the status of the passage (i.e., nothing about why it did not pass). I think it would be better if the "try" function returns either a new thing or null, but has a by-ref argument indicating the reason for the failure. Note that this approach will make better use of implicit typing (for example, the keyword "var" in C #).

0
source

Source: https://habr.com/ru/post/1286016/


All Articles