Monday, February 22, 2010
Wednesday, October 7, 2009
Introducing Object Oriented Concept
In this section you will learn about ‘How to think in Object Oriented way’.
Objectives
After completing this unit you should be able to:
* Think the real world in object oriented way
* Understand what really object and class means
* Describe what are attributes and responsibilities of an object.
Topics
In this unit, you will learn about the following topics:
* What’s wrong with starting of Object Oriented Programming
* Philosophy of OOP
* Mapping Object Oriented Thoughts to Object Oriented Programming
What’s wrong with starting of Object Oriented Programming
Unfortunately most of the people start Object Oriented Programming (OOP) jumping into a language book like C++, Java or C# etc. But it’s not a good start at all. Staring with OOP language book, you may learn writing package/namespace, class, object, interface, etc. But writing class, interface, object etc. does not guarantee good software design. OOP is totally useless if you can’t use this concept for good software design. So, what should to know first? What should you know before starting with an OOP book?
First of all you should know: what’s an object and how to think in OO (Object Oriented) way.
Philosophy of OOP
Yes, Starting of Object Oriented Programming is of course the concept of object.
And this concept is really simple. Ok, I am starting to speak about it. Before starting, I am requesting you to forget everything about programming, database design, software design i.e. all kinds of software engineering and programming language details for some couple of minutes (not forever!!).
Everything can be an object
Look around you, what you see ALL ARE OBJECTS. You may see computer, chair, table, pen, air cooler, carpet etc, all these are objects. Why they are object? Pretty simple, they have some related attributes and some related activities. How? Ok, just think about computer, it has processor, RAM, hard drive, keyboard, mouse, etc. all these things are the attributes of computer. Now, what’re the activities of a computer? It has a lot: it runs antivirus program, displays information, accepts your requests and executes these properly. All these are the activities of computer. So, computer is an object. Same way you will get the attributes and activities of chair, table, etc. So, to be an object, something should have attributes and/or should have activities. Finally, from the above discussion, we can draw a conclusion:
Everything can be an object.
How it is possible? Is it possible that any event, like war or raining, singing, thinking etc (which is not visible) can be object? The answer is YES. These can be objects also. Think, raining has attributes: is it drizzling or “cats and dogs”? Singing can be an object if you consider, in which frequency-range it is sung?
‘Name’ – is it an attribute or an object? Its totally depends on problem domain. See, if you thinking about a banking solution then customer ‘Name’ will be an attribute of customer. But if it a business from where you can purchase the ‘Name’ of your new-born baby then ‘Name’ will be an object to this business. Because ‘Name’ has meaning, length, etc.
Note: In some OOP books, authors may use data instead attribute and responsibility (I personally think its better term) instead of activity.
Object’s data and responsibility depend on problem domain
If I tell you and your friend to find out the data and activity of customer object, suppose, you get customer with name, email, phone attributes and purchase, bargain activities. At the same time your friend may get customer with first name, middle name, last name, gender, credit card attributes and open account activity.
Why it happens? It happens because you and your friend were on different platform with different point of view. You think about the customer of a grocery store whereas your friend thinks about the customer of a bank. But you both are right. Nothing goes wrong with it.
So, object and its data, its responsibility totally depends on problem domain.
What is class?
Class is the blue print of object. Suppose, I say Johnny, Mary and Russell are students. Here, Johnny, Mary and Russell are objects and Student is the class. More specifically, Student is the class with name attributes and there are three student objects whose names are Johnny, Mary and Russell.
Walkthrough 1: Mapping Object Oriented Thoughts to Object Oriented Programming
To make our conception more clear, now we will try to make a small application. Of course, we will try it Object Oriented way.
Let’s start. Suppose our considering problem domain as follows:
“………User wants to get full name and reverse full name providing first name, middle name and last name of a person.”
We will identify the objects first. Here, we will get ‘Person’ object as follows:
Person
Has first name
Has middle name
Has last name
Can tell its full name
Can tell its reverse name
Now we will implement this in C# (VS 2008, DotNet 3.5), an OOP language.
Steps:
1. Start Microsoft Visual Studio 2008
2. Click File>New>Project
You will see the following window. Select ‘Class Library’ template, give a meaningful name and select your preferable location.
3. Click ‘Ok’ Button
4. In Solution Explorer, you will see Class1.cs file. Delete this file.
5. Select project (not solution) OOPWalkThrough1 and Click right button. Then Click on Add>Class from the popup menu. You will get following window.
6. Remind we have found an object, ‘Person’ in our problem domain. Here we will give ‘Person.cs’ in Name as a file name.
7. Click ‘Add’ button and you will see the following code
using System;
namespace OOPWalkThrough1
{
class Person
{
}
}
Here, Person is a class.
8. Now update the Person class as follows:
namespace OOPWalkThrough1
{
class Person
{
public string firstName;
public string middleName;
public string lastName;
public string GetMyFullName()
{
return firstName + " " + middleName + " " + lastName;
}
public string GetMyReverseName()
{
string reverseName = "";
string fullName = GetMyFullName();
for (int index = fullName.Length - 1; index >= 0; index--)
{
reverseName += fullName[index];
}
return reverseName;
}
}
}Have a look inside the Person class. Compare the identified object (Person) with the Person class.
You see data of Person are represented by attributes and responsibilities are represented by methods. So any object creates from Person class will represent our domain object, Person.
9. Now add another class in this project. Here file name will be EntryPoint.cs (or any meaningful name you like) and write Main() method inside this class as follows:
namespace OOPWalkThrough1
{
class EntryPoint
{
public static void Main ()
{
Person personObj = new Person();
personObj.firstName = Console.ReadLine();
personObj.middleName = Console.ReadLine();
personObj.lastName = Console.ReadLine();
string fullName = personObj.GetMyFullName();
string reverseName = personObj.GetMyReverseName();
Console.WriteLine("Full Name: " + fullName);
Console.WriteLine("Reverse Form: " + reverseName);
Console.ReadLine();
}
}
}
Here, we will create a Person object, personObj from Person class using the following line:
Person personObj = new Person();
Then assign some data to the attributes of personObj as follows:
personObj.firstName = "James";
personObj.middleName = "Lucas";
personObj.lastName = "Scott";Finally, ask personObj to tell it’s full name and reversed-name and get it:
string fullName = personObj.GetMyFullName();
string reverseName = personObj.GetMyReverseName();
10. To make the project executable, we need to change the project properties. Select the project, click right button, select Properties from pop-up menu; you will get the following tab to change project properties.
Select Output Type as Console Application and Startup object as OOPWalkThrough1.EntryPoint.
11. Run the application and you will the output:
12. To take input from user you need to change the Main() method. Replace these three lines:
personObj.firstName = "James";
personObj.middleName = "Lucas";
personObj.lastName = "Scott";
with the following three lines
personObj.firstName = Console.ReadLine();
personObj.middleName = Console.ReadLine();
personObj.lastName = Console.ReadLine();
Important Note
Here, to keep the example simple, I’ve violated encapsulation (keep the data public) principle. Discussion has been started with a pretty simple use case and identification of domain object. Somebody may not agree with the process. But I think its better way to start Object Oriented Concept.
Thursday, September 3, 2009
Sufferings with switch smell
Introduction
In my first blog, Using enum in C# for smart coding, described code snippets suffer with switch smell. So, here, I am explaining what the switch smell is, what’s wrong with it and how to avoid it?
Most of the time, our source code suffers with several bad smells. Authors of a great book, Refactoring: Improving the Design of Existing Code, explain these smells with refactoring techniques. Here, I try to explain how switch smell introduces unnecessary complexity, reduces flexibility and leaves a class with vague responsibilities (from caller’s point of view).
Code Explanation
In the following two samples (Sample 1 & Sample 2), I have written a class, Calculator which can perform four basic arithmetic operation addition, subtraction, division and multiplication on two numbers.
Note: Here all code snippets are written in C#.
Sample 1:
public enum Operation
{
Add,
Subtract,
Multiply,
Divide
}
public class Calculator
{
public double Calculate(double firstNo, double secondNo, Operation operation)
{
switch (operation)
{
case Operation.Add:
{
return (firstNo + secondNo);
break;
}
case Operation.Subtract:
{
return (firstNo - secondNo);
break;
}
case Operation.Multiply:
{
return (firstNo * secondNo);
break;
}
case Operation.Divide:
{
return (firstNo / secondNo);
break;
}
default:
{
throw new ArgumentException("Incorrect Argument");
}
}
}
Sample 2:
public class Calculator
{
public double Add(double firstNo, double secondNo)
{
return (firstNo + secondNo);
}
public double Subtract(double firstNo, double secondNo)
{
return (firstNo - secondNo);
}
public double Multiply(double firstNo, double secondNo)
{
return (firstNo * secondNo);
}
public double Divide(double firstNo, double secondNo)
{
return (firstNo / secondNo);
}
}
Calculator of Sample 1 provides these functionalities with its Calculate() method whereas Calculator of Sample 2 has four methods for four specific functionalities.
In Sample 1, I introduce switch statement inside Calculate() method to distinguish the request of client code whether it (client request) wants to add, subtract, multiply or divide. On the other hand, in Sample 2, as each functionality is implemented in separate method I haven’t bothered with condition-checking (switch statement).
Comparison
Now, the question is: Which class is better than other one?
From design point of view Calculator is responsible for four distinct arithmetic operations, so it should have four methods in implementation level.
In Sample 1, Calculator has only a single method, Calculate() which perform four arithmetic operations. As a result it represents poorly self-documentation and introduces unnecessary complexity. It suffers with switch smell. As a result Calculator responsibilities is not concrete here. So, caller of the Calculate() method has to decide what it (caller) wants from Calculate() method by setting the parameter.
On the other hand, in Sample 2, interface of Calculator is clearer and also it is self-documented.
Sample 2 is more flexible than Sample 1. Suppose if I want to provide another functionality to add three numbers.
For Sample 2, I quickly write overload Add() method as follows with reusability.
public double Add(double firstNo, double secondNo, double thirdNo)
{
return Add(Add(firstNo, secondNo), thirdNo);
}
But what’s for Sample 1? :-((. I have to follow some ugly and stupid ways to implement this functionality which introduces more complexity, code repetition, procedural thoughts etc.
More..
In Refactoring: Improving the Design of Existing Code, Authors explain this problem (Sample 1) under bad small of switch statement and also show several ways (‘Replace type code with Subclasses’, ‘Replace type code with State/Strategy’, ‘Replace Parameter with Explicit Method’ how to refactor this smell. At the same time, authors describe ‘Parameterize Method’ which seems reverse of our discussion.
Conclusion
Each method of a class should represents a single activity, must be concrete and self-documented. One more activities in a single method (by switch smell) or one activity in several methods (I will discuss it another day) introduces complexicity and ambiguous interface, hinders changes, intencifies duplication and leave the class poorly self-documented.
Tuesday, August 18, 2009
Using enum in C# for smart coding
Most of us have written these (Sample 1 & Sample 2) kind of code snippet in our student or even professional life:
Sample 1 (C# Code):
string employeeType = employeeTypeComboBox.Text;
if (employeeType == "Permanent")
{
CalculateSalary();
}
else if (employeeType == "Worker")
{
CalculateWages();
}
else
{
// Do nothing
}
Sample 2 (C# Code):
string studentType = studentTypeComboBox.Text;
if (studentType == "Regular")
{
// Do Something
}
else if (studentType == "Private")
{
// Do Something
}
else
{
// Do nothing
}
In these two samples, user input is taken in a string valriable (employeeType /studentType) from a ComboBox and compare the variable with some discrete hard-coded string values (Permanent/Worker/Regular/Private).
What will happen if you type (some of you has faced these sad experiences) Parmanent instead of Permanent in Sample 1? Definitely, CalculateSalary() method will be not called and even program doesn’t show you any error message (any compile error). In best case, You will find out this problem during development and fix it immediately. But in worst case this problem arises after demployment.
Is there any solution where my typo will be detected earliar and show me a compile error?
Yes. Try emun.
See Sample Code 3, the more smart version of Sample code 1. Here you have no typo option.
Sample Code 3
enum EmployeeType
{
Permanent,
Worker
}
string employeeType = employeeTypeComboBox.Text;
if (employeeType == EmployeeType.Permanent.ToString())
{
CalculateSalary();
}
else if (employeeType == EmployeeType.Worker.ToString())
{
CalculateWages();
}
else
{
//Do Nothing
}
Believe me still you have chance to improve the code quality of Sample Code 3. Just see the Sample Code 4, I have wipe out all kinds of string variable from Sample Code 3.
Sample Code 4:
EmployeeType selectedEmployeeType = (EmployeeType)Enum.Parse(typeof(EmployeeType), employeeTypeComboBox.Text);
if (selectedEmployeeType == EmployeeType.Permanent)
{
CalculateSalary();
}
else if (selectedEmployeeType == EmployeeType.Worker)
{
CalculateWages();
}
else
{
//Do Nothing
}
Even, as your input comes from employeeTypeComboBox, don’t write hard-coded string in it’s item list, rather do it:
employeeTypeComboBox.DataSource = Enum.GetNames(typeof(EmployeeType));
So, why enum?
a) To improve code clarity
b) Make the code easier to maintain
c) Getting error at earlier stage
a) To improve code clarity
b) Make the code easier to maintain
c) Getting error at earlier stage
Note:
a) You can define enum inside or outside of class, but not inside of method or property.
b) The list of names contained by a particutar type of enum called enumerator list.
a) You can define enum inside or outside of class, but not inside of method or property.
b) The list of names contained by a particutar type of enum called enumerator list.
More About enum:
a) If you want you can keep value with each name in enumerator list. Example:
enum Priority
{
Critical = 1,
Important = 2,
Medium = 3,
Low = 4
};
You will get this value by type casting to the related type.
int priorityValue = (int) Priority.Medium;
b) Another nice thing, you can easily iterate through enumerator list.
foreach(Priority priority in Enum.GetValues(typeof(Priority)))
Medium = 3,
Low = 4
};
You will get this value by type casting to the related type.
int priorityValue = (int) Priority.Medium;
b) Another nice thing, you can easily iterate through enumerator list.
foreach(Priority priority in Enum.GetValues(typeof(Priority)))
{
MessageBox.Show(priority.ToString());
}
or even
}
or even
for (Priority prio = Priority.Low; prio >= Priority.Critical; prio--)
{
MessageBox.Show(prio.ToString());
}
}
Conclusion:
You should avoid string operation (specially comparison) because it decreases readability and introduces opacity. But using enum you can increase code readability, discover bugs in design time and keep your code more easy to maintain. So, Instead of string operation we should use enum (where applicable) as described in this discussion.
Subscribe to:
Posts (Atom)