110.md 7.8 KB
Newer Older
W
wizardforcel 已提交
1 2 3 4
# 策略设计模式

> 原文: [https://howtodoinjava.com/design-patterns/behavioral/strategy-design-pattern/](https://howtodoinjava.com/design-patterns/behavioral/strategy-design-pattern/)

W
wizardforcel 已提交
5
**策略设计模式**是行为设计​​模式,在该行为型设计模式中,我们选择[算法](//howtodoinjava.com/java-algorithms-implementations/)或任务在运行时的特定实现 - 从同一任务的多个其他实现中选择。
W
wizardforcel 已提交
6

W
wizardforcel 已提交
7
重要的一点是,这些实现是可互换的 – 根据任务可以选择一种实现而不会干扰应用工作流程。
W
wizardforcel 已提交
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

```java
Table of Contents
Introduction
Design Participants
Problem Statement
Solution with strategy design pattern
Code Implementation
Demo
Popular Implementations
Summary

```

## 介绍

策略模式涉及从其宿主类中删除算法并将其放在单独的类中,以便在同一编程上下文中可能存在不同的算法(即策略),可以在运行时选择它们。

**策略模式**使客户端代码可以从一系列相关但不同的算法中进行选择,并提供了一种简单的方法来根据客户端上下文在运行时选择任何算法。

W
wizardforcel 已提交
28
#### 由开/关原则驱动
W
wizardforcel 已提交
29

W
wizardforcel 已提交
30
该模式基于**开闭原则**。 我们不需要修改上下文(已关闭以进行修改),但是可以选择并添加任何实现(可扩展用于开放)。
W
wizardforcel 已提交
31

W
wizardforcel 已提交
32
例如,在`Collections.sort()`中 - 我们无需更改排序方法即可获得不同的排序结果。 我们可以在运行时提供不同的比较器。
W
wizardforcel 已提交
33 34 35

> 阅读更多:[比较器示例](//howtodoinjava.com/java/collections/when-to-use-comparable-and-comparator-interfaces-in-java/)

W
wizardforcel 已提交
36
## 设计参与者
W
wizardforcel 已提交
37 38 39 40 41 42 43

在策略模式中,我们首先创建算法的[抽象](//howtodoinjava.com/object-oriented/understanding-abstraction-in-java/)。 这是具有抽象操作的接口。 然后,我们创建此抽象的实现,这些实现称为策略。

客户端将始终调用抽象,并将传递上下文对象。 该上下文对象将决定使用哪种策略。

![Strategy Pattern Participants](img/559686d16d6dbc6618d63c7b59ed1a29.png)

W
wizardforcel 已提交
44
策略模式参与者
W
wizardforcel 已提交
45 46 47 48 49 50 51



## 问题陈述

让我们解决一个设计问题,以更详细地了解策略模式。

W
wizardforcel 已提交
52
我想设计一个社交媒体应用,使我可以在四个社交平台(例如,Facebook,Google Plus,Twitter 和 Orkut)上与朋友联系。 现在,我希望该客户端能够告诉朋友的名称和所需的平台 - 然后我的应用应该透明地连接到他。
W
wizardforcel 已提交
53

W
wizardforcel 已提交
54
更重要的是,如果我想在应用中添加更多社交平台,则应用代码应在不破坏设计的情况下容纳它。
W
wizardforcel 已提交
55 56 57 58 59

## 具有策略设计模式的解决方案

在上述问题中,我们有一个可以以多种方式(连接到朋友)完成的操作,用户可以在运行时选择所需的方式。 因此,它非常适合用于策略设计模式。

W
wizardforcel 已提交
60
为了实现该解决方案,让我们一次设计一个参与者。
W
wizardforcel 已提交
61

W
wizardforcel 已提交
62 63
*   **`ISocialMediaStrategy`** - 抽象操作的接口。
*   **`SocialMediaContext`** – 确定实现的上下文。
W
wizardforcel 已提交
64 65 66 67 68 69
*   **实现**`ISocialMediaStrategy`的各种实现。 例如。 `FacebookStrategy``GooglePlusStrategy``TwitterStrategy``OrkutStrategy`

#### 类图

![Strategy Pattern Class Diagram](img/4d3a49aeafdc07ea92082ed8f8e401a2.png)

W
wizardforcel 已提交
70
策略模式类图
W
wizardforcel 已提交
71 72 73



W
wizardforcel 已提交
74
## 代码实现
W
wizardforcel 已提交
75 76 77

现在,让我们在设计参与者之上进行编码。

W
wizardforcel 已提交
78
**`ISocialMediaStrategy.java`**
W
wizardforcel 已提交
79 80 81 82 83 84 85 86 87 88 89

```java
package com.howtodoinjava.designpattern.strategy;

public interface ISocialMediaStrategy 
{
	public void connectTo(String friendName);
}

```

W
wizardforcel 已提交
90
**`SocialMediaContext.java`**
W
wizardforcel 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

```java
package com.howtodoinjava.designpattern.strategy;

public class SocialMediaContext 
{
	ISocialMediaStrategy smStrategy;

	public void setSocialmediaStrategy(ISocialMediaStrategy smStrategy) 
	{
		this.smStrategy = smStrategy;
	}

	public void connect(String name) 
	{
		smStrategy.connectTo(name);
	}
}

```

W
wizardforcel 已提交
112
**`FacebookStrategy.java`**
W
wizardforcel 已提交
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128

```java
package com.howtodoinjava.designpattern.strategy.impl;

import com.howtodoinjava.designpattern.strategy.ISocialMediaStrategy;

public class FacebookStrategy implements ISocialMediaStrategy {

	public void connectTo(String friendName) 
	{
		System.out.println("Connecting with " + friendName + " through Facebook");
	}
}

```

W
wizardforcel 已提交
129
**`GooglePlusStrategy.java`**
W
wizardforcel 已提交
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145

```java
package com.howtodoinjava.designpattern.strategy.impl;

import com.howtodoinjava.designpattern.strategy.ISocialMediaStrategy;

public class GooglePlusStrategy implements ISocialMediaStrategy {

	public void connectTo(String friendName) 
	{
		System.out.println("Connecting with " + friendName + " through GooglePlus");
	}
}

```

W
wizardforcel 已提交
146
**`TwitterStrategy.java`**
W
wizardforcel 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

```java
package com.howtodoinjava.designpattern.strategy.impl;

import com.howtodoinjava.designpattern.strategy.ISocialMediaStrategy;

public class TwitterStrategy implements ISocialMediaStrategy {

	public void connectTo(String friendName) 
	{
		System.out.println("Connecting with " + friendName + " through Twitter");
	}
}

```

W
wizardforcel 已提交
163
**`OrkutStrategy.java`**
W
wizardforcel 已提交
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179

```java
package com.howtodoinjava.designpattern.strategy.impl;

import com.howtodoinjava.designpattern.strategy.ISocialMediaStrategy;

public class OrkutStrategy implements ISocialMediaStrategy {

	public void connectTo(String friendName) 
	{
		System.out.println("Connecting with " + friendName + " through Orkut [not possible though :)]");
	}
}

```

W
wizardforcel 已提交
180
## 演示
W
wizardforcel 已提交
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240

现在看看如何在运行时中使用这些策略。

```java
package com.howtodoinjava.designpattern.strategy.demo;

import com.howtodoinjava.designpattern.strategy.SocialMediaContext;
import com.howtodoinjava.designpattern.strategy.impl.FacebookStrategy;
import com.howtodoinjava.designpattern.strategy.impl.GooglePlusStrategy;
import com.howtodoinjava.designpattern.strategy.impl.OrkutStrategy;
import com.howtodoinjava.designpattern.strategy.impl.TwitterStrategy;

public class Demo {
	public static void main(String[] args) {

		// Creating social Media Connect Object for connecting with friend by
		// any social media strategy.
		SocialMediaContext context = new SocialMediaContext();

		// Setting Facebook strategy.
		context.setSocialmediaStrategy(new FacebookStrategy());
		context.connect("Lokesh");

		System.out.println("====================");

		// Setting Twitter strategy.
		context.setSocialmediaStrategy(new TwitterStrategy());
		context.connect("Lokesh");

		System.out.println("====================");

		// Setting GooglePlus strategy.
		context.setSocialmediaStrategy(new GooglePlusStrategy());
		context.connect("Lokesh");

		System.out.println("====================");

		// Setting Orkut strategy.
		context.setSocialmediaStrategy(new OrkutStrategy());
		context.connect("Lokesh");
	}
}

```

输出:

```java
Connecting with Lokesh through Facebook
====================
Connecting with Lokesh through Twitter
====================
Connecting with Lokesh through GooglePlus
====================
Connecting with Lokesh through Orkut [not possible though :)]
```

## 热门实现

1.  Java `Collections.sort(list, comparator)`方法,客户端根据运行时的要求实际将适当的比较器传递给该方法,并且该方法通用以接受任何比较器类型。 根据传递的比较器,可以对同一集合进行不同的排序。
W
wizardforcel 已提交
241
2.  [Log4j](//howtodoinjava.com/log4j2/) 中的附加器,布局和过滤器。
W
wizardforcel 已提交
242 243
3.  UI 工具箱中的布局管理器。

W
wizardforcel 已提交
244
## 总结
W
wizardforcel 已提交
245 246 247

*   此模式定义了一组相关算法,并将它们封装在单独的类中,并允许客户端在运行时选择任何算法。
*   它允许添加新算法而无需修改使用算法或策略的现有算法或上下文类
W
wizardforcel 已提交
248
*   策略是“GOF”列表中的一种行为型模式。
W
wizardforcel 已提交
249
*   策略模式基于 SOLID 主体的开放式封闭设计原则。
W
wizardforcel 已提交
250
*   `Collections.sort()``Comparator`接口的组合是策略模式的可靠示例。
W
wizardforcel 已提交
251 252 253

这就是有关策略设计模式的全部内容。 将我的问题放在评论部分。

W
wizardforcel 已提交
254
[下载源码](//howtodoinjava.com/wp-content/downloads/strategyDesignPattern.zip)
W
wizardforcel 已提交
255 256

学习愉快!