Il team esterno è al capolinea di un nuovo progetto. Uno dei componenti al confine del sistema è il componente che interagisce con una stampante attraverso un componente COM esterno (indicato come una normale dll).
Il componente COM restituisce i codici interi se si è verificato un errore durante l'esecuzione del comando. Consideriamo un codice concreto.
public class OperationException:Exception {
public int ErrorCode { get; private set; }
public string ErrorDescription { get; private set; }
public OperationException(int errorCode, string errorDescription) {
ErrorCode = errorCode;
ErrorDescription = errorDescription;
}
}
//The exception throwing way
public class Provider1:IFrProvider {
private readonly IDrvFR48 driver;
public string GetSerialNumber() {
//must read status before get SerialNumber
int resultCode = driver.ReadEcrStatus();
if (resultCode != 0) {
throw new OperationException(resultCode, driver.ErrorDescription);
}
return driver.SerialNumber;
}
}
//The way of out parameters returning.
public class Provider2 : IFrProvider
{
private readonly IDrvFR48 driver;
public string GetSerialNumber(out Result result) {
//must read status before get SerialNumber
int resultCode = driver.ReadEcrStatus();
if (resultCode != 0) {
result = new Result(resultCode, driver.ErrorDescription);
return null;
}
result = new Result(0, null);
return driver.SerialNumber;
}
}
//The way of LastResult property setting.
public class Provider3 : IFrProvider
{
private readonly IDrvFR48 driver;
public Result LastResult {
get {
return new Result(driver.ErrorCode, driver.ErrorDescription);
}
}
public string GetSerialNumber() {
//must read status before get SerialNumber
if (driver.GetECRStatus() == 0)
return driver.SerialNumber;
return null;
}
}
public class Result {
public int ResultCode { get; private set; }
public string Description { get; private set; }
public Result(int resultCode, string description) {
ResultCode = resultCode;
Description = description;
}
}
public class Caller {
public void CallProvider1() {
var provider = new Provider1();
try {
string serialNumber = provider.GetSerialNumber();
//success flow
}
catch (OperationException e) {
if (e.ErrorCode == 123) {
//handling logic
}
}
}
public void CallProvider2() {
var provider = new Provider2();
Result result;
string serialNumber = provider.GetSerialNumber(out result);
if (result.ResultCode == 123) {
//error handling
}
//success flow
}
public void CallProvider3()
{
var provider = new Provider3();
string serialNumber = provider.GetSerialNumber();
if (provider.LastResult.ResultCode == 123) {
//handling
}
//success flow
}
}
Quindi abbiamo tre modi di gestire gli errori. La cosa più specifica di tutte queste cose è che ogni operazione può fallire, perché dipende da un dispositivo.
Il nostro team pensa di utilizzare i parametri, a causa della paura della propagazione delle eccezioni non gestite. L'altro motivo, collegato alla paura, è che dovremo coprire tutte le chiamate provando \ catch i blocchi per non avere paura, ma un tale codice sarà piuttosto brutto.
Quali pro e contro vedi e cosa potresti dare un consiglio?