Taming the Beast: A Guide to Identifying and Eliminating Bloaters Code Smells in Your Software

Taming the Beast: A Guide to Identifying and Eliminating Bloaters Code Smells in Your Software


As we venture into the ever-evolving realm of software development, we must revisit the coding principles we've previously explored. In a past discussion on coding smells (Don’t fall in love with your code), we delved into the intricacies of identifying and mitigating issues that impact the maintainability and efficiency of our codebase. Today, we build upon the insights gained from that earlier exploration, taking another step toward refining our understanding and addressing new challenges in the pursuit of cleaner, more robust code


Bloaters are a type of code smell that refers to pieces of code that have grown excessively large or complex, making them harder to understand, maintain, and modify. They typically indicate areas where the code could be optimized and streamlined.


  1. Data Clumps:

  • Problem: A class has a method that takes a large number of parameters, many of which are related to each other. This can make the method difficult to read and understand, and it can also lead to errors.

class Customer {
  String name;
  String address;
  String city;
  String state;
  String zip;
  String phone;
  String email;

  Customer(
      this.name, this.address, this.city, this.state, this.zip, this.phone, this.email);
}

void main() {
  var customer = Customer(
      'John Doe',
      '123 Main Street',
      'Anytown',
      'CA',
      '12345',
      '0123456789',
      '[email protected]');

  // This method takes a lot of parameters, many of which are related to each other.
  void updateCustomer(String name, String address, String city, String state, String zip, String phone, String email) {
    customer.name = name;
    customer.address = address;
    customer.city = city;
    customer.state = state;
    customer.zip = zip;
    customer.phone = phone;
    customer.email = email;
  }

  // This code is difficult to read and understand, and it is also easy to make mistakes when updating the customer's information.
}
        

  • Solution: Extract the related parameters into a separate object. This will make the method easier to read and understand, and it will also reduce the risk of errors.

class Customer {
  String name;
  Address address;
  String phone;
  String email;

  Customer(this.name, this.address, this.phone, this.email);
}

class Address {
  String street;
  String city;
  String state;
  String zip;

  Address(this.street, this.city, this.state, this.zip);
}

void main() {
  var customer = Customer(
      'John Doe',
      Address('123 Main Street', 'Anytown', 'CA', '12345'),
      '0123456789',
      '[email protected]');

  // This method now takes fewer parameters, and it is easier to read and understand.
  void updateCustomer(String name, Address address, String phone, String email) {
    customer.name = name;
    customer.address = address;
    customer.phone = phone;
    customer.email = email;
  }

  // This code is now easier to read and understand, and it is also less likely to contain mistakes.
}        

2. Large Class :

  • Problem: A class has more than 1,000 lines of code. This can make the class difficult to read and understand, and it can also lead to errors.

class Customer {
  String name;
  String address;
  String city;
  String state;
  String zip;
  String phone;
  String email;
  List<Order> orders;

  Customer(
      this.name, this.address, this.city, this.state, this.zip, this.phone, this.email, this.orders);

  // This class has more than 1,000 lines of code, which makes it difficult to read and understand.
}        

  • Solution: Break the class into smaller, more manageable classes. This will make the class easier to read and understand, and it will also reduce the risk of errors.

class Customer {
  String name;
  String address;
  String city;
  String state;
  String zip;
  String phone;
  String email;

  Customer(
      this.name, this.address, this.city, this.state, this.zip, this.phone, this.email);
}

class Order {
  String id;
  String customerName;
  String customerAddress;
  String customerCity;
  String customerState;
  String customerZip;
  String customerPhone;
  String customerEmail;
  List<Product> products;

  Order(
      this.id,
      this.customerName,
      this.customerAddress,
      this.customerCity,
      this.customerState,
      this.customerZip,
      this.customerPhone,
      this.customerEmail,
      this.products);
}

class Product {
  String id;
  String name;
  double price;

  Product(this.id, this.name, this.price);
}        

3. Long Method:

  • Problem: A method has more than 100 lines of code. This can make the method difficult to read and understand, and it can also lead to errors.

class Customer {
  String name;
  String address;
  String city;
  String state;
  String zip;
  String phone;
  String email;

  Customer(
      this.name, this.address, this.city, this.state, this.zip, this.phone, this.email);

  // This method has more than 100 lines of code, which makes it difficult to read and understand.
  void updateCustomer(String name, String address, String city, String state, String zip, String phone, String email) {
    if (name != null) {
      this.name = name;
    }
    if (address != null) {
      this.address = address;
    }
    if (city != null) {
      this.city = city;
    }
    if (state != null) {
      this.state = state;
    }
    if (zip != null) {
      this.zip = zip;
    }
    if (phone != null) {
      this.phone = phone;
    }
    if (email != null) {
      this.email = email;
    }
  }
}        

  • Solution: Break the method into smaller, more focused methods. This will make the method easier to read and understand, and it will also reduce the risk of errors.

class Customer {
  String name;
  String address;
  String city;
  String state;
  String zip;
  String phone;
  String email;

  Customer(
      this.name, this.address, this.city, this.state, this.zip, this.phone, this.email);

  // This method now has fewer lines of code, and it is easier to read and understand.
  void updateName(String name) {
    this.name = name;
  }

  void updateAddress(String address) {
    this.address = address;
  }

  void updateCity(String city) {
    this.city = city;
  }

  void updateState(String state) {
    this.state = state;
  }

  void updateZip(String zip) {
    this.zip = zip;
  }

  void updatePhone(String phone) {
    this.phone = phone;
  }

  void updateEmail(String email) {
    this.email = email;
  }
}        

4. Long Parameter List:

  • Problem: A long list of parameters makes the function signature complex and harder to read. Developers may find it challenging to understand the purpose of each parameter and their respective roles in the function. This reduces code readability and can lead to misunderstandings, making it difficult for developers (including the original author) to comprehend the function's behavior.

class Rectangle {
  double calculateArea(double length, double width, String color, bool highlight) {
    // Calculation logic here
    return length * width;
  }
}

void main() {
  var rectangle = Rectangle();

  // Calling the function with a long parameter list
  var area = rectangle.calculateArea(10.0, 5.0, 'blue', true);
  print('Area: $area');
}
        

  • Solution: Create a Class or Structure bundle related parameters into a class or structure. Pass an Instance Instead of passing individual parameters, pass an instance of the class or structure. Group Related Parameters If possible, group related parameters into smaller logical units. Use Named Parameters If your language supports it, use named parameters to make function calls more readable.

class Rectangle {
  double calculateArea(RectangleProperties properties) {
    // Calculation logic here
    return properties.length * properties.width;
  }
}

class RectangleProperties {
  final double length;
  final double width;
  final String color;
  final bool highlight;

  RectangleProperties(this.length, this.width, this.color, this.highlight);
}

void main() {
  var rectangle = Rectangle();

  // Creating a RectangleProperties object
  var properties = RectangleProperties(10.0, 5.0, 'blue', true);

  // Calling the function with a single parameter
  var area = rectangle.calculateArea(properties);
  print('Area: $area');
}        
Addressing bloaters through refactoring techniques helps to streamline code, improve its maintainability, and reduce complexity, making it easier to understand and work with in the long run.



Mahmoud Elsadany

Lead Mobile Engineer | MSc

11 个月

Keep it up ya NINJA ????

Omar Abdelazeem

Software developer (Flutter - Dotnet core - Vue js)

11 个月

Amazing ??

Mohamed Gomaa

Senior Flutter Developer

11 个月

Keep going, bro??

Bola Tharwat

Senior Unity Developer at PROVEN

11 个月

Great work my friend ????

要查看或添加评论,请登录

Bola Samy的更多文章

社区洞察

其他会员也浏览了