JIYIK CN >

Current Location:Home > Learning > ALGORITHM >

Strategy Design Pattern and Open-Closed Principle in Java

Author:JIYIK Last Updated:2025/03/19 Views:

The Strategy design pattern is based on the Open/Closed design principle , the famous " OSOLID " of design principles . It is one of the patterns that has become popular in the field of object-oriented analysis and design, along with the Decorator pattern , the Observer pattern , and the Factory pattern . The Strategy pattern allows us to encapsulate possible changes in a process and encapsulate it in a class. By doing so, our process (mostly a method) depends on a strategy, a higher level of abstraction than the implementation. This allows our process to be extended by providing new implementations, but not modified, since introducing a new strategy does not require changing the tested methods. This is how it confirms the Open/Closed design principle.StrategyStrategy

Although like any other design pattern it also introduces a few more classes in your code base, it is worth it as it organizes the code better and provides the much-needed flexibility. It also makes changing properties easy.

The Strategy pattern is very useful, especially for implementing algorithmic strategies such as encryption, compression, comparison, etc. A few examples of the Strategy pattern from JDK are Comparatorand LayoutManager. We can Comparatorthink of as Strategyan interface, defining compare()the method, and now it is up to the class to compare themselves.

This method is used to Collections.sort()do the sorting internally, which confirms OCP as it does not require any changes when the comparison logic changes. Similarly LayoutManager such as GridLayout, BorderLayout helps us to organize components in different ways.


Strategy Design Pattern Example - Open and Closed Design Principle

This example of the strategy pattern can also be seen as an example of the open-closed design principle , which states that the design and code (classes or methods) should be open for extension and closed for modification.

When we say closed to modification, it means that new changes should be implemented by new code, rather than changing existing code. This reduces the possibility of breaking existing battle-tested code.

The strategy pattern is also GOFone of the behavioral patterns in the list, and it first appeared in the classic GOFdesign pattern book.

In this example, we need to filter incoming messages by a certain criteria, such as filtering messages if they are of a certain type. But we know that this criteria may change, and we may need to filter messages based on their size or specific keywords in the content. At the heart of this operation, we MessageUtilshave a filter()method in the class that is responsible for filtering messages.

In the simplest form, we simply remove them from the list of incoming messages. To keep this code intact even when the filtering strategy changes due to new requirements, we will use the Strategy design pattern .

To implement the strategy pattern , we will define a Strategy interface, for example FilteringStrategy, it contains a method that returns true if the MessageisFilterable(Message msg) passed to it can be filtered according to the conditions, which is implemented by the subclass.

This design makes it very easy to introduce new strategies. We have three implementations of this Strategy interface FilterByType, , FilterBySizeand .FilteryByKeyword

Our data object Message contains a type represented by a Java Enum, an integer size and a String content. This design is also extensible because we can introduce any filtering strategy.

This is the UML diagram of Strategy pattern , this time, we use sort strategy to implement different sorting algorithms such as Bubble Sort tml), Quick Sort tml) and Insertion Sort .

 

UML diagram of strategy pattern in Java
UML diagram of strategy pattern in Java

 

Implementation of Strategy Design Pattern in Java

This is a complete code example of Strategy design pattern in Java .

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Java程序实现策略设计模式和开闭设计原则。 
 * filter() 方法使用策略模式来过滤消息。
 *
 * @author jiyik
 */
public class StrategyPattern {

    private static final Logger logger = LoggerFactory.getLogger(StrategyPattern.class);

    public static void main(String args[]) {
        List<Message> messages = new ArrayList<>();
        messages.add(new Message(MessageType.TEXT, 100, "This is test message"));
        messages.add(new Message(MessageType.XML, 200, "How are you "));
        messages.add(new Message(MessageType.TEXT, 300, "Does Strategy pattern follows OCP design principle?"));
        messages.add(new Message(MessageType.TEXT, 400, "Wrong Message, should be filtered"));
       
        messages = filter(messages, new FilterByType(MessageType.XML));
        messages = filter(messages, new FilterByKeyword("Wrong"));
        messages = filter(messages, new FilterBySize(200));
       
    }

    /*
     * 该方法符合开闭设计原则,开放修改,
     * 因为我们可以通过提供FilteringStrategy的实现来提供任何过滤条件,
     * 而无需更改此处的任何代码。 
     * 新功能将由新代码提供。
     */
    public static final List<Message> filter(List<Message> messageList, FilteringStrategy strategy){
       
        Iterator<Message> itr = messageList.iterator();
       
        while(itr.hasNext()){
            Message msg = itr.next();           
            if(strategy.isFilterable(msg)){
                logger.info(strategy.toString() + msg);
                itr.remove();
            }
        }
       
        return messageList;
    }
   
}

We can see that our list contains four messages, one of type XML and three of type TEXT . So when we first filtered the messages by type XML , we can see that only the messages of type XML were filtered. Next, when we filter the messages based on the keyword " Wrong ", only the messages containing that keyword will be filtered.

Finally, when I filter the messages of size 200 , only the messages with size greater than 200 are filtered . So we can Strategydo different things with the same code by providing new implementations of the interface, and that is the power of the Strategy design pattern .

We can also implement strategy pattern in Java using lambda expressions , because we can use lambda in place of anonymous classes in Java. This will make our code more readable and concise.

Important classes in this example

Here are the other important classes for executing this example:

Message.java

class Message{
    private MessageType type;
    private int size;
    private String content;

    public Message(MessageType type, int size, String content) {
        this.type = type;
        this.size = size;
        this.content = content;
    }

    public String getContent() {
        return content;
    }

    public int getSize() {
        return size;
    }

    public MessageType getType() {
        return type;
    }

    @Override
    public String toString() {
        return " Message{" + "type=" + type + ", size=" + size + ", content=" + content + '}';
    }
   
}

This class is used to define different message types.

MessageType.java

/*
 * 枚举以表示不同的消息类型
 */
public enum MessageType {
    TEXT, BYTE, XML;
}

This is the core interface that defines Strategy

FilteringStrategy.java

/*
 * 为该模式定义策略的接口。
 */
public interface FilteringStrategy{
    public boolean isFilterable(Message msg);
}

This is Strategyan implementation of the interface that filters messages by type.

FilterByType.java

/*
 * Strategy 接口的实现,它决定按类型过滤消息。
 */
public class FilterByType implements FilteringStrategy{
    private MessageType type;

    public FilterByType(MessageType type) {
        this.type = type;
    }

    @Override
    public boolean isFilterable(Message msg) {
        return type == msg.getType();
    }

    @Override
    public String toString() {
        return "Filtering By type: " + type;
    }
   
}

Here is Strategyanother implementation of the interface, which filters messages by size:

FilterBySize.java

/*
 * 另一种按大小过滤消息的策略实现
 */
public class FilterBySize implements FilteringStrategy{
    private int maxSize;

    public FilterBySize(int maxSize) {
        this.maxSize = maxSize;
    }   

    @Override
    public boolean isFilterable(Message msg) {
        return msg.getSize() > maxSize;
    }
   
    @Override
    public String toString() {
        return "Filtering By maxSize: " + maxSize;
    }
}

This is Strategyanother implementation of the interface that will filter messages by keyword

FilterByKeyword.java

/*
 * 另一种通过内容中的关键字过滤消息的策略实现。
 */
public class FilterByKeyword implements FilteringStrategy{
    private String keyword;

    public FilterByKeyword(String keyword) {
        this.keyword = keyword;
    }

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    @Override
    public boolean isFilterable(Message msg) {
        return msg.getContent()==null || msg.getContent().contains(keyword);
    }
   
    @Override
    public String toString() {
        return "Filtering By keyword: " + keyword;
    }
   
}

That's all there is to it in this real-world example of Strategy design pattern in Java . As I said, since Strategy pattern confirms the Open-Closed design principle , we can also consider it as an example of Open-Closed design principle in Java. Design patterns are time-tested ways to solve problems in a specific context, and the knowledge of the core patterns can really help us write better code.

For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.

Article URL:

Related Articles

How to implement binary search in Java without recursion?

Publish Date:2025/03/19 Views:196 Category:ALGORITHM

Hey Java programmers, if you want to implement binary search in Java and looking for iterative and recursive binary search algorithms, then you have come to the right place. Today I am going to teach you an important algorithm. In computer

How to implement the singleton pattern in JavaScript ES6+

Publish Date:2025/03/19 Views:54 Category:ALGORITHM

In this article, we will show you how to implement the singleton pattern in JavaScript. If we are a full-stack JavaScript developer, we know that JavaScript is a powerful language and we can build amazing websites with it. On the other hand

How to use the Adapter design pattern in Java

Publish Date:2025/03/19 Views:76 Category:ALGORITHM

The Adapter design pattern in Java , also known as the Wrapper pattern, is another very useful GOF pattern that helps bridge the gap between two classes in Java. According to the Gang of Four pattern list, Adapter is a structural pattern, m

Java Decorator Design Pattern Example

Publish Date:2025/03/19 Views:115 Category:ALGORITHM

Hello everyone, if you want to learn about Decorator Design Pattern in Java , then you have come to the right place. As design patterns are very important while building software and equally important in any core Java interview, it is alway

How to implement the Command Design Pattern in Java

Publish Date:2025/03/19 Views:176 Category:ALGORITHM

Hello everyone, today, we will learn an important design pattern which is often overlooked by Java developers. Yes, I am talking about the Command pattern which helps us write flexible and loosely coupled code to implement actions and event

How to use the State Design Pattern in Java?

Publish Date:2025/03/19 Views:143 Category:ALGORITHM

The State design pattern is a behavioral pattern. The State pattern looks similar to the Strategy pattern, but it helps in managing the object states so that they behave differently in different states. In this example, we will take a famou

Adapter vs Decorator vs Facade vs Proxy Design Pattern in Java

Publish Date:2025/03/19 Views:67 Category:ALGORITHM

There are some striking similarities between the Adapter, Decorator, Facade, and Proxy design patterns as they all use composition and delegation to solve problems. The Adapter pattern wraps an interface and delegates calls to it. Decorator

Observer Design Pattern in Java

Publish Date:2025/03/19 Views:70 Category:ALGORITHM

Observer design pattern in Java is a basic core Java pattern where the Observer monitors any changes in the state or properties of the Subject . For example, a company updates all shareholders about any decision taken by them here the compa

How to use Composite Design Pattern in Java?

Publish Date:2025/03/19 Views:179 Category:ALGORITHM

Hello Java programmers, if you want to learn about Composite Design Pattern in Java , such as how to implement Composite Design Pattern and when to use it, then you have come to the right place. In this article, we will discuss Composite De

Scan to Read All Tech Tutorials

Social Media
  • https://www.github.com/onmpw
  • qq:1244347461

Recommended

Tags

Scan the Code
Easier Access Tutorial