Posts tagged with: sr

TodoApp – Part 2: Single responsibility is what we need.

In our journey towards hardcore we need to refactor the shitcore into a bit more softcore =) I’m not going to show all source code in this blog entry. You can look at the code here.

It will take some iterations before the code is quite usable. In this iteration we will focus giving each method a single responsibility, which means that each method should only contain the logic for one thing. The constructor is a kick ass example of that. Lets look at it.

First of all, it’s responsible of connecting to the database.

public MainWindow()
{
    InitializeComponent();
    _db = new SQLiteConnection("Data Source=todomachine.db;Version=3;DateTimeFormat=Ticks;");
    _db.Open();

then, it’s also verifying that the table exists in the database.

    //create table if it do not exist.
    if (!DoesTableExist(_db, "todo_items"))
    {
        SQLiteCommand command = new SQLiteCommand(_db);
        command.CommandText =
            @"CREATE TABLE todo_items(
id INTEGER PRIMARY KEY AUTOINCREMENT,
title VARCHAR(40) NOT NULL,
description text NOT NULL
);";
        command.ExecuteNonQuery();
    }

and finally it’s loading stuff into the list box.


    // load all todo items.
    SQLiteCommand mycmd = new SQLiteCommand(_db);
    mycmd.CommandText = "SELECT * FROM todo_items";
    var reader = mycmd.ExecuteReader();
    while (reader.Read())
    {
        lbTodos.Items.Add(new Item { Id = (long)reader["id"], Title = (string)reader["title"] });
    }
}

Let’s fix that and write a little bit of documentation for each method.

btnNew_Click

Next we have btnNew_Click which is used to save a new item:

private void btnNew_Click(object sender, EventArgs e)
        {
            var frm = new TodoItemForm();
            frm.ShowDialog(this);

            var cmd =
                new SQLiteCommand("INSERT INTO todo_items (title, description) values(@title, @description)", _db);
            cmd.Parameters.Add(new SQLiteParameter("title", frm.tbTitle.Text));
            cmd.Parameters.Add(new SQLiteParameter("description", frm.tbDescription.Text));
            cmd.ExecuteNonQuery();

            lbTodos.Items.Clear();
            // load all todo items.
            SQLiteCommand mycmd = new SQLiteCommand(_db);
            mycmd.CommandText = "SELECT * FROM todo_items";
            var reader = mycmd.ExecuteReader();
            while (reader.Read())
            {
                lbTodos.Items.Add(new Item { Id = (long)reader["id"], Title = (string)reader["title"] });
            }
        }

It has two responsibilities: Saving an item into the database and refreshing the listbox.
Fortunately, we have already created a method for the listbox in the constructor refactoring. Let’s just add that the listbox should be emptied before adding all items.

lbTodos_MouseDoubleClick

lbTodos_MouseDoubleClick is used to edit an item.

        private void lbTodos_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Item item = (Item)lbTodos.SelectedItem;

            SQLiteCommand mycmd = new SQLiteCommand(_db);
            mycmd.CommandText = "SELECT * FROM todo_items WHERE id=" + item.Id;
            var reader = mycmd.ExecuteReader();
            reader.Read();

            var frm = new TodoItemForm();
            frm.tbDescription.Text = (string)reader["description"];
            frm.tbTitle.Text = (string) reader["title"];
            frm.ShowDialog(this);

            var cmd =
                new SQLiteCommand("UPDATE todo_items set title=@name, description=@description WHERE id = @id", _db);
            cmd.Parameters.Add(new SQLiteParameter("name", frm.tbTitle.Text));
            cmd.Parameters.Add(new SQLiteParameter("description", frm.tbDescription.Text));
            cmd.Parameters.Add(new SQLiteParameter("id", item.Id));
            cmd.ExecuteNonQuery();

            lbTodos.Items.Clear();
            // load all todo items.
            SQLiteCommand cmd3 = new SQLiteCommand(_db);
            cmd3.CommandText = "SELECT * FROM todo_items";
            reader = cmd3.ExecuteReader();
            while (reader.Read())
            {
                lbTodos.Items.Add(new Item { Id = (long)reader["id"], Title = (string)reader["title"] });
            }

        }

Responsibilities:

  1. Load item from database
  2. Populate item form
  3. Save stuff from the item form into the database
  4. Populate list box

Here we’ll refactor the item form to use the Item class, and we’ll therefore make the item class standalone (instead of being a private class inside MainWindow). That should take care of #2.

#4 have already been fixed thanks to the previous method refactorings.

We’ll move the item loading into a separate method.

Done

The first refactoring is now done. The goal of this post was to help you understand what Single responsibility really means, although we are not quite done with the guideline yet. The MainWindow form still have many different responsibilities. But first let’s explore exception handling in the next post.


DRY KISS, SR!

omg! wtf?! Nahh, this ain’t a porn blog. The title is three coding principles that I try to follow when I code. And this blog is going to be all about them.

You’ll find code refactorings, insights and such that I discover during my days as a software architect/developer.

As you might notice, no entries will be elaborate or poetic. They will be short and concise: HARDCORE!

DRY – Don’t repeat yourself.

Most of you have probably heard of this principle. You can read more about it at wikipedia.

Code duplication is evil since you:

  1. can get the same bug in a lot of different places
  2. refactoring becomes hard (try finding all the places you have the duplicate code in)
  3. larger programs -> more code to maintain
  4. your application design is most likely bad as a rotten apple

Let’s focus on the last entry. Sorry, but it’s true. If you need to duplicate code, you have done something wrong. Go and take a coffee. Go through your code and try to refactor it. Ask a colleague of yours. DO NOT CONTINUE UNTIL YOU SOLVE THE PROBLEM. Trust me. You’ll regret it later.

KISS – Keep it simple (and) stupid

I have a really active brain. It comes up with all sorts of cool stuff and solutions when programming. That’s a BIG problem when coding. Coding is not about having the coolest solution or the most fancy features. It’s about doing as little as possible to get the job done. I do not mean that you should take shortcuts or writing shit code. I’m talking about doing a simple solid solution which get’s the job done but nothing more.

Time estimation is still one of the hardest thing to do when developing software. How long have we been coding? 40 years? And we still can’t do proper time estimations. El oh el! Do you know why? Because most programmers do not keep it simple! We love to learn new stuff and do cool solutions.

Finish the application first! Then do the fancy stuff.

Read more about KISS at wikipedia.

SR – Single responsibility

Have you ever seen a cop (Mr. Police) mow a lawn when on active duty? (If you have, please give him this link). I thought not. Why? Because doing a lot of different things would make him a bad cop. It’s the same with your classes, methods and projects. Don’t let a class both fetch the users from the database and present the info to the user. Do not let a method both send an email and eject the CD tray.

If a class is called UserReporsitory it should not do anything else than fetch/save you users from/to your data source. That’s what single responsibility means.

Why?! you ask. Well, letting your method/class/project doing a lot of stuff will make it hard to understand what your application does. It will also make it harder to understand. But the most important thing is: It will make it hard to test your application. (unit tests). And you don’t want that. Unit tests are a life saver when your application grows. All those green dots that says that the tests have passed will give you a warm fuzzy feeling inside when your application is 5M lines long. Imagine how hard it would be to test an app that large when all your classes do a lot of different stuff. Imaging a cop mow a lawn.

Read more about single responsibility @ objectmentor || oodesign

That’s it

Again. Welcome to my blog. Leave a comment or two.