Skip to main content

Code refactoring - Create base class/interface when is needed

When I made the last code review on a project I found the following lines of code:
Original version
public abstract class FooBase
{
Person _person;
public void string PersonId()
{
if(_person is Student)
{
return ((Student)_person).Id;
}
if(_person is Worker)
{
return ((Worker)_person).Id;
}

return _someDefaultValue;
}
public void string ScreenName()
{
if(_screen is MainScreen)
{
return ((MainScreen)_screen).Name;
}
if(_screen is SettingsScreen)
{
return ((SettingsScreen)_screen).Name;
}

((DefaultScreen)_screen).Name ;
}
}

After some new functionality was added:
public abstract class FooBase
{
Person _person;
public void string PersonId()
{
if(_person is Student)
{
return ((Student)_person).Id;
}
if(_person is Worker)
{
return ((Worker)_person).Id;
}
if(_person is Vampire)
{
return ((Vampire)_person).Id;
}

return _someDefaultValue;
}
public void string ScreenName()
{
if(_screen is MainScreen)
{
return ((MainScreen)_screen).Name;
}
if(_screen is SettingsScreen)
{
return ((SettingsScreen)_screen).Name;
}
if(_screen is TimeScreen)
{
return ((TimeScreen)_screen).Name;
}

((DefaultScreen)_screen).Name;
}
}
If you ask you’re self if the Person class contains the Id property, the response is not. The original team didn’t look over the code and add common items to the base class.
What we can observe in the above code?
First of all, the screens and persons could have a base class or at least a base interface.
The changes are made without trying to improve the code and design. Extracting a base class (interface) is a mandatory think to do before marking a task as done.
There are times when the developer don’t want to make changes to the code because is afraid that he can brake something. Maybe, if the code is covered with strong unit tests than the developer would feel more comfortable to make changes. If you are a developer and see that the code is not covered with test and because of this you cannot improve the design that you should begin to write some test first. After that you should refac. this methods.
After we make the refac our FooBase class should look something similar to this:
public abstract class FooBase
{
// Add the Id property to the base class (Person)
Person _person;
public void string PersonId()
{
if(_person == null)
{
return _someDefaultValue;
}
return _person.Id
}
public void string ScreenName()
{
// Define a base Screen class that contains the Name property
return _screen.Name;
}
}
As a developer, don’t be afraid to improve the code. If the first team that implemented this class would made the refac. we would never had this problem. But in the same time, the second developer that made the changes should look over the code and try to improve it.

Comments

Popular posts from this blog

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine:
threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration:

TeamCity.NET 4.51EF 6.0.2VS2013
It seems that there …

Fundamental Books of a Software Engineer (version 2018)

More then six years ago I wrote a blog post about fundamental books that any software engineer (developer) should read. Now it is an excellent time to update this list with new entries.

There are 5 different categories of books, that represent the recommended path. For example, you start with Coding books, after that, you read books about Programming, Design and so on.
There are some books about C++ that I recommend not because you shall know C++, only because the concepts that you can learn from it.

Coding

Writing solid codeCode completeProgramming Pearls, more programming pearls(recommended)[NEW] Introduction to Algorithms

Programming

Refactoring (M. Fowler)Pragmatic ProgrammerClean code[NEW] Software Engineering: A Practitioner's Approach[NEW] The Mythical Man-Month[NEW] The Art of Computer Programming

Design

Applying UML and Patterns (GRASP patterns)C++ coding standards (Sutter, Alexandrescu)The C++ programming language (Stroustrup, Part IV)Object-oriented programming (Peter Coad)P…

Entity Framework (EF) TransactionScope vs Database.BeginTransaction

In today blog post we will talk a little about a new feature that is available on EF6+ related to Transactions.
Until now, when we had to use transaction we used ‘TransactionScope’. It works great and I would say that is something that is now in our blood.
using (var scope = new TransactionScope(TransactionScopeOption.Required)) { using (SqlConnection conn = new SqlConnection("...")) { conn.Open(); SqlCommand sqlCommand = new SqlCommand(); sqlCommand.Connection = conn; sqlCommand.CommandText = ... sqlCommand.ExecuteNonQuery(); ... } scope.Complete(); } Starting with EF6.0 we have a new way to work with transactions. The new approach is based on Database.BeginTransaction(), Database.Rollback(), Database.Commit(). Yes, no more TransactionScope.
In the followi…