Study with me for Code Refactoring ( Story 4— Large Class of Bloaters)
Symptoms
Large class refers to a software design problem where a single class becomes too large and complex, difficult to understand, maintain and extend.
# Large Class
class LargeClass {
# Many class variables
# Many fields
# Many Methods
}
Treatment
To address this problem,
- developers can refactor the class by breaking it up into smaller
- by using design patterns such as the Single Responsibility Principle, the Open-Closed Principle, and the Liskov Substitution Principle
- Extract Class — helps reduce the class's size and complexity by moving some of its responsibilities and behaviors to a new class. Because of this, it makes a more modular and more maintainable design.
Problem
# Large Class before Extract Class
class Order {
var customerName: String = ""
var customerAddress: String = ""
var customerPhone: String = ""
var orderItems: List<String> = listOf()
var orderTotal: Double = 0.0
fun addItem(item: String, price: Double) {
orderItems.add(item)
orderTotal += price
}
fun removeItem(item: String) {
orderItems.remove(item)
}
}
/**
*Extract Class treatment
*create a new class and place the fields and methods responsible for the relevant functionality in it
**/
class Order {
var customer: Customer = Customer()
var orderItems: List<String> = listOf()
var orderTotal: Double = 0.0
fun addItem(item: String, price: Double) {
orderItems.add(item)
orderTotal += price
}
fun removeItem(item: String) {
orderItems.remove(item)
}
}
class Customer {
var name: String = ""
var address: String = ""
var phone: String = ""
}
Benefit
- more obvious and understandable
- Single Reason to change (SRP)
2. Extract SubClass — taking a class and breaking it down into many classes which become a subclass of the other. After this treatment, we can better be encapsulated in a separate class.
Problem
class Employee(var name: String, var salary: Double) {
fun printEmployee() {
println("Employee name: $name")
println("Employee salary: $salary")
}
fun calculateTax(): Double {
return salary * 0.1
}
fun calculateBonus(): Double {
return salary * 0.2
}
fun calculateBenefits(): Double {
return salary * 0.15
}
}
Treatment
abstract class Employee(var name: String, var salary: Double) {
abstract fun calculateTax(): Double
abstract fun calculateBonus(): Double
abstract fun calculateBenefits(): Double
}
class FullTimeEmployee(name: String, salary: Double) : Employee(name, salary) {
override fun calculateTax() = salary * 0.1
override fun calculateBonus() = salary * 0.2
override fun calculateBenefits() = salary * 0.15
override fun printEmployee() = println("FullTimeEmployee": $name)
}
class ContractEmployee(name: String, salary: Double,val contractPeriod:Int) : Employee(name, salary) {
override fun calculateTax() = salary * 0.15
override fun calculateBonus() = 0.0
override fun calculateBenefits() = salary * 0.10
override fun printEmployee() = println("ContractEmployee":$name)
}
Benefit
- trace bugs more easily and quickly
- Improving testability
- enhancing encapsulation
3. It has too complex functionalities and behaviors — use Extract Interface
Problem
class Employee {
fun calculatePay() { /* code */ }
fun printPaycheck() { /* code */ }
fun saveToDatabase() { /* code */ }
fun sendEmail() { /* code */ }
// many other methods
}
Treatment
// Interface extraction
interface PayrollOperations {
fun calculatePay()
fun printPaycheck()
}
class Employee : PayrollOperations {
override fun calculatePay() { /* code */ }
override fun printPaycheck() { /* code */ }
fun saveToDatabase() { /* code */ }
fun sendEmail() { /* code */ }
// other methods
}
Benefits
- Readability
- Maintainability
- Reducing complexity
- Improving Flexibility
- Enabling polymorphism
Notice, too many extracting classes, subclasses and interfaces tend to be more complex. Please write documentation. If you can’t, do some comments in this case and can produce them automatically with KDOC.
This is the end of story 4.
See you next time, bye-bye 👋
Story 1 — https://thawzintoe.medium.com/study-with-me-for-code-refactoring-story1-introduction-50d0f9b95cee
Story 2 — https://thawzintoe.medium.com/study-with-me-for-code-refactoring-story2-code-smell-4a5dbac61a0b