Refactoring with BLoC Pattern: Meaningful Software Improvement

Kezia Irene Tesiman
LEARNFAZZ
Published in
4 min readMay 23, 2019

Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior. — Refactoring.com

Congratulations! You are now a new software developer in a cool company. You’re asked to continue the code of a retired software engineer that cannot be contacted. After reading several lines of codes, you get very devastated. Why? Because of all of the “bad smells” that you can barely understand. This is where refactoring becomes handy.

First of all, what are the “bad smells” in the codes? I will just name some of them that are mentioned in Fowler (2008) book:

  1. Duplicated code → Same code structure in more than one place.
  2. Long Method → The longer a procedure is the more difficult is to understand.
  3. Large Classes → When a class is trying to do too much, the duplicated code cannot be far behind.
  4. Long Parameter List → They are hard to understand, inconsistent and difficult to use.
  5. Divergent Change → When one class is commonly changed in different ways for different reasons.
  6. Shotgun Surgery → When every time you make a kind of change, you have to make a lot of little changes to a lot of different classes

Now that you have already know what are the bad smells, we should do something about it, right? We should refactor those rancid codes! Here are some examples from Fowler’s book about how to refactor your code:

  • Extract Method

You have a code fragment that can be grouped together. Increases the chances that other methods can use a method. Allows the higher-level methods to read more like a series of comments. You should change these codes:

void printOwing(double amount) {
printBanner();
//print details
System.out.println ("name:" + _name);
System.out.println ("amount" + amount);
}

to

void printOwing(double amount) {
printBanner();
printDetails(amount);
}
void printDetails (double amount) {
System.out.println ("name:" + _name);
System.out.println ("amount" + amount);
}
  • Inline Method

A method’s body is just as clear as its name. When Indirection is needless (simple delegation), it becomes irritating. However, if a group of methods are badly factored and grouping them makes it clearer. Change

int getRating() {
return (moreThanFiveLateDeliveries()) ? 2 : 1;
}
boolean moreThanFiveLateDeliveries() {
return _numberOfLateDeliveries > 5;
}

to

int getRating() {
return (_numberOfLateDeliveries > 5) ? 2 : 1;
}
  • Introduce Explaining Variable

This will help to explain the meaning of each variable when expressions are hard to read.

if ( (platform.toUpperCase().indexOf("MAC") > -1) &&
(browser.toUpperCase().indexOf("IE") > -1) &&
wasInitialized() && resize > 0 )
{
// do something
}

to

final boolean isMacOs = platform.toUpperCase().indexOf("MAC") >-1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") >-1;
final boolean wasResized = resize > 0;
if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {
// do something
}

Now that I have covered some of the refactoring techniques, I am going to tell you about my refactoring experience when I developed a mobile app with Flutter. I was creating a login page and was obligated to make a 100% coverage test of the code. Here is the snippet of the login page test, that is very hard to read and redundant.

This is where I realized that I should refactor these codes. After I looked further, I found that this problem also has been encountered by many other people, and they have decided to make a compact design pattern out of it.

A design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design. It is not a finished design that can be transformed directly into source or machine code.

One of the design patterns that match with this problem is BLoC pattern. Business Logic Component (BLoC) pattern is made to handle state changes in Flutter. It utilizes Reactive Programming (declarative programming paradigm concerned with data streams and the propagation of change) to handle the flow of the data. BLoC stands as a layer for our UI to interact with our back end. With this architecture, our team doesn’t need to store data in our UI (Widget, in this case). The architecture diagram of BLoC pattern can be seen on the image below.

Source: https://pub.dartlang.org/packages/bloc

With BLoC pattern, I successfully separated the front end page (login) and the logic. This means, now I can create the mock of the front end page without having to consider the logic. The test is now much simpler.

Also, by implementing BLoC pattern, the code is more maintainable and open for further improvement. I can easily use the mock classes that I have created on login test page for another test pages.

Final Words:

When life gives you lemons, make lemonade. You should remember when you think you’re developing an application with overwhelming codes that you could barely understand, it is probably because of the “bad smells”. You should refactor it!

References:

  1. Fowler, M. (2018). Refactoring: improving the design of existing code. Addison-Wesley Professional.
  2. Freeman, E., Robson, E., Bates, B., & Sierra, K. (2004). Head first design patterns. “ O’Reilly Media, Inc.”.

--

--

Kezia Irene Tesiman
LEARNFAZZ

Biomedical Informatics Graduate Student at Harvard University. Interested in medical imaging, natural language processing, and machine learning.