Achieve closure by using Visitor Part II

In the previous article, I showed the way of using Visitor pattern to achieve closure to accomplish ordering stuff. However, that approach focused on the detail of my project business. So, to make a silver bullet for all cases, I will provide you a general solution for your problem.
Now, I define interface IOrderable

public interface IOrderable

{

IOrderVisitor OrderVisitor { get;}

void Accept(IOrderVisitor visitor);

}

Your data class must implement IOrderable to be orderable.

Next, I define interface IOrderVisitor

public interface IOrderVisitor

{

ComparerInfo Visit(IOrderable host);

}

Correspond to each IOrderable implementation, you must make an IOrderVisitor implementation.

Then, I define a base class ComparerInfo

public class ComparerInfo : IComparable

{

#region IComparable Members

public virtual int CompareTo(ComparerInfo other)

{

return ComparatorUtility.Compare(this, other);

}

#endregion

}

Now, for your business for ordering stuff, you define your own class that inherits from ComparerInfo and optional override method CompareTo.

And final class Comparator that will showed below, will do the ordering stuff for you.

public class Comparator : Comparer

{

#region IComparer Members

public override int Compare(IOrderable x, IOrderable y)

{

if (x == null || y == null)

{

return Comparer.Default.Compare(x, y);

}

return x.OrderVisitor.Visit(x).CompareTo(y.OrderVisitor.Visit(y));

}

#endregion

}

Case Study:
I will present here the way you can apply above solution to the problem in previous article.
This is your business interface

public interface IItemDetailInfo

{

String Name { get; set; }

}

And this is your ComparerInfo to perform the sorting

public class ItemComparer : ComparerInfo

{

public ItemComparer (string sequenceOrder)

{

this.sequenceOrder = sequenceOrder;

}

private string sequenceOrder;

public string SequenceOrder

{

get { return sequenceOrder; }

set { sequenceOrder = value; }

}

}

Now, this is stuff for all Item

AnyItem

public class AnyItemDetailInfo : IItemDetailInfo, IOrderable

{

public AnyItemDetailInfo(string name)

{

this.Name = name;

this.Accept(new AnyOneVisitor());

}

private string name;

public string Name

{

get { return name; }

set { name = value; }

}

private IOrderVisitor orderVisitor;

public IOrderVisitor OrderVisitor

{

get

{

return this.orderVisitor;

}

}

public void Accept(IOrderVisitor visitor)

{

this.orderVisitor = visitor;

}

}

public class AnyItemVisitor : IOrderVisitor

{

public ComparerInfo Visit(IOrderable host)

{

return new ItemComparer(string.Empty);

}

}

ProductItem

public class ProductDetailInfo : IItemDetailInfo, IOrderable

{

public ProductDetailInfo(string name, string sequenceNumber)

{

this.Name = name;

this.SequenceNumber = sequenceNumber;

IOrderVisitor visitor = new ProductVisitor();

this.Accept(visitor);

}

private string name;

public string Name

{

get { return name; }

set { name = value; }

}

private string sequenceNumber;

public string SequenceNumber

{

get { return sequenceNumber; }

set { sequenceNumber= value; }

}

private IOrderVisitor orderVisitor;

public IOrderVisitor OrderVisitor

{

get

{

return this.orderVisitor;

}

}

public void Accept(IOrderVisitor visitor)

{

this.orderVisitor = visitor;
}

}

public class ProductVisitor : IOrderVisitor

{

public ComparerInfo Visit(IOrderable host)

{

return new ItemComparer((host as ProductDetailInfo).SequenceNumber);

}

}

CategoryItem

public class CategoryDetailInfo : IItemDetailInfo, IOrderable

{

public CategoryDetailInfo(string name, string sequenceNumber)

{

this.Name = name;

this.SequenceNumber= sequenceNumber;

this.Accept(new CategoryVisitor());

}

private string name;

public string Name

{

get { return name; }

set { name = value; }

}

private string sequenceNumber;

public string SequenceNumber

{

get { return sequenceNumber; }

set { sequenceNumber= value; }

}

private IOrderVisitor orderVisitor;

public IOrderVisitor OrderVisitor

{

get

{

return this.orderVisitor;

}

}

public void Accept(IOrderVisitor visitor)

{

this.orderVisitor = visitor;

}

}

public class CategoryVisitor : IOrderVisitor

{

public ComparerInfo Visit(IOrderable host)

{

return new ItemComparer((host as CategoryDetailInfo).SequenceNumber);

}

}

Finally, this is Unit Test code

ArrayList itemList = new ArrayList();

itemList .Add(new UserDetailInfo(“Product”, “001”));

itemList .Add(new GroupDetailInfo(“Category”, “001”));

itemList .Add(new AnyItemDetailInfo(string.Empty));

itemList .Sort(new Comparator());

foreach (IItemDetailInfo item in itemList )

{

Console.WriteLine(item .GetType().ToString() + “: ” + item .Name);

}

Thanks for reading. I’d like to mention again: Your feedbacks are very important!

Rgds
Nguyen Minh Dung

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: