Design pattern ~ behavior pattern ~ strategy pattern ~ strategy pattern.

lyfGeek 2022-05-22 11:58:12 阅读数:437

designpatternbehaviorpatternstrategy

Design patterns ~ Behavioral patterns ~ The strategy pattern ~ Strategy Pattern.



what.

There are many travel modes we choose to travel , You can ride a bike 、 You can take a car 、 You can take the train 、 You can fly .

As a procedural ape , Development needs to choose a development tool , Of course, there are many tools for code development , You can choose IntelliJIDEA Development , You can also use Eclipse Development , You can also use some other development tools .

This pattern defines a series of algorithms , And encapsulate each algorithm , Make them interchangeable , And the change of algorithm will not affect the customers who use the algorithm . The strategy pattern belongs to the object behavior pattern , It encapsulates the algorithm , Separate the responsibility of using the algorithm from the implementation of the algorithm , And delegate to different objects to manage these algorithms .


structure .

The main roles of the strategy model are as follows .

  • Abstract strategy (Strategy) class .
    This is an abstract character , Usually implemented by an interface or abstract class . This role gives all
    The interface required by the specific policy class .

  • Specific strategies (Concrete Strategy) class .
    Implements the interface of abstract policy definition , Provide specific algorithm implementation or behavior .

  • Environmental Science (Context) class .
    Hold a reference to a policy class , Finally, the client calls .


【eg.】 Sales promotion activity .

A department store's annual promotional activities . For different festivals ( Spring Festival 、 Mid-Autumn Festival 、 Christmas ) Launch different promotions , The promoter will show the promotion to the customer .

 Insert picture description here

package com.geek.strategy;
/** * A common interface for all department store promotions ~ Abstract strategy . * * @author geek */
public interface IStrategy {

void show();
}

Specific strategic roles (Concrete Strategy): Specific promotions for each festival .

package com.geek.strategy;
/** * Promotion for the Spring Festival . * * @author geek */
public class StrategyA implements IStrategy {

@Override
public void show() {

System.out.println(" Promotion for the Spring Festival ~ Buy 1 Get 1 FREE .");
}
}
package com.geek.strategy;
/** * Specific strategies ~ Encapsulation algorithm . * Promotion for the Spring Festival . * * @author geek */
public class StrategyA implements IStrategy {

@Override
public void show() {

System.out.println(" Promotion for the Spring Festival ~ Buy 1 Get 1 FREE .");
}
}
package com.geek.strategy;
/** * Specific strategies ~ Encapsulation algorithm . * Promotional activities for Christmas . * * @author geek */
public class StrategyC implements IStrategy {

@Override
public void show() {

System.out.println(" Promotional activities for Christmas ~ full 1000 Yuan plus one yuan for any 200 Goods below yuan .");
}
}

Environmental roles (Context): Used to connect context , That is to sell sales promotion to customers , This can be understood as a salesman .

package com.geek.strategy;
/** * Environmental roles (Context). * Used to connect context . * That is to sell sales promotion to customers , This can be understood as a salesman . * * @author geek */
public class SalesMan {

/** * Aggregate policy class object . * References holding Abstract policy roles . */
private IStrategy strategy;
public SalesMan(IStrategy strategy) {

this.strategy = strategy;
}
/** * The promoter shows the promotion to the customer . */
public void salesManShow() {

strategy.show();
}
}
package com.geek.strategy;
/** * @author geek */
public class Client {

public static void main(String[] args) {

// Spring Festival is coming. , Use the Spring Festival Promotion .
IStrategy strategyA = new StrategyA();
SalesMan salesMan = new SalesMan(strategyA);
// The salesperson shows the promotion .
salesMan.salesManShow();
// Promotion for the Spring Festival ~ Buy 1 Get 1 FREE .
// The Mid Autumn Festival is coming , Use the Mid Autumn Festival Promotion .
IStrategy strategyB = new StrategyB();
salesMan.setStrategy(strategyB);
// The salesperson shows the promotion .
salesMan.salesManShow();
// Promotional activities for the Mid Autumn Festival ~ full 200 reduce 50.
// Christmas is coming , Use Christmas promotions .
IStrategy strategyC = new StrategyC();
salesMan.setStrategy(strategyC);
// The salesperson shows the promotion .
salesMan.salesManShow();
// Promotional activities for Christmas ~ full 1000 Yuan plus one yuan for any 200 Goods below yuan .
}
}

advantage .

  • Policy classes can be switched freely .
    Because the policy classes all implement the same interface , So they can switch freely between them .

  • extensible .
    To add a new policy, you just need to add a specific policy class , Basically no need to change the original code , accord with “ Opening and closing principle “.
    Avoid using multiple conditional selection statements (if else), Fully embody the idea of object-oriented design .


shortcoming .

  • The client must know all the policy classes , And decide which strategy class to use .

  • The strategy pattern will result in many strategy classes , You can reduce the number of objects to a certain extent by using the share pattern .


Use scenarios .

  • When a system needs to dynamically choose one of several algorithms , Each algorithm can be encapsulated in a policy class .

  • A class defines multiple behaviors , And these behaviors appear in the form of multiple conditional statements in the operation of this class , Instead of these conditional statements, each conditional branch can be moved into its own policy class .

  • The algorithms in the system are completely independent of each other , And the implementation details of specific algorithms are required to be hidden from customers .

  • The system requires that customers using algorithms should not know the data they operate on , You can use policy patterns to hide data structures related to the algorithm .

  • Multiple classes differ only in their behavior , You can use the strategy pattern , Select the specific behavior to execute dynamically at runtime .


JDK The source code parsing .

Comparator The strategic model in . stay Arrays There is one in the class sort(); Method .

public class Arrays {

/** * Sorts the specified array of objects according to the order induced by * the specified comparator. All elements in the array must be * <i>mutually comparable</i> by the specified comparator (that is, * {@code c.compare(e1, e2)} must not throw a {@code ClassCastException} * for any elements {@code e1} and {@code e2} in the array). * * <p>This sort is guaranteed to be <i>stable</i>: equal elements will * not be reordered as a result of the sort. * * <p>Implementation note: This implementation is a stable, adaptive, * iterative mergesort that requires far fewer than n lg(n) comparisons * when the input array is partially sorted, while offering the * performance of a traditional mergesort when the input array is * randomly ordered. If the input array is nearly sorted, the * implementation requires approximately n comparisons. Temporary * storage requirements vary from a small constant for nearly sorted * input arrays to n/2 object references for randomly ordered input * arrays. * * <p>The implementation takes equal advantage of ascending and * descending order in its input array, and can take advantage of * ascending and descending order in different parts of the the same * input array. It is well-suited to merging two or more sorted arrays: * simply concatenate the arrays and sort the resulting array. * * <p>The implementation was adapted from Tim Peters's list sort for Python * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> * TimSort</a>). It uses techniques from Peter McIlroy's "Optimistic * Sorting and Information Theoretic Complexity", in Proceedings of the * Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-474, * January 1993. * * @param <T> the class of the objects to be sorted * @param a the array to be sorted * @param c the comparator to determine the order of the array. A * {@code null} value indicates that the elements' * {@linkplain Comparable natural ordering} should be used. * @throws ClassCastException if the array contains elements that are * not <i>mutually comparable</i> using the specified comparator * @throws IllegalArgumentException (optional) if the comparator is * found to violate the {@link Comparator} contract */
public static <T> void sort(T[] a, Comparator<? super T> c) {

if (c == null) {

sort(a);
} else {

if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
}

Arrays It's an environment role class , This sort(); Method can pass a new strategy to Arrays Sort according to this strategy .

eg. Test class .

package com.geek.strategy.demo;
import java.util.Arrays;
import java.util.Comparator;
/** * @author geek */
public class Demo {

public static void main(String[] args) {

Integer[] data = {
12, 2, 3, 4, 2, 5, 1};
// Implement descending sort .
Arrays.sort(data, new Comparator<Integer>() {

@Override
public int compare(Integer o1, Integer o2) {

return o2 - o1;
}
});
System.out.println(Arrays.toString(data));
// [12, 5, 4, 3, 2, 2, 1]
}
}

Here we are calling Arrays Of sort(); When the method is used , The second parameter passes Comparator The subclass object of the interface . therefore Comparator It plays the role of abstract policy , The concrete subclass of implementation plays the role of concrete policy . Environment role class
(Arrays) You should hold a reference to an abstract policy to invoke . that ,Arrays Class sort(); Whether the method is used or not Comparator Implement... In subclasses compare(); Methods? ? Let's continue to look at TimSort Class sort(); Method .

class TimSort<T> {

/** * Sorts the given range, using the given workspace array slice * for temp storage when possible. This method is designed to be * invoked from public methods (in class Arrays) after performing * any necessary array bounds checks and expanding parameters into * the required forms. * * @param a the array to be sorted * @param lo the index of the first element, inclusive, to be sorted * @param hi the index of the last element, exclusive, to be sorted * @param c the comparator to use * @param work a workspace array (slice) * @param workBase origin of usable space in work array * @param workLen usable size of work array * @since 1.8 */
static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,
T[] work, int workBase, int workLen) {

assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;
int nRemaining = hi - lo;
if (nRemaining < 2)
return; // Arrays of size 0 and 1 are always sorted
// If array is small, do a "mini-TimSort" with no merges
if (nRemaining < MIN_MERGE) {

int initRunLen = countRunAndMakeAscending(a, lo, hi, c);
binarySort(a, lo, hi, lo + initRunLen, c);
return;
}
...
/** * Returns the length of the run beginning at the specified position in * the specified array and reverses the run if it is descending (ensuring * that the run will always be ascending when the method returns). * * A run is the longest ascending sequence with: * * a[lo] <= a[lo + 1] <= a[lo + 2] <= ... * * or the longest descending sequence with: * * a[lo] > a[lo + 1] > a[lo + 2] > ... * * For its intended use in a stable mergesort, the strictness of the * definition of "descending" is needed so that the call can safely * reverse a descending sequence without violating stability. * * @param a the array in which a run is to be counted and possibly reversed * @param lo index of the first element in the run * @param hi index after the last element that may be contained in the run. It is required that {@code lo < hi}. * @param c the comparator to used for the sort * @return the length of the run beginning at the specified position in * the specified array */
private static <T> int countRunAndMakeAscending(T[] a, int lo, int hi,
Comparator<? super T> c) {

assert lo < hi;
int runHi = lo + 1;
if (runHi == hi)
return 1;
// Find end of run, and reverse range if descending
if (c.compare(a[runHi++], a[lo]) < 0) {
 // Descending
while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) < 0)
runHi++;
reverseRange(a, lo, runHi);
} else {
 // Ascending
while (runHi < hi && c.compare(a[runHi], a[runHi - 1]) >= 0)
runHi++;
}
return runHi - lo;
}
}

The code above will eventually run to countRunAndMakeAscending(); In this method . We can see , It only took compare(); Method , So in calling Arrays.sort(); The method is specific compare(); Override the class object of the method , This is also Comparator A method in an interface that must be implemented by a subclass .

copyright:author[lyfGeek],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/142/202203140552360218.html