Encapsulation changes (III)

Source: Internet
Author: User

To imagine such a requirement, we need to provide a sort component for our framework. Currently, Bubble Sorting is required.AlgorithmAccording to the idea of "interface-oriented programming", we can provide a unified interface isort for these sorting algorithms, in which there is a method sort (), it can accept an object array parameter. Returns the array after sorting the array. The interface is defined as follows:

Public interface isort
{
Void sort (ref object [] besorted );
}

The class diagram is as follows:

However, for sorting, the results are returned in different order, such as ascending or descending order. The simplest method is to use the if statement to achieve this purpose. For example, in the quicksort class:

Public class quicksort: isort

{

Private string m_sorttype;

Public quicksort (string sorttype)

{

M_sorttype = sorttype;

}

Public void sort (ref object [] besorted)

{

If (m_sorttype.toupper (). Trim () = "ascending ")

{

//Execute fast sorting in ascending order;

}

Else

{

//Execute a fast sort in descending order;

}

}

}

Of course, we can also define sorttype of string type as Enumeration type to reduce the possibility of errors. However, read carefullyCode, We can find that such code is very rigid. Once we need to expand, if we want to add a new sort order, such as dictionary order, we will face a very heavy workload. That is to say, changes have taken place. Through analysis, we found that the so-called sorting order is exactly the most critical part of the sorting algorithm, which determines who is ranked first and who is ranked after. However, it is not a sort algorithm, but a comparison strategy. The latter is a comparison behavior.

If you carefully analyze the classes that implement the isort interface, such as the quicksort class, it needs to compare the two objects when implementing the sorting algorithm. According to the refactoring method, we can extract a private method compare () in the sort method, and use the returned Boolean value to determine which object is in the front and which object is in the back. Obviously, what may change is this comparative behavior. Using the principle of "encapsulation abstraction", we should establish a proprietary interface icompare for this behavior, however, class objects that implement ascending, descending, or dictionary sorting are defined respectively.

 

We introduce the icompare interface object in every class constructor that implements the isort interface, this establishes a weak coupling relationship between the Sorting Algorithm and the comparison algorithm (because this relationship is related to the abstract icompare Interface), such as the quicksort class:

Public class quicksort: isort

{

Private icompare m_compare;

Public quicksort (icompare compare)

{

M_compare = compare;

}

Public void sort (ref object [] besorted)

{

//Implementation

For (INT I = 0; I <besorted. Length-1; I ++)

{

If (m_compare.compare (besorted [I], besorted [I + 1 ))

{

//Omitted;

}

}

//Implementation

}
}

The class diagram is as follows:

By encapsulating the comparison policy to cope with its changes, it is clearly the design of the stategy mode. In fact, the Sorting Algorithm here may also change, for example, binary tree sorting. Because we have introduced the idea of "interface-oriented programming", we can easily add a new class binarytreesort to implement the isort interface. For the caller, the implementation of the isort interface is also a strategy mode. At this time, the class structure is completely a state of extension development, which can fully adapt to the changes in the new requirements of class library callers.

Taking petshop as an example, this project involves order management, such as inserting orders. Considering the relationship between visits, petshop provides synchronous and asynchronous order management methods. Obviously, only one of the two methods can be used in actual applications, and is determined by the specific application environment. To cope with such frequent changes, we still need to use the principle of "encapsulation changes" to create abstract-level objects, that is, the iorderstrategy interface:

Public interface iorderstrategy

{

Void insert (petshop. model. orderinfo order );

}

Define two classes: ordersynchronous and orderasynchronous. The class structure is as follows:

In petshop, because the user may change the order insertion policy at any time, the Order domain objects at the business layer cannot be coupled with specific order policy objects. That is to say, in the domain object order class, a specific order policy object cannot be created, as shown in the following code:

Iorderstrategy orderinsertstrategy = new ordersynchronous ();

In Martin Fowler'sArticleIn IOC container and dependency injection mode, a solution to this type of problem is proposed, which is called dependency injection. However, because petshop does not use IOC containers such as sping. net, the dependency issue is usually solved by using the configuration file and reflection. In the order class of the domain object, it is implemented as follows:

Public class order

{

Private Static readonly iorderstategy orderinsertstrategy = loadinsertstrategy ();

Private Static iorderstrategy loadinsertstrategy ()

{

// Look up which strategy to use from config file

String Path = configurationmanager. receivettings ["orderstrategyassembly"];

String classname = configurationmanager. etettings ["orderstrategyclass"];

 

// Load the appropriate assembly and class

Return (iorderstrategy) Assembly. Load (PATH). createinstance (classname );

}

}

In the configuration file web. config, configure the following section:

<Add key = "orderstrategyassembly" value = "petshop. BLL"/>
<Add key = "orderstrategyclass" value = "petshop. BLL. ordersynchronous"/>

This is actually a compromise of the service locator mode. Put the logic of locating and creating dependent objects directly into the object. In the petshop example, it is a good method. After all, in this example, there are not many objects that require dependency injection. However, we can also think of it as a helpless compromise. Once this dependency injection logic increasesProgramThis requires a dedicated lightweight IOC container.

It seems that the topic of "encapsulation change" has been removed. But in fact, we need to understand that the use of abstract methods to encapsulate changes is certainly the king of response to changes in demand, but it can only lift the coupling relationship between the caller and the called, as long as the creation of specific objects is involved, even if the factory mode is introduced, the creation of specific factory objects is still indispensable. Then, for such objects that have been encapsulated and changed, we should also take full advantage of the "dependency injection" method to completely remove the coupling between the two.

 

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.