### Replace Parameter with Method Call - Python Example Source: https://sourcemaking.com/refactoring/replace-parameter-with-method-call A Python example of replacing parameters with method calls. The 'Before' code passes calculated 'seasonalDiscount' and 'fees'. The 'After' code simplifies the call by removing these parameters, suggesting the 'discountedPrice' function now computes them internally. ```python basePrice = quantity * itemPrice seasonalDiscount = self.getSeasonalDiscount() fees = self.getFees() finalPrice = discountedPrice(basePrice, seasonalDiscount, fees) ``` ```python basePrice = quantity * itemPrice finalPrice = discountedPrice(basePrice) ``` -------------------------------- ### Introduce Foreign Method: Python Example Source: https://sourcemaking.com/refactoring/introduce-foreign-method Demonstrates the 'Introduce Foreign Method' refactoring in Python. The logic for calculating the next day is moved into a private method '_nextDay', which accepts a 'Date' object. ```Python class Report: # ... def sendReport(self): nextDay = Date(self.previousEnd.getYear(), self.previousEnd.getMonth(), self.previousEnd.getDate() + 1) # ... class Report: # ... def sendReport(self): newStart = self._nextDay(self.previousEnd) # ... def _nextDay(self, arg): return Date(arg.getYear(), arg.getMonth(), arg.getDate() + 1) ``` -------------------------------- ### Split Temporary Variable: PHP Example Source: https://sourcemaking.com/refactoring/split-temporary-variable Shows the application of the Split Temporary Variable refactoring in PHP. The example transforms a single '$temp' variable used for two distinct calculations into '$perimeter' and '$area' for improved code structure. ```PHP $temp = 2 * ($this->height + $this->width); echo $temp; $temp = $this->height * $this->width; echo $temp; ``` ```PHP $perimeter = 2 * ($this->height + $this->width); echo $perimeter; $area = $this->height * $this->width; echo $area; ``` -------------------------------- ### Split Temporary Variable: Python Example Source: https://sourcemaking.com/refactoring/split-temporary-variable A Python example demonstrating the Split Temporary Variable refactoring. It converts a single 'temp' variable, used for calculating perimeter and area, into two separate variables, 'perimeter' and 'area', for better code clarity. ```Python temp = 2 * (height + width) print(temp) temp = height * width print(temp) ``` ```Python perimeter = 2 * (height + width) print(perimeter) area = height * width print(area) ``` -------------------------------- ### Substitute Algorithm Implementation Source: https://sourcemaking.com/refactoring/substitute-algorithm Demonstrates replacing a verbose conditional search algorithm with a more concise collection-based approach. The examples show the 'before' state with multiple if-statements and the 'after' state using optimized lookup mechanisms. ```Java // Before String foundPerson(String[] people){ for (int i = 0; i < people.length; i++) { if (people[i].equals("Don")){ return "Don"; } if (people[i].equals("John")){ return "John"; } if (people[i].equals("Kent")){ return "Kent"; } } return ""; } // After String foundPerson(String[] people){ List candidates = Arrays.asList(new String[] {"Don", "John", "Kent"}); for (int i=0; i < people.length; i++) { if (candidates.contains(people[i])) { return people[i]; } } return ""; } ``` ```C# // Before string FoundPerson(string[] people) { for (int i = 0; i < people.Length; i++) { if (people[i].Equals("Don")) { return "Don"; } if (people[i].Equals("John")) { return "John"; } if (people[i].Equals("Kent")) { return "Kent"; } } return String.Empty; } // After string FoundPerson(string[] people) { List candidates = new List() {"Don", "John", "Kent"}; for (int i = 0; i < people.Length; i++) { if (candidates.Contains(people[i])) { return people[i]; } } return String.Empty; } ``` ```PHP // Before function foundPerson(array $people){ for ($i = 0; $i < count($people); $i++) { if ($people[$i] === "Don") { return "Don"; } if ($people[$i] === "John") { return "John"; } if ($people[$i] === "Kent") { return "Kent"; } } return ""; } // After function foundPerson(array $people){ foreach (["Don", "John", "Kent"] as $needle) { $id = array_search($needle, $people, true); if ($id !== false) { return $people[$id]; } } return ""; } ``` ```Python # Before def foundPerson(people): for i in range(len(people)): if people[i] == "Don": return "Don" if people[i] == "John": return "John" if people[i] == "Kent": return "Kent" return "" # After def foundPerson(people): candidates = ["Don", "John", "Kent"] return next((p for p in people if p in candidates), "") ``` ```TypeScript // Before foundPerson(people: string[]): string{ for (let person of people) { if (person.equals("Don")){ return "Don"; } if (person.equals("John")){ return "John"; } if (person.equals("Kent")){ return "Kent"; } } return ""; } // After foundPerson(people: string[]): string{ let candidates = ["Don", "John", "Kent"]; for (let person of people) { if (candidates.includes(person)) { return person; } } return ""; } ``` -------------------------------- ### Introduce Foreign Method: C# Example Source: https://sourcemaking.com/refactoring/introduce-foreign-method Illustrates the 'Introduce Foreign Method' refactoring in C#. The logic for calculating the next day is moved from the 'SendReport' method into a new private static method 'NextDay', which accepts a 'DateTime' object. ```C# class Report { // ... void SendReport() { DateTime nextDay = previousEnd.AddDays(1); // ... } } class Report { // ... void SendReport() { DateTime nextDay = NextDay(previousEnd); // ... } private static DateTime NextDay(DateTime date) { return date.AddDays(1); } } ``` -------------------------------- ### Introduce Foreign Method: PHP Example Source: https://sourcemaking.com/refactoring/introduce-foreign-method Shows the 'Introduce Foreign Method' refactoring in PHP. The date manipulation logic is extracted into a private static method 'nextWeek', which takes a 'DateTime' object and returns the date one week later. ```PHP class Report { // ... public function sendReport() { $previousDate = clone $this->previousDate; $paymentDate = $previousDate->modify("+7 days"); // ... } } class Report { // ... public function sendReport() { $paymentDate = self::nextWeek($this->previousDate); // ... } /** * Foreign method. Should be in Date. */ private static function nextWeek(DateTime $arg) { $previousDate = clone $arg; return $previousDate->modify("+7 days"); } } ``` -------------------------------- ### Decompose Conditional: PHP Example Source: https://sourcemaking.com/refactoring/decompose-conditional Shows how to refactor a PHP conditional. The original code with date comparisons and rate calculations is replaced by calls to `isSummer`, `summerCharge`, and `winterCharge` methods for better readability. ```php if ($date->before(SUMMER_START) || $date->after(SUMMER_END)) { $charge = $quantity * $winterRate + $winterServiceCharge; } else { $charge = $quantity * $summerRate; } // After refactoring if (isSummer($date)) { $charge = summerCharge($quantity); } else { $charge = winterCharge($quantity); } ``` -------------------------------- ### Introduce Foreign Method: Java Example Source: https://sourcemaking.com/refactoring/introduce-foreign-method Demonstrates the 'Introduce Foreign Method' refactoring in Java. The 'nextDay' method, originally part of the 'Report' class logic, is extracted into a private static method within the same class, taking a 'Date' object as an argument. ```Java class Report { // ... void sendReport() { Date nextDay = new Date(previousEnd.getYear(), previousEnd.getMonth(), previousEnd.getDate() + 1); // ... } } class Report { // ... void sendReport() { Date newStart = nextDay(previousEnd); // ... } private static Date nextDay(Date arg) { return new Date(arg.getYear(), arg.getMonth(), arg.getDate() + 1); } } ``` -------------------------------- ### Extract Variable Refactoring: Python Example Source: https://sourcemaking.com/refactoring/extract-variable Demonstrates the Extract Variable refactoring in Python, simplifying a multi-part conditional expression by assigning intermediate results to named variables, enhancing code readability. ```python def renderBanner(self): isMacOs = self.platform.toUpperCase().indexOf("MAC") > -1 isIE = self.browser.toUpperCase().indexOf("IE") > -1 wasResized = self.resize > 0 if isMacOs and isIE and self.wasInitialized() and wasResized: # do something ``` -------------------------------- ### Introduce Foreign Method: TypeScript Example Source: https://sourcemaking.com/refactoring/introduce-foreign-method Illustrates the 'Introduce Foreign Method' refactoring in TypeScript. The 'nextDay' function is extracted as a private static method within the 'Report' class, taking a 'Date' object as input. ```TypeScript class Report { // ... sendReport(): void { let nextDay: Date = new Date(previousEnd.getYear(), previousEnd.getMonth(), previousEnd.getDate() + 1); // ... } } class Report { // ... sendReport() { let newStart: Date = nextDay(previousEnd); // ... } private static nextDay(arg: Date): Date { return new Date(arg.getFullYear(), arg.getMonth(), arg.getDate() + 1); } } ``` -------------------------------- ### Extract Variable Refactoring: C# Example Source: https://sourcemaking.com/refactoring/extract-variable Shows how to apply the Extract Variable refactoring in C# by creating descriptive variables for parts of a complex conditional. This makes the logic within the 'if' statement easier to follow. ```csharp void RenderBanner() { readonly bool isMacOs = platform.ToUpper().IndexOf("MAC") > -1; readonly bool isIE = browser.ToUpper().IndexOf("IE") > -1; readonly bool wasResized = resize > 0; if (isMacOs && isIE && wasInitialized() && wasResized) { // do something } } ``` -------------------------------- ### Inline Temp Refactoring across multiple languages Source: https://sourcemaking.com/refactoring/inline-temp Demonstrates the Inline Temp refactoring pattern by replacing a temporary variable holding a method result with the direct method call. Examples are provided for Java, C#, PHP, Python, and TypeScript. ```Java boolean hasDiscount(Order order) { return order.basePrice() > 1000; } ``` ```C# bool HasDiscount(Order order) { return order.BasePrice() > 1000; } ``` ```PHP return $anOrder->basePrice() > 1000; ``` ```Python def hasDiscount(order): return order.basePrice() > 1000 ``` ```TypeScript hasDiscount(order: Order): boolean { return order.basePrice() > 1000; } ``` -------------------------------- ### Replace Parameter with Method Call - PHP Example Source: https://sourcemaking.com/refactoring/replace-parameter-with-method-call Shows the refactoring in PHP, where parameters for seasonal discounts and fees are removed. The 'Before' code explicitly passes these calculated values, while the 'After' code assumes the 'discountedPrice' method now internally handles these calculations. ```php $basePrice = $this->quantity * $this->itemPrice; $seasonDiscount = $this->getSeasonalDiscount(); $fees = $this->getFees(); $finalPrice = $this->discountedPrice($basePrice, $seasonDiscount, $fees); ``` ```php $basePrice = $this->quantity * $this->itemPrice; $finalPrice = $this->discountedPrice($basePrice); ``` -------------------------------- ### Split Temporary Variable: Java Example Source: https://sourcemaking.com/refactoring/split-temporary-variable Demonstrates splitting a temporary variable in Java. The original code reuses 'temp' for perimeter and area calculations. The refactored code uses 'perimeter' and 'area' for clarity and maintainability. ```Java double temp = 2 * (height + width); System.out.println(temp); temp = height * width; System.out.println(temp); ``` ```Java final double perimeter = 2 * (height + width); System.out.println(perimeter); final double area = height * width; System.out.println(area); ``` -------------------------------- ### Replace Parameter with Method Call - TypeScript Example Source: https://sourcemaking.com/refactoring/replace-parameter-with-method-call Demonstrates the refactoring in TypeScript. The 'Before' code passes calculated 'seasonDiscount' and 'fees' as arguments. The 'After' code removes these parameters, implying that the 'discountedPrice' function now handles the calculation internally. ```typescript let basePrice = quantity * itemPrice; const seasonDiscount = this.getSeasonalDiscount(); const fees = this.getFees(); const finalPrice = discountedPrice(basePrice, seasonDiscount, fees); ``` ```typescript let basePrice = quantity * itemPrice; let finalPrice = discountedPrice(basePrice); ``` -------------------------------- ### Split Temporary Variable: C# Example Source: https://sourcemaking.com/refactoring/split-temporary-variable Illustrates splitting a temporary variable in C#. The refactoring replaces the reused 'temp' variable with 'perimeter' and 'area', enhancing code readability and making it easier to manage different calculations. ```C# double temp = 2 * (height + width); Console.WriteLine(temp); temp = height * width; Console.WriteLine(temp); ``` ```C# readonly double perimeter = 2 * (height + width); Console.WriteLine(perimeter); readonly double area = height * width; Console.WriteLine(area); ``` -------------------------------- ### Extract Variable Refactoring: PHP Example Source: https://sourcemaking.com/refactoring/extract-variable Illustrates the Extract Variable refactoring in PHP, where complex conditions within an 'if' statement are broken down into individual variables for better clarity and maintainability. ```php $isMacOs = $platform->toUpperCase()->indexOf("MAC") > -1; $isIE = $browser->toUpperCase()->indexOf("IE") > -1; $wasResized = $this->resize > 0; if ($isMacOs && $isIE && $this->wasInitialized() && $wasResized) { // do something } ``` -------------------------------- ### Extract Variable Refactoring: TypeScript Example Source: https://sourcemaking.com/refactoring/extract-variable Shows the Extract Variable refactoring in TypeScript, where a complex conditional is made more readable by assigning its components to constants. This improves the clarity of the 'if' statement. ```typescript renderBanner(): void { const isMacOs = platform.toUpperCase().indexOf("MAC") > -1; const isIE = browser.toUpperCase().indexOf("IE") > -1; const wasResized = resize > 0; if (isMacOs && isIE && wasInitialized() && wasResized) { // do something } } ``` -------------------------------- ### Introduce Null Object Pattern Implementation Source: https://sourcemaking.com/refactoring/introduce-null-object Demonstrates the refactoring process across multiple languages by creating a NullCustomer subclass to handle missing customer data. This replaces explicit null checks with a polymorphic approach that simplifies client code. ```Java class NullCustomer extends Customer { boolean isNull() { return true; } Plan getPlan() { return new NullPlan(); } } // Replace null values with Null-object. customer = (order.customer != null) ? order.customer : new NullCustomer(); // Use Null-object as if it's normal subclass. plan = customer.getPlan(); ``` ```C# public sealed class NullCustomer: Customer { public override bool IsNull { get { return true; } } public override Plan GetPlan() { return new NullPlan(); } } // Replace null values with Null-object. customer = order.customer ?? new NullCustomer(); // Use Null-object as if it's normal subclass. plan = customer.GetPlan(); ``` ```PHP class NullCustomer extends Customer { public function isNull() { return true; } public function getPlan() { return new NullPlan(); } } // Replace null values with Null-object. $customer = ($order->customer !== null) ? $order->customer : new NullCustomer; // Use Null-object as if it's normal subclass. $plan = $customer->getPlan(); ``` ```Python class NullCustomer(Customer): def isNull(self): return True def getPlan(self): return self.NullPlan() # Replace null values with Null-object. customer = order.customer or NullCustomer() # Use Null-object as if it's normal subclass. plan = customer.getPlan(); ``` ```TypeScript class NullCustomer extends Customer { isNull(): boolean { return true; } getPlan(): Plan { return new NullPlan(); } } // Replace null values with Null-object. let customer = (order.customer != null) ? order.customer : new NullCustomer(); // Use Null-object as if it's normal subclass. plan = customer.getPlan(); ``` -------------------------------- ### Extract Variable Refactoring: Java Example Source: https://sourcemaking.com/refactoring/extract-variable Demonstrates refactoring a complex conditional statement in Java by extracting boolean expressions into separate, named variables. This improves the readability of the 'if' condition. ```java void renderBanner() { final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1; final boolean isIE = browser.toUpperCase().indexOf("IE") > -1; final boolean wasResized = resize > 0; if (isMacOs && isIE && wasInitialized() && wasResized) { // do something } } ``` -------------------------------- ### Replace Constructor with Factory Method (PHP) Source: https://sourcemaking.com/refactoring/replace-constructor-with-factory-method Shows how to refactor a PHP constructor into a static factory method. This approach improves object instantiation by abstracting complex creation processes and allowing for flexible return types. ```PHP class Employee { // ... public function __construct($type) { $this->type = $type; } // ... } ``` ```PHP class Employee { // ... static public function create($type) { $employee = new Employee($type); // do some heavy lifting. return $employee; } // ... } ``` -------------------------------- ### Pull Up Constructor Body across multiple languages Source: https://sourcemaking.com/refactoring/pull-up-constructor-body Demonstrates the refactoring process of moving common initialization logic from subclass constructors to a superclass constructor. This pattern is implemented using language-specific syntax for constructor delegation. ```Java class Manager extends Employee { public Manager(String name, String id, int grade) { super(name, id); this.grade = grade; } // ... } ``` ```C# public class Manager: Employee { public Manager(string name, string id, int grade): base(name, id) { this.grade = grade; } // ... } ``` ```PHP class Manager extends Employee { public function __construct($name, $id, $grade) { parent::__construct($name, $id); $this->grade = $grade; } // ... } ``` ```Python class Manager(Employee): def __init__(self, name, id, grade): Employee.__init__(name, id) self.grade = grade # ... ``` ```TypeScript class Manager extends Employee { constructor(name: string, id: string, grade: number) { super(name, id); this.grade = grade; } // ... } ``` -------------------------------- ### Replace Parameter with Method Call - Java Example Source: https://sourcemaking.com/refactoring/replace-parameter-with-method-call Demonstrates replacing parameters with method calls in Java. The 'Before' code passes calculated values like season discount and fees as separate arguments. The 'After' code simplifies this by removing these parameters, implying the calculation is now done within the 'discountedPrice' method. ```java int basePrice = quantity * itemPrice; double seasonDiscount = this.getSeasonalDiscount(); double fees = this.getFees(); double finalPrice = discountedPrice(basePrice, seasonDiscount, fees); ``` ```java int basePrice = quantity * itemPrice; double finalPrice = discountedPrice(basePrice); ``` -------------------------------- ### Decompose Conditional: C# Example Source: https://sourcemaking.com/refactoring/decompose-conditional Demonstrates refactoring a C# conditional statement. The complex date comparison and charge calculation are moved into `isSummer`, `SummerCharge`, and `WinterCharge` methods, enhancing code clarity. ```csharp if (date < SUMMER_START || date > SUMMER_END) { charge = quantity * winterRate + winterServiceCharge; } else { charge = quantity * summerRate; } // After refactoring if (isSummer(date)) { charge = SummerCharge(quantity); } else { charge = WinterCharge(quantity); } ``` -------------------------------- ### Encapsulate Field: PHP Example Source: https://sourcemaking.com/refactoring/encapsulate-field Illustrates encapsulating a public '$name' property in PHP by making it private and creating public 'getName' and 'setName' methods. This adheres to encapsulation principles in PHP. ```PHP public $name; // Refactored: private $name; public getName() { return $this->name; } public setName($arg) { $this->name = $arg; } ``` -------------------------------- ### Introduce Assertion in getExpenseLimit Method Source: https://sourcemaking.com/refactoring/introduce-assertion Demonstrates replacing implicit logic assumptions with explicit assertion checks across multiple programming languages. This ensures that required conditions for the method to function correctly are validated at runtime. ```Java double getExpenseLimit() { Assert.isTrue(expenseLimit != NULL_EXPENSE || primaryProject != null); return (expenseLimit != NULL_EXPENSE) ? expenseLimit: primaryProject.getMemberExpenseLimit(); } ``` ```C# double GetExpenseLimit() { Assert.IsTrue(expenseLimit != NULL_EXPENSE || primaryProject != null); return (expenseLimit != NULL_EXPENSE) ? expenseLimit: primaryProject.GetMemberExpenseLimit(); } ``` ```PHP function getExpenseLimit() { assert($this->expenseLimit !== NULL_EXPENSE || isset($this->primaryProject)); return ($this->expenseLimit !== NULL_EXPENSE) ? $this->expenseLimit: $this->primaryProject->getMemberExpenseLimit(); } ``` ```Python def getExpenseLimit(self): assert (self.expenseLimit != NULL_EXPENSE) or (self.primaryProject != None) return self.expenseLimit if (self.expenseLimit != NULL_EXPENSE) else \ self.primaryProject.getMemberExpenseLimit() ``` ```TypeScript getExpenseLimit(): number { if (!(expenseLimit != NULL_EXPENSE || (typeof primaryProject !== 'undefined' && primaryProject))) { console.error("Assertion failed: getExpenseLimit()"); } return (expenseLimit != NULL_EXPENSE) ? expenseLimit: primaryProject.getMemberExpenseLimit(); } ``` -------------------------------- ### Encapsulate Field: Java Example Source: https://sourcemaking.com/refactoring/encapsulate-field Demonstrates encapsulating a public 'name' field in a Java class by making it private and adding 'getName' and 'setName' methods. This ensures controlled access to the field. ```Java class Person { public String name; } // Refactored: class Person { private String name; public String getName() { return name; } public void setName(String arg) { name = arg; } } ``` -------------------------------- ### Replace Constructor with Factory Method (C#) Source: https://sourcemaking.com/refactoring/replace-constructor-with-factory-method Demonstrates refactoring a C# constructor into a static factory method. This pattern enhances object creation by encapsulating complex logic and potentially returning subclasses. ```C# public class Employee { public Employee(int type) { this.type = type; } // ... } ``` ```C# public class Employee { public static Employee Create(int type) { employee = new Employee(type); // Do some heavy lifting. return employee; } // ... } ```