Bruce Zhang

<December 2008>
SuMoTuWeThFrSa
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910


Navigation

.Net Resource

Favourite Blog

Subscriptions



Handling Distributed Transactions In Visual Studio 2005

It provides the System.Transaction namespace in Visual Studio 2005. So it is very convenient to handle distributed transactions. In Visual Studio 2003 .Net, distributed transactions are handled by Enterprise Service and require COM+ registration. We may compare the methods of inserting the order between Pet Shop 3.0 and Pet Shop 4.0. In Pet Shop 3.0, the OrderInsert class must be derived from a Serviced Component in order to handle the transaction, as shown as below:

using System;
using System.Collections;
using System.EnterpriseServices;
using System.Runtime.InteropServices;
...
namespace PetShop.BLL {
   /// <summary>
   /// A business component to manage the creation of orders
   /// Creation of an order requires a distributed transaction
   /// so the Order class derives from ServicedComponents
   /// </summary>
   [Transaction(System.EnterpriseServices.TransactionOption.Required)]
   [ClassInterface(ClassInterfaceType.AutoDispatch)]
   [ObjectPooling(MinPoolSize=4, MaxPoolSize=4)]
   [Guid("14E3573D-78C8-4220-9649-BA490DB7B78D")]
   public class OrderInsert : ServicedComponent {
      ...
      /// <summary>
      /// A method to insert a new order into the system
      /// The orderId will be generated within the method and should not
      /// be supplied as part of the order creation the inventory will be 
      /// reduced by the quantity ordered.
      /// </summary>
      /// <param name="order">All the information about the order</param>
      /// <returns>
      /// The new orderId is returned in the order object
      /// </returns>
      [AutoComplete]
      public int Insert(OrderInfo order) {

         // Get an instance of the Order DAL using the DALFactory
         IOrder dal = PetShop.DALFactory.Order.Create();

         // Call the insert method in the DAL to insert the header
         int orderId = dal.Insert(order);

         // Get an instance of the Inventory business component
         Inventory inventory = new Inventory();
         inventory.TakeStock( order.LineItems);
         ...

         // Set the orderId so that it can be returned to the caller
         return orderId;
      }
   }
}

But in Pet Shop 4.0, we can use System.Transaction to insert an order and update the inventory stock. It has implemented the Order.Insert() method by adding a reference to the System.Transaction namespace and wrapping the order insertion and inventory stock reduction methods inside of a TranscationScope, as shown as below:

using System;
using System.Transactions;
using PetShop.IBLLStrategy;

namespace PetShop.BLL {
    /// <summary>
    /// This is a synchronous implementation of IOrderStrategy 
    /// By implementing IOrderStrategy interface, the developer can 
    /// add a new order insert strategy without re-compiling the whole 
    /// BLL.
    /// </summary>
    public class OrderSynchronous : IOrderStrategy {
      ...
        /// <summary>
        /// Inserts the order and updates the inventory stock within 
        /// a transaction.
        /// </summary>
        /// <param name="order">All information about the order</param>
        public void Insert(PetShop.Model.OrderInfo order) {

            using (TransactionScope ts = new                      
TransactionScope(TransactionScopeOption.Required)) {

                dal.Insert(order);

                // Update the inventory to reflect the current inventory 
                // after the order submission.
                Inventory inventory = new Inventory();
                inventory.TakeStock(order.LineItems);

                // Calling Complete commits the transaction.
                // Excluding this call by the end of TransactionScope's
                // scope will rollback the transaction.
                ts.Complete();
            }
        }
    }
}

Obviously, it is simpler by handling Distributed Transaction in Visual Studio 2005 than in Visual Studio 2003. Furthermore, it can improve the performance of program when handling transaction.

posted Wednesday, February 15, 2006 1:44 AM by wayfarer with 0 Comments

Encapsulation of Change (Part One)

The change of the requirement is an enemy we must fight against when we develop the software project. Sometimes, the change of the requirement is endless, so we have to delay our project. Of course, our customers have not been patient with our delay. They would rather believe the difficulty we meet because of the change of requirement is the foxy excuse. The change is like a sword of Damocles over our head. As brooks said, there is no silver bullet in the process of software engineering. It is same that we can't find the "silver bullet" to solve the problem of change. It's a mission impossible. But don't scare of it, we must face its difficulty actively. So Kent Beck, the leader of XP (Extreme Programming), announced that we must embrace the change. He provided the solution to solve it from the angle of Software Engineering Methodology. And now, this article will address issue how to solve the change in the process of developing the software project from the angle of Software Design Methodology. That is "Encapsulation of Change".

 

Design Patterns is the best interpretation of "Encapsulation of Change". No matter we use the Creational Pattern, Structural Pattern, or Behavioral Pattern, our objective is finding the change in Software, then encapsulating the change with abstraction and polymorphism. So, at the beginning of design, we not only implement the User Case, but also mark the existed change. Encapsulation of change means to discover the change or find the change. It is very important.

 

The objective of Creational Pattern is to encapsulate the change when creating an object. For example, it builds the specific abstract factory class when we use Factory Method Pattern or Abstract Factory Pattern. So this factory class encapsulates the creational change in the future. Bridge Pattern encapsulates the change when creating the object inside the product, so that we can replace it with the new object to fit the change of requirement.

 

As far as Structural Pattern, it focuses on the composite style between the object. When we change the structure of object, in fact the dependent relationship between the objects would be changed. Of course if you want to use the Structural Pattern, you will use not only encapsulation, but also inheritance and aggregation. For example, Decorate Pattern describes the dependent relationship between the decorator and the decorated object. The decorator is the abstract class so we can handle the change of the structure of the object. Similarly, Builder Pattern encapsulates the dependent relationship of an implementation of the object. Composite Pattern encapsulates the recursive relationship between the objects.

 

Behavioral Pattern mainly focuses on the behavior of the object. It abstracts the behavior of the object into the specific abstract class or interface, so that it becomes more extensible, because the behavior is the most unstable part in the architecture. For instance, Strategy Pattern abstracts the strategy or algorithm into a sole class or interface in order to encapsulate the strategy. Command Pattern encapsulates the request. State Pattern encapsulates the state. Visitor Pattern encapsulates the style of visiting. Iterator Pattern encapsulates the algorithm of iteration.

 

By using the Design Patterns and encapsulating the change, it ensures the extensible of the architecture. Maybe we can’t drive off the nightmare which was brought by the change, however, if we can foresee some changes at the beginning of the design, it will avoid the trouble caused by the change in the future. So we can say Design Patterns should be a nice spear to fight against the change, although we can’t find out the “Silver Bullet”.

posted Thursday, January 19, 2006 9:59 PM by wayfarer with 0 Comments

My Workspaces

Today, I applied for the workspaces in http://www.gotdotnet.com. It is free and useful. Through it, you can upload your resources, for instance, your projects, your articles and some material you collected. It likes the storehouse so that you can backup your important stuff. At the same time you may share them with your friends who are easy to get them by visiting your workspaces website. By the way, you can assign the catchy alias to your workspaces in order to create the friendly URL at http://workspaces.gotdotnet.com/[alias]. It's cool!

More  exact definition is that "Workspaces is an online collaborative development enviroment where developer can create, host and manage projects throughout the project lifecycle". Yeah, so you can invite your partners to join it. You can check in or check out your projects with teamwork.

So, do you want to own your workspaces? Please visit http://www.gotdotnet.com and create the new workspaces. Of course, welcome to my workspaces which url is http://workspaces.gotdotnet.com/wayfarer.

posted Tuesday, December 27, 2005 10:09 PM by wayfarer with 0 Comments

Terrible Harddisk

A couple of days ago, the harddisk of my laptop met the fatal mistake, it couldn't work. So I had to send my laptop to the headquaters of Company. The result of examination was to change the new harddisk, and my total data stored in the harddisk could not be restored. Terrible! But I must accept this fact. Fortunately, many important material had been backuped, otherwise my loss would be very serious.

So, please remember backupping your important data at any moment!

posted Thursday, December 22, 2005 9:14 PM by wayfarer with 0 Comments

My Plan

These days, I get the precious leisure time. This condition will go on for half year. I'd better making the best of  it. My plan to improve the technical skill is:

1. Learning C++ Programming In the Unix Environment;
2. Depth-Understanding .Net;
3. Obtain the knowledge of Architecture Design, Especially SOA(Service Oriented Architecture);
4. Master the Domain Knowledge of Semiconductor Industry.

Very difficult, but I must try my best.

posted Thursday, December 22, 2005 8:56 PM by wayfarer with 0 Comments

Switch Statement is the poison resulting in Stiff

Head First Design Pattern is nice book that introduces the Design Pattern. There are  a great number of samples in the book. These samples were written with Java. But we can download the C# samples from HeadFirstDesignPatternCSharp.

In this book, it introduces the Abstract Factory Pattern with the case of PizzaStore. This example is very interesting and easy to understand. The class diagram of PizzaStore is as below:

<Figure1.1 Class Diagram of PizzaStore>

Subclasses NYPizzaStore and ChicagoPizzaStore are derived from the Abstract Class PizzaStore. They are all override the CreatePizza() method. This method would create the specific pizza according to the value of string type. It would be invoked by OrderPizza() method which is contained in base class PizzaStore. The codes of OrderPizza() are as below:

    public Pizza OrderPizza(string type)

    {

        Pizza pizza;

        pizza = CreatePizza(type);

 

        pizza.Prepare();

        pizza.Bake();

        pizza.Cut();

        pizza.Box();

        return pizza;

}

CreatePizza is the virtual method. It is overrided in subclass NYPizzaStore:
    protected override Pizza CreatePizza(string type)
    {
        Pizza pizza = null;

        IPizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();

 

        switch (type)

        {

            case "cheese":

                pizza = new CheesePizza(ingredientFactory);

                pizza.Name = "New York Style Cheese Pizza";

                break;

            case "clam":

                pizza = new ClamPizza(ingredientFactory);

                pizza.Name = "New York Style Clam Pizza";

                break;

            case "pepperoni":

                pizza = new PepperoniPizza(ingredientFactory);

                pizza.Name = "New York Style Pepperoni Pizza";

                break;

        }

        return pizza;

}

However it occurs the terrible switch statement. The switch statement is very important when we want to make a choice by the specific condition, but it will hurt the program's flexibility also. Imaging this case, if we want to add the new kind of Pizza, we must modify all of the subclasses which are derived from PizzaStore. Absolutely, it is the poison resulting in the stiff of program structure. So how to eliminate it?

In the CreatePizza() method, its responsibility for creating the Pizza. So we may introduce the special factory class which responsibility for producing the product, that is the specific Pizza Class, like CheesePizza, ClamPizza or PepperoniPizza. The class diagram like this:

<Figure1.2 Class Diagram of PizzaFactory>

We must modify the CreatePizza() method in PizzaStore class. We should accept the parameter which type is IPizzaIngredientFactory. IPizzaIngredientFactory is the factory class. Its function is to make the Pizza which style is different. For instance, it is New York style or Chicago style. If you want to know more detail, please download the sample and refer to the source code. At last, the codes of our PizzaFactory and his subclasses are as below:

    public abstract class PizzaFactory

    {

        public abstract Pizza CreatePizza(IPizzaIngredientFactory ingredientFactory);

}

    public class CheesePizzaFactory : PizzaFactory

    {

        public override Pizza CreatePizza(IPizzaIngredientFactory ingredientFactory)

        {

            return new CheesePizza(ingredientFactory);

        }

}
ClarmPizzaStore and PepperoniPizzaStore are similar to CheesePizzaFactory.

Then we must modify the CreatePizza() method in the PizzaStore family:

    public class NYPizzaStore : PizzaStore

    {

         protected override Pizza CreatePizza(PizzaFactory pizzaFactory)

         {           

             IPizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();

              return pizzaFactory.CreatePizza(ingredientFactory);

         }       

}

    public class ChicagoPizzaStore : PizzaStore

    {

         protected override Pizza CreatePizza(PizzaFactory pizzaFactory)

         {           

             IPizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory();

              return pizzaFactory.CreatePizza(ingredientFactory);

         }       

    }

Of course we should modify the OrderPizza() method in the base class of PizzaStore like this:

    public Pizza OrderPizza(PizzaFactory pizzaFactory)

    {

        Pizza pizza;

        pizza = CreatePizza(pizzaFactory);

 

        pizza.Prepare();

        pizza.Bake();

        pizza.Cut();

        pizza.Box();

        return pizza;

}

Great! we have eliminated the terrible switch statment in the CreatePizza() method. At the same time, it became to simple and clear. The most important thing is that the structure is more flexible than before. If we want to produce the new kind of Pizza, we only add the factory class for new Pizza. We don't need modify the existed class family of PizzaStore any more.

posted Friday, December 16, 2005 12:38 AM by wayfarer with 0 Comments

Easier and more convenient

If you want to determine if string b is substring of string a, you must write the code line in C# 1.0 or 1.1 as below:
      if (a.IndexOf(b) != 0) {//...}

But it is easier and more convenient in C#2.0, like this:
      if (a.Contains(b)) {//...}

If you want to determine if string s is null or empty, the logic expression using C# 1.0 or 1.1 is very complex:
      if (s == null || s.Length == 0) {//...}

But it is easier and more convenient in C#2.0, like this:
      if (String.IsNullOrEmpty(s)) {//...}

Why is it static method of IsNullOrEmpty() method instead of dynamic method,? Otherwise we can invoke it like this:
      if (s.IsNullOrEmpty()) {//...}
It is easier than what we invoke with static method, but in fact, it will throw the NullReferenceException. So static method is the right choice.

posted Wednesday, December 14, 2005 9:26 PM by wayfarer