About design patterns in the. NET framework--applying policy patterns to list sorting _ Practical Tips

Source: Internet
Author: User
Tags exception handling inheritance
Simple Type sorting

Programming when encountering sorts in the usual however, use. NET the most common is to sort generic list<t>, if T is simple data type sort

Copy Code code as follows:

Public list<int> sortsimplelist (list<int> List)
{
List. Sort ();
return list;
}

The same is true for simple type list<t> such as String, and if we're going to have complex objects, we know that list<t> sort () is finally sorted with a quick sort, a quick sort, What sort needs to know the comparison between the items in the list, if it is a simple int type, direct judgment can, to achieve the IComparable interface object, you can call its CompareTo () to achieve the item comparison size, the following is a quick sort of writing

Copy Code code as follows:

void Sort<t> (t[] array, int left, int. right, icomparer_sly<t> comparer) where t:icomparable
{
if (left < right)
{
T middle = array[(left + right)/2];
int i = left-1;
Int J = right + 1;
while (true)
{
while (Array[++i). CompareTo (middle) < 0);

while (ARRAY[--J). CompareTo (middle) > 0);

if (i >= j)
Break

T temp = array[i];
Array[i] = Array[j];
ARRAY[J] = temp;
}

Sort (array, left, i-1, comparer);
Sort (Array, j + 1, right, comparer);
}
}

Problem

Although the first two situations can be sorted, it is not possible to require all objects to be sorted to implement the IComparable interface, even if you can ensure that each object implements the IComparable interface, if you want to implement multiple fields within the object, such as student objects, Sometimes want to sort by name, sometimes grades, sometimes age, this how to break

In accordance with the idea of object-oriented, to change out of the package, packaging changes, for us to sort list<t> changes in fact is how to compare the size of the two objects of the algorithm, if we can take out the algorithm, sorting on a lot of simple, no matter what sort, the algorithm is made of, The part of the package we want to encapsulate is how to compare the size of the two item, in order to achieve scalability we have to follow another important principle of object-oriented design, programming for interfaces, not for implementation.

writing a generic list<t> sorting method

First define an interface, which has a method to compare the size of the item, in the sort of time passed as a parameter, of course, is passed into its implementation class, with this idea, we can write our own list<t> sorting method

Copy Code code as follows:

public interface mparer_sly<t>{
int Compare (t x, t y);
}

Then for testing, we add a wrapper for list<t>, write a sort method of our own, and implement it internally with a quick sort. have been puzzled by our change part--The comparison size algorithm, we have to block it up, as a parameter passed in

Copy Code code as follows:

Using System;
Using System.Collections.Generic;

Namespace Test.stategy
{public class listtest<t>
{
Public list<t> List = new list<t> ();
public void Sort (icomparer_sly<t> comparer)
{
t[] array = list. ToArray ();
int left = 0;
int right = array. Length-1;
QuickSort (array, left, right, comparer);
List = new list<t> (array);
}

private void Quicksort<s> (s[] array, int left, int. right, icomparer_sly<s> comparer)
{
if (left < right)
{
S middle = array[(left + right)/2];
int i = left-1;
Int J = right + 1;
while (true)
{
while (Comparer.compare (Array[++i], middle) < 0);

while (Comparer.compare (Array[--j], middle) > 0);

if (i >= j)
Break

S temp = array[i];
Array[i] = Array[j];
ARRAY[J] = temp;
}

QuickSort (array, left, i-1, comparer);
QuickSort (Array, j + 1, right, comparer);
}
}
}
}

For example, now we have a student entity.

Copy Code code as follows:

public class Student
{
public Student (int ID, string name)
{
This.id = ID;
This. name = name;
}
public int ID {get; set;}
public string Name {get; set;}
}

If you want to sort the list<t> of this entity, we just need a class studentcomparer that implements the icomparer_sly<student>, and implement its comparison size method internally--compare (), At the same time we can add the control of ascending or descending sort

Copy Code code as follows:

Class studentcomparer:icomparer_sly<student>
{
private string expression;
private bool isascending;
Public Studentcomparer (string expression, bool isascending)
{
this.expression = expression;
this.isascending = isascending;
}

public int Compare (Student x, Student y)
{
Object V1 = GetValue (x), V2 = GetValue (y);
if (v1 is string | | v2 is string)
{
string S1 = ((V1 = = null)? "": v1. ToString (). Trim ());
String s2 = ((v2 = = null)? "": V2. ToString (). Trim ());
if (S1. Length = = 0 && s2. Length = = 0)
return 0;
else if (S2. Length = = 0)
return-1;
else if (S1. Length = = 0)
return 1;
}

Here lazy call system methods, not their own implementation, in fact, is to compare the size of two arbitrary types of data, their own to achieve more trouble
if (!isascending)
Return Comparer.Default.Compare (v2, v1);
Return Comparer.Default.Compare (v1, v2);
}

Private Object GetValue (Student stu)
{
Object v = null;
switch (expression)
{
Case "id":
v = stu.id;
Break
Case "Name":
v = stu. Name;
Break
Default
v = null;
Break
}
return v;
}
}

Let's test it, okay?

Copy Code code as follows:

static void Main (string[] args)
{
listtest<student> test = new listtest<student> ();
for (int i = 0; i < i++)
{
Student stu = new Student (i,string. Format ("N_" + (9-i));
TEST.LIST.ADD (Stu);
}
Console.WriteLine ("Meta Data");
for (int i = 0; i < test.list.count;i++)
{
Console.WriteLine (String. Format ("id:{0}, Name:{1}", Test.list[i].id, Test.list[i]. Name));
}

Console.WriteLine ("Name incremented");
Test. Sort (New Studentcomparer ("name", true));
for (int i = 0; i < Test.list.Count; i++)
{
Console.WriteLine (String. Format ("id:{0}, Name:{1}", Test.list[i].id, Test.list[i]. Name));
}
}

Look at the effect

how the. NET List sort is sorted for us

You can see this when you call the List<t> sort () method by using Ilspy to decompile. Sort (0, this. Count, NULL); Then go inside, after a series of exception processing will call Array.sort<t> (This._items, index, count, comparer); This._items is to transform the list content into several groups, and then go through some column exception processing, call the method arraysorthelper<t> Default.sort (array, index, length, comparer); It's just like the way we wrote it, but Microsoft added a lot of exception handling and algorithm optimization.

Policy Mode

Look at the above example and we can get to the point and talk about our strategy model. The policy pattern defines a series of algorithms and encapsulates each one, and allows them to be replaced with each other. The policy pattern allows the algorithm to vary independently from the customer who uses it. (Original: The strategy pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients this use it.)

This pattern involves three roles:

Environment (context) Role: holds a reference to a strategy class. Abstract policy (Strategy) role: This is an abstract role, usually implemented by an interface or abstract class. This role gives all the interfaces required by the specific policy class. Specific policy (concretestrategy) Role: Wraps the associated algorithm or behavior.

I believe you can conveniently put the class in our example above the role of the policy model, the IComparer interface is our abstract policy role, the Listtest<t> class holds an abstract policy reference is the environment (in the Sort method, You can actually define an interface as a property of a class, assign a value in a constructor, but not for this scenario, after all, not all lists need to be sorted, they cannot be forced to accept an interface that may not be used, and of course it is appropriate for each instance to use a policy scenario. There is no doubt that our class to implement IComparer abstract policies is a specific strategy.

Working with scenes

The strategy model is easy to understand, but it's a good way to understand encapsulation changes and two object-oriented design principles for interface programmers, and let's see when we're going to use the strategy model

1, multiple classes only differ in the performance behavior, you can use the strategy mode, the runtime dynamically select the behavior to perform.

2. Different policies (algorithms) need to be used in different situations, and these policies have a unified interface.

3, the customer hides the specific strategy (algorithm) The realization details, each other completely independent.

advantages and disadvantages of the strategy model

Advantages:

1. Provides an alternative to inheritance, and retains the benefits of inheritance (code reuse) more flexible than inheritance (the algorithm is independent and can be extended arbitrarily).

2. Use combination to avoid multiple conditional transfer statements in the program, making the system more flexible and easy to expand.

3, adhere to most grasp principles and common design principles, high cohesion, low coupling.

Disadvantages:

1, because each specific policy class will produce a new class, it will increase the number of classes the system needs to maintain.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.