Reconstruction Method-Simplified function call [6], reconstruction method-Simplified Function
Total returned directory
Directory of this section
- Replace Error Code with Exception (Replace the Error Code with an Exception)
- Replace Exception with Test (Replace Exception with Test)
13 Replace Error Code with Exception (Replace the Error Code with an Exception) Summary
A function returns a specific code to indicate a specific situation.Switch exception.
Motivation
Exceptions clearly separate "Common Programs" from "error handling", which makes the program easier to understand.
The comprehensibility of code should be our goal.
Example
Class Account {// <summary> // balance /// </summary> private int _ balance; /// <summary> /// withdrawal // </summary> /// <param name = "amount"> withdrawal amount </param> /// <returns> </returns> public int Withdraw (int amount) {if (amount> _ balance) {return-1;} _ balance-= amount; return 0;} public bool CanWithdraw (int amount) {return amount <= _ balance ;} public void HandOverdran () {}public void DoTheUsualThing (){}}
In order to let this code use exceptions, first decide whether to use controlled exceptions or uncontrolled exceptions. The key lies in whether the caller is responsible for checking the deposit balance before the withdrawal, or whether the Withdraw () function should be responsible for checking. If the "check balance" is the caller's responsibility, "the withdrawal amount is greater than the deposit amount" is a programming error and an uncontrolled exception should be used. If the "check balance" is the responsibility of the Withdraw () function, this exception must be thrown in the function.
Example: uncontrolled exceptions
An uncontrolled exception indicates that the caller is responsible for the check. First, check the calling code. It should not use the return value of the Withdraw () function, because the return value is only used to indicate programmer errors. If you see the following code:
Account account = new Account();if (account.Withdraw(100) == -1){ account.HandOverdran();}else{ account.DoTheUsualThing();}
Replace it with the following code:
Account account = new Account();if (!account.CanWithdraw(100)){ account.HandOverdran();}else{ account.Withdraw(100); account.DoTheUsualThing();}
Remove the error code and throw an exception when a program error occurs. Because this behavior is abnormal and rare, use the Wei statement to check this situation:
public void Withdraw(int amount){ if (amount > _balance) { throw new ArgumentException("Amount too large."); } _balance -= amount;}
Example: Controlled exceptions
The handling methods of controlled exceptions are slightly different. First, you can create a suitable exception:
class BalanceException:Exception{ }
Of course, it is okay not to create a new one here.
Then adjust the call end as follows:
Account account = new Account(); try{ account.Withdraw(100); account.DoTheUsualThing();}catch (BalanceException ex){ account.HandOverdran();}
Next, modify the Withdraw () function to indicate the error status with an exception:
public void Withdraw(int amount){ if (amount > _balance) { throw new BalanceException(); } _balance -= amount;}
Summary
Replacing the error code with an exception makes the code easier to understand.
15 Replace Exception with Test (Replace Exception with Test) Summary
You throw an exception in the face of conditions that a caller can check in advance.
Modify the caller so that the caller can check the caller before calling the function.
Motivation
Exceptions can help us avoid complicated error handling logic. However, exceptions can also be abused. "Exception" should only be used for abnormal and rare behaviors, that is, those that generate unexpected errors, rather than being a substitute for conditional checks.
Example
In the following example, A ResourcePool object is used to manage resources that are expensive to create and can be reused. This object has two "pools": one for saving available resources and the other for saving allocated resources. When a user requests a resource, the ResourcePool object retrieves a resource from the "available resource pool" and transfers the resource to the "allocated resource pool ". When a user releases a resource, the ResourcePool object should change the resource from the allocated resource pool to the available resource pool ". If the "available resource pool" cannot meet user requests, the ResourcePool object creates a new resource.
class ResourcePool{ private Stack<Resource> _available; private Stack<Resource> _allocated; public Resource GetResource() { Resource result; try { result = _available.Pop(); _allocated.Push(result); return result; } catch (Exception ex) { result = new Resource(); _allocated.Push(result); return result; } }}class Resource{}
In this case, "use up of available resources" is not an unexpected event, so we should not use exceptions to indicate this situation.
To remove the exception, first add an appropriate early test and handle the case where "the available resources are empty:
class ResourcePool{ private Stack<Resource> _available; private Stack<Resource> _allocated; public Resource GetResource() { Resource result; if (_available.Count == 0) { result = new Resource(); _allocated.Push(result); return result; } result = _available.Pop(); _allocated.Push(result); return result; }}class Resource{}
Here, you can sort out the condition code and use the condition lidate Duplicate Conditional Fragments:
class ResourcePool{ private Stack<Resource> _available; private Stack<Resource> _allocated; public Resource GetResource() { Resource result; if (_available.Count == 0) { result = new Resource(); } else { result = _available.Pop(); } _allocated.Push(result); return result; }}class Resource{}
Summary
Stage Summary
In object technology, the most popular concept is "interface ". Interfaces that are easy to understand and be used are the key to developing good object-oriented software.
The simplest and most important thing is to modify the function name. Name is a key tool for programmers to communicate with readers. As long as you can understand the functions of a program, you should use Rename Method to express what you know to others.
Function parameters play a very important role in interfaces. Add Parameter and Remove Parameter are common refactoring methods. Programmers who are new to object-oriented technology often use long parameter columns. However, using object technology, you can keep the parameter column brief. If multiple values from the same Object are passed as parameters, you can use Preserve Whole Object to replace them with a single Object, thus reducing the parameter column. If such an Object does not exist before, you can use Introduce Parameter Object to create it. If the function Parameter comes from an object that can be obtained by the function, Replace Parameter with Methods can be used to avoid passing parameters. If some parameters are used for selection in conditional expressions, You can implement Replace Parameter with Explicit Method. You can also use Parameterize Method to add parameters to several similar functions and merge them together.
It is a good habit to clearly separate the function of "modifying object state" from the function of "querying object state. If you see these two functions mixed together, you can use Separate Query from Modifier to Separate them.
A good interface only shows users what must be presented. If an interface exposes too many details, you can hide unnecessary exposed items to improve the interface quality. During refactoring, some things often need to be exposed temporarily, and then hidden by Hide Method and Remove Setting Method.
Constructor is often "troublesome" because it forces you to know the class of the object to be created, and you often do not need to know this. Replace Constructor with Factory Method can be used to avoid unnecessary information.
Like many modern programming languages, C # also has an exception handling mechanism, which makes error handling easier. Programmers who are not used to using exceptions often use error codes to indicate that the program is in trouble. Replace Error Code with Exception can be used to apply the new Exception feature. But sometimes exceptions are not the most appropriate choice. Replace Exception with Test should be implemented first.
To Be Continued ......