Navigation

Feed your aggregator (RSS 2.0)   Send mail to the author(s)

Recent Entries
Archives
<January 2009>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567


Categories
Blogroll
Login

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.


Copyright 2010 Manish Kumar Singh
 Tuesday, January 13, 2009
Do not implement Design Patterns - if you do not understand it

I have seen many programmers and senior programmers showing their prowess in implementing and justifying a design pattern implementation. Before doing so one should ask a very simple and honest question to self, “Do I fully understand it?” I am sure many of you, would say off course, what’s the big deal. Now look at your decision once more by answering the following questions:

  1. Does your team, working with you also understand the pattern correctly? Are they comfortable with its implementation?
  2. Would you be there till the project reaches its logical end or do you have at least one successor who would be there and understands the pattern correctly?
  3. Does it require other members to follow a set of rules while coding?
  4. Do you understand “What it solves” OR “How it solves”?
  5. Are you thinking about scalability or maintainability?

Thoughts on Question 1

Most of the serious projects require a team of developers working together on different modules. If they do not understand the pattern, it is more likely, that you would encounter chaotic and unorganized codes. The common evils are repetition of codes which explains the lack of understanding the design pattern, code tweaking to override design pattern, hard coded lines, code spaghetti and more. Wow these codes could kill.

Thoughts on Question 2

Something that remains constant in software development is “Change”. It is inevitable and the requirement itself keeps changing. No doubt the design patterns are there to help, but when it requires any change, who’s going to do it? In case it falls in a wrong hand, it would shit all over your effort and logic.

Thoughts on Question 3

If your answer to this question is YES, then you must ensure you understand question one, and keep a constant vigil or do a knowledge sharing for your team to bring them on the same page, else the errors and problem can pretty quickly escalate making your module a piece of shit. If your answer is NO, then you need to worry about question two only.

Thoughts on Question 4

A big question! It is really easy to say what it solves, but knowing how it solves is entirely a different ball game. You need to think on what is the price you need to pay for implementing it, what are the other alternatives, is there a mix and match of patterns to suit your need, does it increases the complexity of the module or simplifies it, what is the cost of maintaining it, how frequently it is expected to change, what are the impact points etc. etc. I am sure it would make you crazy, at first it seemed to me as a simple question but later wow!

Thoughts on Question 5

You must read what other people think about scalablability. Damien Katz, in his post, writes about crappy programmers, boasting about concepts like enterprise, scalability and patterns without actually understanding it. Another hilarious and a bit “PG” post by Ted Dziuba, where he is really pissed off and frustrated with people talking about scalability without having a good knowledge of it. In sync, there is another post by Rajiv Popat where he talks about the best practices and people who seriously talk about such concepts but are not able to answer the simplest questions he asked.

Design patterns are not meant for scalability. It is about extension and maintenance. It should reduce the impact of change, help in decoupling the elements of module interacting with each other, reduce maintenance cost, provide extra room for extension.


Thoughts
Tuesday, January 13, 2009 5:17:12 AM (GMT Standard Time, UTC+00:00)  #  Comments [0] Trackback
 Friday, November 07, 2008
Getting Started with LINQ - Part I

Few months back while upgrading my project to .NET Framework 3.5 for using LINQ, I had conducted a knowledge sharing session for LINQ. The piece of code and explanation are the parts taken from the knowledge sharing session.

Before we start off with "Getting started with LINQ - Part I", I would like to explain few good things I learnt while working with LINQ. Also I would assume that you are familiar with the Generics, C# 3.0 language enahancements and basics of SQL. If you are unaware of the language enhancement, I would like to recommend visiting MSDN where you wouldfind some good videos about Visual C# 3.0 enahancements. You can also visit a nice blog by Mike Hanley where he quickly reviews most of the C# 3.0 Language enhancements with examples and comparison to C# 2.0. For Genrics you can visit MSDN article "An Introduction to C# Generics".

Introduction

LINQ is not just a query, it stands for "Language Integrated Query" and more than that it is a data iteration engine applied to the language. The iteration engine is inbuilt in the language. LINQ uses mainly IEnumerable<T> for iteration and IQueryable<T> for querying. C# 3.0 enhancements introduced the "var" keyword which is an anonymous type.

var m = new { FirstName = "Manish", LastName = "Singh" };

Notice the use of "var keyword" and "anonymous class". The first thing that should strike in your mind is - "Hey! Is C# still doing the type checking here?" The answer is YES! C# is still doing the type checking here. The first time you use "var" type, it gets intialized with the type inferred from RHS. If you try to change the type of the variable later in the code, C# complains with an error. The CLR is clever enough to shoot off an error message like "Cannot implicitly convert type 'X' to 'Y'." at the design time itself. However, you must be careful in using "var" keyword or else, very quickly you can land up in a mess, with lots of anonymous variable, making it difficult to debug and maintain. The best is, use it when you know the return type can vary and would be decided at runtime. In short, use "var" when you are confused about the return type :-).

LINQ uses deferred query. This means that the query is not performed when the line containing the query is executed. It is performed during the actual enumeration of the object. However, methods like ToList(), ToArray(), Sum(), Max(), Count(), First(), Last() etc is called immediately and are also known as Non-Deferred queries. The advantage of deferred query is that it executes when required and does not apply any extra overload to your code. Non-Deferred queries execute immediately returning an instance of the IEnumerable<T> list. Why? Because C# 3.0 language enhancement allows you to change the data while iterating using the iterator (Not allowed in C# 2.0).

I would show you LINQ using Lamda expressions. Thus, let us have a little introduction to Lamda expression. Lamda expressions are coma-delimited parameter(s) followed by lambda operator "=>", followed by an expression or statement block. e.g. [(param-1, param-2,..., param-N) => expr]. Example: x => x.FirstName.Equals("Manish"). This lambda expression can be read as "x goes to x" or "input x returns x".

For using LINQ for entities your project must be running on framework 3.5, must reference System.Core and you must be having the using directive "System.Linq". Normally, if you use VS 2008 with Framework 3.5 installed, while creating a new project, VS 2008 does all the work for you.

LINQ Console Program
To start add a new project "Sample Data" of type class library in your solution. This is where all our object declaration and initialization takes place. The following image shows the solution explorer with a project "SampleData" in it.

solution explorer

The "SampleData.cs" int the "SampleData" project includes a classical example of Customer, Product, Order and OrderItem. For the sake of simplicity, I have declared the properties as "public".

SampleData.cs
  The "DataContext.cs" int the "SampleData" project includes the initialization code for Customer, Product, Order and OrderItem. For the sake of simplicity, I have declared all methods static for the sake of simplicity. This method is required from my console program to collect some meaningful data for "Customer", "Product", "Order" and "OrderItem". The next section shows you a sample initialization.

DataContext.cs

To initialize the entities with some sample data you may create the object with fictitious but meaningful data and assign it to a list as shown in the image below. Later we will query these data and check the output.

DataContext.cs

Next, we add a new console project into your solution say "LINQ-Object". Add Reference to "SampleData" project. In the "Program.cs" file that is created by VS 2008 for you, go ahead and declare a bunch of static methods as explained below. After that you can call each of these from the "static void Main(string[] args) " method and check the output. Also try to use break point and see what is displayed.

LINQ: Select
Select Most of the extension methods of LINQ applied on IQueryable<T> or IEnumerable<T> returns another IQueryable<T> or IEnumerable<T>. This allows you to nest the methods in progressive manner like "Append()" method of "StringBuilder" class. I have purposefully applied nested select to explain this. Select is a deferred query and parsing is done at the runtime.

Output

LINQ: Where Clause
Where In this part of the code I have explained a simple "where" clause using LINQ. The query simply returns all customer who belong to "category", "A". If you see the declaration of "Customer" entity explained earlier, you would see that it has an attribute "category" to help categorize the customers into groups depending on their importance.

Output

LINQ: Join
Join In this part of the code "Customer" and "Order" to see the customer's full name, order name and order date. When you run the program the output (see image below) would be shown, depending on your data.

Output

LINQ: Group Join
Group Join In this part "Customer", "Order" and "OrderItem" is joined to see the customer full name, customer category, order name and order details like product name, quantity and price. When you run the program the output (see image below) would be shown, depending on your data.

Output

LINQ: Group By
Group By This part of the code, returns the customers grouped by their category. When using "Group By" extension method in LINQ, it returns a two dimensional list. Each elements of the outer list contains a list of customers belonging to the same group.

Output

LINQ: Order By
Order By This section explains the "Order By" clause as seen in SQL. You can have multiple attributes in the "Order By" clause and also provide sorting direction.

Output

LINQ: TakeWhile
TakeWhile "Take" extension method allows you to select items from top while the TakeWhile extension method allows you to select items based on certain condition. The code selects items whose string length is below six.

Output

LINQ: Skip
Skip "Skip" extension method allows you to skip items from top while the SkipWhile extension method allows you to skip items based on certain condition. The code skips five items from the top.

Output

There are several more methods defined in LINQ. I would encourage you to apply more of these extension menthods for practice and clarity.


.Net
Friday, November 07, 2008 1:30:05 PM (GMT Standard Time, UTC+00:00)  #  Comments [4] Trackback