انت هنا الان : شبكة جامعة بابل > موقع الكلية > نظام التعليم الالكتروني > مشاهدة المحاضرة
الكلية كلية تكنولوجيا المعلومات
القسم قسم البرامجيات
المرحلة 3
أستاذ المادة احمد خلفة عبيد العجيلي
30/06/2018 10:27:01
Definition I Refactoring is changing a software system by improving its internal structure without changing its external behaviour, i.e. it is a technique to restructure the code in a disciplined way I It makes the software easier to understand and cheaper to modify. I Refactoring can help a team recover code that was previously written off as an unmaintainable mess - spaghetti code I Code that is easier to understand is easier to maintain, and code that is harder to understand is harder to maintain I Refactoring can also help a programmer find bugs more quickly 3 / 17 The code example In this example, a programming team in an investment bank is reviewing a block of code for a feature that calculates fees and bonuses for brokers who sell a certain kind of investment account to their corporate clients. The programmer who wrote the code uses refactoring to clarify problems that were identified during the code review. The inspection team performed a code review on this block of Java code, which included the class Account and a function calculateFee from a different class: 4 / 17 Continued... 1 class Account { 2 f loa t p r i n c i p a l ; 3 f loa t rate ; 4 int daysAct ive ; 5 int accountType ; 6 public s t a t i c f i n a l int STANDARD = 0; 7 public s t a t i c f i n a l int BUDGET = 1; 8 public s t a t i c f i n a l int PREMIUM = 2; 9 public s t a t i c f i n a l int PREMIUM_PLUS = 3; 10 } 11 f loa t calculateFee ( Account accounts [ ] ) { 12 f loa t totalFee = 0; 13 Account account ; 14 for ( int i = 0; i < accounts . length ; i ++) { 15 account = accounts [ i ] ; 16 i f ( account . accountType == Account .PREMIUM | | account . accountType == Account .PREMIUM_PLUS) { 17 totalFee += .0125 * ( account . p r i n c i p a l * Math . exp ( account . rate * ( account . daysAct ive / 365.25) ) ?? account . p r i n c i p a l ) ; 18 } 19 } 20 return totalFee ; 21 } 5 / 17 The Extract Method refactoring When refactor? I You have a code fragment that can be grouped together I Turn the fragment into a method whose name explains the purpose of the method Motivation I Extract Method is one of the most common refactorings done I Looking at a method that is too long or look at code that needs a comment to understand its purpose I Then turn that fragment of code into its own method 6 / 17 Continued... Mechanics I Create a new method, and name it after the intention of the method (name it by what it does, not by how it does it). I Copy the extracted code from the source method into the new target method. I See whether any temporary variables are used only within this extracted code. If so, declare them in the target method as temporary variables. I Pass into the target method as parameters local-scope variables that are read from the extracted code. I Compile when you have dealt with all the locally-scoped variables. I Replace the extracted code in the source method with a call to the target method. I Compile and test. 7 / 17 The refactored code 1 class Account { 2 f loa t p r i n c i p a l ; 3 f loa t rate ; 4 int daysAct ive ; 5 int accountType ; 6 public s t a t i c f i n a l int STANDARD = 0; 7 public s t a t i c f i n a l int BUDGET = 1; 8 public s t a t i c f i n a l int PREMIUM = 2; 9 public s t a t i c f i n a l int PREMIUM_PLUS = 3; 10 f loa t interes tEarned ( ) { 11 return ( p r i n c i p a l * ( f loa t ) Math . exp ( rate * ( daysAct ive / 365.25) ) ) ?? p r i n c i p a l ; 12 } 13 } 14 f loa t calculateFee ( Account accounts [ ] ) { 15 f loa t totalFee = 0; 16 Account account ; 17 for ( int i = 0; i < accounts . length ; i ++) { 18 account = accounts [ i ] ; 19 i f ( account . accountType == Account .PREMIUM | | account . accountType == Account .PREMIUM_PLUS) 20 totalFee += .0125 * account . interes tEarned ( ) ; 21 } 22 return totalFee ; 23 } 8 / 17 Replace Magic Number with Symbolic Constant When refactor? I You have a literal number with a particular meaning I Create a constant, name it after the meaning, and replace the number with it Motivation I Magic numbers are one of oldest ills in computing I They are numbers with special values that usually are not obvious I Magic numbers are really nasty when you need to reference the same logical number in more than one place I If the numbers might ever change, making the change is a nightmare 9 / 17 Continued... Mechanics I Declare a constant and set it to the value of the magic number I Find all occurrences of the magic number I See whether the magic number matches the usage of the constant; if it does, change the magic number to use the constant I When all magic numbers are changed, compile and test. At this point all should work as if nothing has been changed 10 / 17 The refactored code 1 class Account { 2 f loa t p r i n c i p a l ; 3 f loa t rate ; 4 int daysAct ive ; 5 int accountType ; 67 public s t a t i c f i n a l int STANDARD = 0; 8 public s t a t i c f i n a l int BUDGET = 1; 9 public s t a t i c f i n a l int PREMIUM = 2; 10 public s t a t i c f i n a l int PREMIUM_PLUS = 3; 11 12 f loa t interes tEarned ( ) { 13 return ( p r i n c i p a l * ( f loa t ) Math . exp ( rate * ( daysAct ive / 365.25) ) ) ?? p r i n c i p a l ; 14 } 15 } 16 f loa t calculateFee ( Account accounts [ ] ) { 17 f loa t totalFee = 0; 18 Account account ; 19 for ( int i = 0; i < accounts . length ; i ++) { 20 account = accounts [ i ] ; 21 i f ( account . accountType == Account .PREMIUM | | 22 account . accountType == Account .PREMIUM_PLUS) 23 totalFee += BROKER_FEE_PERCENT * account . interes tEarned ( ) ; 24 } 25 return totalFee ; 26 } 27 s t a t i c f i n a l double BROKER_FEE_PERCENT = 0.0125; 11 / 17 The Decompose Conditional refactoring When refactor? I You have a complicated conditional (if-then-else) statement I Extract methods from the condition, then part, and else part Motivation I One of the most common areas of complexity in a program lies in complex conditional logic Mechanics I Extract the condition into its own method I Extract the then part and the else part into their own methods 12 / 17 The refactored code 1 class Account { 2 f loa t p r i n c i p a l ; 3 f loa t rate ; 4 int daysAct ive ; 5 int accountType ; 7 public s t a t i c f i n a l int STANDARD = 0; 8 public s t a t i c f i n a l int BUDGET = 1; 9 public s t a t i c f i n a l int PREMIUM = 2; 10 public s t a t i c f i n a l int PREMIUM_PLUS = 3; 11 f loa t interes tEarned ( ) { 12 return ( p r i n c i p a l * ( f loa t ) Math . exp ( rate * ( daysAct ive / 365.25) ) ) ?? p r i n c i p a l ; 13 } 14 public boolean isPremium ( ) { 15 i f ( accountType == Account .PREMIUM | | accountType == Account .PREMIUM_PLUS) 16 return true ; 17 else 18 return false ; 19 } 20 } 21 f loa t calculateFee ( Account accounts [ ] ) { 22 f loa t totalFee = 0; 23 Account account ; 24 for ( int i = 0; i < accounts . length ; i ++) { 25 account = accounts [ i ] ; 26 i f ( account . isPremium ( ) ) 27 totalFee += BROKER_FEE_PERCENT * account . interes tEarned ( ) ; 28 } 29 return totalFee ; 30 } 31 s t a t i c f i n a l double BROKER_FEE_PERCENT = 0.0125; 13 / 17 The Introduce Explaining Variable refactoring When refactor? I You have a complicated expression I Put the result of the expression, or parts of the expression, in a temporary variable with a name that explains the purpose Motivation I Expressions can become very complex and hard to read I In such situations temporary variables can be helpful to break down the expression into something more manageable 14 / 17 Continued... Mechanics I Declare a final temporary variable, and set it to the result of part of the complex expression I Replace the result part of the expression with the value of the temp. I Compile and test I Repeat for other parts of the expression 15 / 17 The refactored code 1 class Account { 2 f loa t p r i n c i p a l ; 3 f loa t rate ; 4 int daysAct ive ; 5 int accountType ; 7 public s t a t i c f i n a l int STANDARD = 0; 8 public s t a t i c f i n a l int BUDGET = 1; 9 public s t a t i c f i n a l int PREMIUM = 2; 10 public s t a t i c f i n a l int PREMIUM_PLUS = 3; 12 f loa t interes tEarned ( ) { 13 f loa t years = daysAct ive / ( f loa t ) 365.25; 14 f loa t compoundInterest = p r i n c i p a l * ( f loa t ) Math . exp ( rate * years ) ; 15 return ( compoundInterest ?? p r i n c i p a l ) ; 16 } 17 public boolean isPremium ( ) { 18 i f ( accountType == Account .PREMIUM | | accountType == Account .PREMIUM_PLUS) 19 return true ; 20 else 21 return false ; 22 } 23 } 16 / 17 Continued... 24 f loa t calculateFee ( Account accounts [ ] ) { 25 f loa t totalFee = 0; 26 Account account ; 27 for ( int i = 0; i < accounts . length ; i ++) { 28 account = accounts [ i ] ; 29 i f ( account . isPremium ( ) ) 30 totalFee += BROKER_FEE_PERCENT * account . interes tEarned ( ) ; 31 } 32 return totalFee ; 33 } 34 s t a t i c f i n a l double BROKER_FEE_PERCENT = 0.0125; 17 / 17
المادة المعروضة اعلاه هي مدخل الى المحاضرة المرفوعة بواسطة استاذ(ة) المادة . وقد تبدو لك غير متكاملة . حيث يضع استاذ المادة في بعض الاحيان فقط الجزء الاول من المحاضرة من اجل الاطلاع على ما ستقوم بتحميله لاحقا . في نظام التعليم الالكتروني نوفر هذه الخدمة لكي نبقيك على اطلاع حول محتوى الملف الذي ستقوم بتحميله .
|