One, foreword

Working partners in the Internet may have developed management system, such a system has a characteristic – query conditions thief, and each condition needs to recommend search (that is, the drop-down selection below).

Small white: this also too troublesome, make so flower in whistle stem what ah, direct input fuzzy search not finish matter.

Leader: I thought he was too young. Fuzzy search efficiency is too poor, and so fuzzy search does not go to the index, a lot of conditions, business is not to ridicule the system * * 😄. The advantage of our use of recommendation search is to average the performance of fuzzy search consumption to each search condition, so that we do not query the precise query button, this query speed can fly!

Small white: yes, the user experience rose a level again!

Za as a craftsman spirit of the siege lion, the details of this must take hold 😎

So many search criteria, many friends directly distinguish the type if-else simple and efficient to complete the needs.

Development is good, refactoring is crying.

With so many if-else scenarios, it’s a good opportunity to upgrade your code to b-grid. It’s best to use policy mode. Factory mode is more creative!

Second, the principle of

The following is a guide to use the strategic pattern to complete the requirements. To apply this knowledge, let’s first get to the heart of the idea, and then let’s look at the structure.

Abstract policy class: Defines rules and is the entry point of policy logic policy class: Subclasses of abstract policy class (concrete implementation) Policy context: The place where concrete logic classes are stored and executed

It’s not that complicated, right? You get it, so let’s take a look at the case.

Three cases,

** * recommend a search abstract strategy class */ public abstract class abstractstStrategy <T> {/** * recommend a search strategy * @param suggestParam contains the policy type and search keyword  * @return */ public abstract T suggest(SuggestParam suggestParam); }Copy the code

We define the abstract policy class first, and make rules for the concrete policy class. At the same time, it is also a key role for us to auto-assemble the context later.

Then there are the concrete policy classes.

*/ @service @suggestType (type = SuggestTypeEnum.ORDER_NAME) public class OrderNameSuggestStrategy Suggeststrategy <T> {@override public T suggest(SuggestParam) {return null; }}Copy the code
SuggestType(type = SuggestTypeEnum.CUSTOMER_NAME) public class */ @service @suggestType (type = SuggestTypeEnum CustomerNameSuggestStrategy extends AbstractSuggestStrategy<T> { @Override public T suggest(SuggestParam suggestParam) { // query logic return null; }}Copy the code

Finally, define a policy context

@Component Public class StrategyContext {// This is the key feature of the autowage context, which takes advantage of Spring's special List injection. // Classes that inherit AbstractSuggestStrategy abstract classes and are managed by Spring will be loaded into this list. @Resource private List<AbstractSuggestStrategy> suggestStrategies; private static Map<SuggestTypeEnum, AbstractSuggestStrategy> suggestStrategyMap = Maps.newHashMap(); @postconstruct public void init() {if (collectionutil.isempty (suggestStrategies)) {return; } // go through the list, Structural types and specific are spring the mapping relationship management class suggestStrategies. ForEach (strategy - > {SuggestType SuggestType = AopUtils.getTargetClass(strategy).getAnnotation(SuggestType.class); suggestStrategyMap.put(suggestType.type(), strategy); }); } /** * Get the policy class that is managed by Spring from the enum type * @param suggestType * @return */ public static abstractstStrategy getStrategy(StoreSuggestTypeEnum suggestType) { AbstractSuggestStrategy suggestStrategy = suggestStrategyMap.get(suggestType); if (null == suggestStrategy) { throw new IllegalArgumentException("not fond suggestType"); } return suggestStrategy; }}Copy the code

In fact, this is an extra step, let the policy class by Spring management, and establish a mapping relationship, we use key to obtain the corresponding policy class. Because our project is basically based on Spring in the development, the normal query logic of policy class also needs to rely on Spring management class, so the unified development can be more convenient.

The context can then be retrieved in the business logic

** * @description */ @slf4j @service public class SuggestBizService {public Object suggest(SuggestParam) suggestParam) { SuggestTypeEnum suggestTypeEnum = SuggestTypeEnum.findByCode(suggestParam.getSuggestType()); SuggestTypeEnum == null) {throw new StoreApiException(" Please specify the correct query type "); } AbstractSuggestStrategy suggestStrategy = StrategyContext.getStrategy(suggestTypeEnum); return suggestStrategy.suggest(suggestParam); }}Copy the code

Thoughtful Rose also posted some other code implemented above

*/ @data @equalSandHashCode @accessors (chain = true) public class SuggestParam implements Serializable {@APIModelProperty (value = "Suggest type ORDER_NAME: order name, CUSTOMER_NAME: customer name ", required = true) private String suggestType; @apiModelProperty (value = "suggest keyword ") @notBlank (message = "suggest keyword not null ") @length (Max = 50, Message = "keyword < 50 ") private String keyword; }Copy the code
/** * @description Policy TYPE annotation */ @target (elementtype.type) @Retention(retentionPolicy.runtime) public @interface SuggestType  { SuggestTypeEnum type(); }Copy the code
/** * @description suggest */ @get@allargsconstructor public enum SuggestTypeEnum {ORDER_NAME("ORDER_NAME", "Order name "), CUSTOMER_NAME("CUSTOMER_NAME"," customer name "); private final String code; private final String name; public static SuggestTypeEnum findByCode(String code) { for (SuggestTypeEnum typeEnum : values()) { if (typeEnum.getCode().equals(code)) { return typeEnum; } } return null; }}Copy the code

Is not complicated haha ~

In fact, the core idea of strategy mode is to implement different strategies according to different types.

Four,

If -else statements in our method can be optimized by using the strategic design pattern. Using a large number of if-else statements will make the code difficult to expand and maintain, and it will also be difficult to maintain when various problems occur in the later period. After using such a design pattern can meet the isolation and extensibility, while the responsibility of the class is also single, for constantly increasing requirements are also very convenient to undertake.

Design mode is actually a general paradigm summarized in the development of predecessors, we should reasonably learn each design mode suitable for the scene, what problems to solve. Don’t force design patterns into your code either.

In the face of a variety of development scenarios, we should think more, more precipitation, can make their own code more elegant, better expansion.

Refueling workers! Ollie give 😎

I’m Rose, thank you for watching, your likes are the biggest power of Rose output, we will see you in the next article!

Five, series recommendation

How to automatically construct a BO input parameter for each call