Click here to Skip to main content
5,786,882 members and growing! (24,066 online)
Email Password   helpLost your password?
Development Lifecycle » Design and Architecture » Patterns and Practices     Intermediate License: The Code Project Open License (CPOL)

Simple, and Clean .NET Design and Implementation Method - Part 1

By Yang Yu

A fast and simple way in application design patterns - Part 1
C# (C# 1.0, C# 2.0, C# 3.0, C#), Windows, Visual Studio (Visual Studio, VS2005), WinForms, Design, Architect, Dev

Posted: 24 Apr 2008
Updated: 24 Apr 2008
Views: 6,654
Bookmarked: 16 times
Note: This is an unedited reader contribution
Announcements
Loading...



Search    
Advanced Search
Sitemap
4 votes for this Article.
Popularity: 1.81 Rating: 3.00 out of 5
0 votes, 0.0%
1
2 votes, 50.0%
2
1 vote, 25.0%
3
0 votes, 0.0%
4
1 vote, 25.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article



Introduction

There are many methodologies surrounding design patterns and standards available in reference to the software development life cycle. Each needs to address the following issues: standardization, reuse-ability, and scalability. The standardization aspect consists of coding standards, naming conventions, comments, use of interfaces, etc. Reuse-ability looks at the extendability, and flexibility to run as a component model, or wrap-able an n-tiered approach. Scalability encapsulates the emphases on robust coding, performance, and data usage and transfers and finally security.

For sure there are many decisions involved in designing and developing an application, even the simplest applications should require ample amount of design work before implementation takes place.

In this articles, I will take an easy and simple business requirement and go through the process of the design and implementation where I will try to emphasis on standardization, reuse-ability, and scalability.

Background

  • Software Architecture
  • Object Oriented Programming
  • Design Methodologies (RUP)
  • UML

Name Value Storage Project

User Requirements

In this example, the business user requires a program be built to store Name Value Pairs such as FirstName = Yang where FirstName = Name and Yang = value

The Name value must can only be alpha numeric values, and spaces around the equal sign should be ignored.

The storage needs to be xml based and the GUI must be simple and user friendly.

Design

Use Case

The User Requirement in this case is simple, and straightforward. Without meeting with the clients to gather more information, we can now deduce a useful List of Actions that can be performed, we can also draw up the high level interactions between Users and the Software. At this point, we can also create a list of processes the application's must haves, and should haves that would increase the reuse-ability, and extendibility.

A Use Case diagram can be put together to illustrate this.

Use_Case.png

Even though we only have one User and some very simple Use Cases, the process can quickly grow and become more complex. By analyzing the Use Cases, we can minimize the risks involve in under taking feature changes as well as development time.

Process Diagram

The next step is to introduce some process diagrams into the design. A good starting point is to take each Use Case and extrapolate an Business Process out of it. Again, a good design is dictated by the robustness on validations, extendability and error handling.

A good way to extend a business process is to Expose Events through the objects. This gives can also provide ways of intercepting specific processes thus scaling the application.

Error handling and validations ties in hand and to hand. The result of specific business rules validations should generate specific exceptions or result that is controlled within the application.

Lets take a look at a very simple Process of Creating a Name Value Pair.

Insert_Process.png

This process is a simple and involves particular layers of business operation. The segregation of the business layers will give clues to the implementation phase, and reduce the amount of effort in actual project design. It is important to focus on the way entities in the process connect since this ultimately reflects the performance and will be utilized for security on calculating attack surfaces.

Class Diagram

Name_Value_Libarary.png

The Key to a robust and scalable application lies in its core design model. Since most applications deal with information, it is critical to develop a model that will capture all the properties of the required information as well as the interactions and relationships between them. The more you understand about what it is you are trying to capture, the better the model will be, and the more robust and scalable the application will be.

Many times during this phase, you will be faced to challenge the business users on why a particular decisions about the types of information are captured. A robust object oriented model sometimes does not follow a particular business model, since the business requirements usually apply to a very scope centric and project centric collection of data. Due to this face, our model may lack growth potentials and key elements that allow future advancements and scalability. It is crucial to challenge the Business Users whenever possible to increase the scope or alter it to enable the project to reach its potentials. By following this methodology, we can deliver more with less time for the first phase, and for future phases as well.

Usage of Interfaces

Below is the Class Diagram for the Name Value Storage Project. Instead of simply using a Hash table or Dictionary as my implementation, I've Started off the project by introducing an Business Logic Interface.

using System;
using NameValueLib.BLL;
namespace NameValueLib
{
    /// <summary>
    /// Name value collection is used to manage a list of Name/Value pairs
    /// </summary>
    public interface INameValueCollection : 
        System.Collections.Generic.IList<NameValuePair> 
    {
        /// <summary>
        /// Raised on Adding new NameValuePair to the List
        /// </summary>
        event NameValueHandler InsertNameValuePair;

        /// <summary>
        /// Raised on Deleting NameValuePair from the list
        /// </summary>
        event NameValueHandler RemoveNameValuePair;

        /// <summary>
        /// Add a new Name value pair into the list given a single patterned input in the format of [Name][delimiter][Value]
        /// </summary>
        /// <param name="NameValueString"></param>
        void Add(string NameValueString);

        /// <summary>
        /// Removes all the name value pairs
        /// </summary>
        void Remove(NameValuePair[] nameValuePairs);

        /// <summary>
        /// Sort the list by Name ascendingly
        /// </summary>
        void SortByName();

        /// <summary>
        /// Sort the list by Value ascendingly
        /// </summary>
        void SortByValue();

        /// <summary>
        /// Sort the Name Value collection by a sort by and order
        /// </summary>
        void Sort(NameValueComparer.SortByType sortBy, bool ascending);
        /// <summary>
        /// Get the XML output of the list
        /// </summary>
        /// <returns></returns>
        string GetXML();

        /// <summary>
        /// Save the List to an XML File
        /// </summary>
        /// <param name="FileName"></param>
        void Save(string FileName);
    }
}
 

If you look at the Use Case, you will notice that there are a lot of similarities. By segregating the implementation and the abstract prototype, having this interface, allows room for extendability and to create standardization. Depending on the size and User desires, I can wish to implement this interface a number of ways either with a List<> or Dictionary<> or even a custom written data structure.

N-Tier Architecture

By Adapting an N-Tiered approach, we enough the application to cross domains, reused, pluggable into any type of application weather its web or windows or even services, we've allow it be registered in the GAC, and even for COM+. We've also opened new door for more secure abilities while not increasing the attack surface of the core functionalities. N-Tiered Architecture render many benefits that out weights the disadvantages. It is now an industry standard and is the bridge to the next generation applications such as SAAS.

The Project is split up into 2 Tiers, the Business Logic Layer and the Presentation Layer done in Windows Forms. I can easily implement a web version of even a console version for the presentation layer.

A point to make about standardization. Standardization enables the project to be understood by peers even by yourself in the future if you needed to make changes. Coding standards and naming conventions can be critical in minimizing the amount of find need in searching and filtering. It is an good idea to develop a standard project layout (using folders) as well as class layout (using namespaces). This not only help us developers it can sometimes help CLR to more efficiently execute grouped code.

Project_View.JPG

Validation

A robust business layer should contain solid validations of input variables. You should never trust the client no mater how secure the presentation layer is. The pattern I used in the project uses the .NET Exception framework. To efficiently utilize the .NET exceptions framework, NameValueException is used to handle application level business logic validation Exceptions.

..
    public void Add(string NameValueString, string Delimiter)
        {
            string Errors;
            // pre: validate
            if (!NameValueValidator.DefaultValidator.ValidateNameValueInput(NameValueString, Delimiter, out Errors))
                throw new NameValueException(Errors);

            try
            {
                // find delimiter position
                int delPos = NameValueString.IndexOf(Delimiter);
                // create new Name Value Pair
                this.Add(new NameValuePair(NameValueString.Substring(0, delPos).Trim(),
                    NameValueString.Substring(delPos+Delimiter.Length).Trim(), Delimiter));
            }
            catch (NameValueException nex)
            {
                throw nex;
            }
            catch (Exception ex)
            {
                throw new NameValueException("Error Parsing Name Value Input.", ex);
            }
        } 
..  

Events and Delegates

The usage of events and delegates provides an way to intercept application triggers, aswell as a way to efficiently extend business logic.

In this project, I've created a delegate to handle generic Events such as Add() or Removed() for standard data collections.

<<>>>

<<>>>

<<>>>
public delegate void NameValueHandler(object sender, NameValuePair NameValuePair);


Sorting

There are a number of ways to implement sorting in .NET. One efficient methods is to implement a Comparer and utilize the default .NET Quick Sort for the List<> object.

/// <summary>
    /// Comparer used to compare Name Value Pairs and for Sorting the NameValueCollection
    /// </summary>
    public class NameValueComparer
        :IComparer<NameValuePair>
    {
        public enum SortByType: byte 
        {
            name = 1,
            value = 2
        };

        #region public propperties
        private bool _ascending;
        public bool Ascending
        {
            get
            {
                return this._ascending;
            }
            set
            {
                this._ascending = value;
            }
        }

        private SortByType _sortBy;
        public SortByType SortBy
        {
            get{
                return this._sortBy;
            }
            set{
                this._sortBy = value;
            }
        }
        #endregion

        #region constructors
        public NameValueComparer():this(SortByType.name, true){}
        /// <summary>
        /// Create comparer
        /// </summary>
        /// <param name="sortBy"></param>
        /// <param name="ascending"></param>
        public NameValueComparer(SortByType sortBy, bool ascending)
        {
            this._sortBy = sortBy;
            this._ascending = ascending;
        }
        #endregion

        #region IComparer<NameValuePair> Members

        /// <summary>
        /// Compares x to y according to the sort and ordering
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public int Compare(NameValuePair x, NameValuePair y)
        {
            // pre:
            if (x == null || y == null)
                throw new NameValueException("Error Sorting Collection.");
            if (this.SortBy == SortByType.name)
                return this._ascending ? x.Name.CompareTo(y.Name) : y.Name.CompareTo(x.Name);
            else if (this.SortBy == SortByType.value)
                return this._ascending ? x.Value.CompareTo(y.Value) : y.Value.CompareTo(x.Value);
            else
                throw new NameValueException("Sort Type not found.");
        }

        #endregion
    } 

Serialization

One of the major improvements in .NET framework is its ability for easy serialization and deserialization. The adaptations are used for object persistence, communication protocols such as SOAP, and remoting.

XML Serialization

Comming Soon...

Presentation Layer

Main Form

MainScreen.JPG

Custom Validation Handling...

Invalid.JPG

Using the GetXML() Method

Get_XML.JPG

Conclusion

Comming Soon...

Points of Interest

You may wish to improve this project in anyway possible and send it to me. I've left a empty Dictionary implementation of interface which if you are interest feel free to go ahead at it.

History

  • April 24, 2008 - First draft of Article Created

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Yang Yu


Has has extensive business experience in numerous industries such like Automotive, Education, Insurance, Financial Services, and Telecommunication. Currently he is the CEO of Prognex Corp.

He has over 9 years of experience in IT involved in Business Analysis, Architecture, Implementation of SOA, OOAD Enterprise Systems using .NET 1/2/3, SSIS, BEA Web logic, BlackBerry MDS, SQL Server 2000/2005, Oracle 8/9/10g, VB 6, etc. to construct Enterprise Level Web Applications, Windows Services, COM+ Services, Smart Client Windows Applications, Pocket PC, Black Berry Applications, and Data Warehouses that are Scalable, Reliable, Robust, and Secure.

His emphasis is towards Business Objectives, Security and Integrity of Assets, and Clients.
Occupation: Web Developer
Company: Prognex Corp.
Location: Canada Canada

Other popular Design and Architecture articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 4 of 4 (Total in Forum: 4) (Refresh)FirstPrevNext
GeneralUse Case diagram - Wrong Notation??memberNirosh17:44 24 Apr '08  
GeneralRe: Use Case diagram - Wrong Notation??memberYang Yu4:44 25 Apr '08  
GeneralConfusing ...memberMaximilien9:02 24 Apr '08  
GeneralRe: Confusing ...memberYang Yu12:29 24 Apr '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 24 Apr 2008
Editor:
Copyright 2008 by Yang Yu
Everything else Copyright © CodeProject, 1999-2009
Web20 | Advertise on the Code Project