## 问题 Problem
你很多方法用来解决某个问题,但是需要在运行时选择或者切换这些方法。
You have more than one way to solve a problem but you need to choose (or even switch) between these methods at run time.
## 方法 Solution
将你的算法分装到策略对象中。
Encapsulate your algorithms inside of Strategy objects.
例如,给定一个无序列表,我们可以在不同的情景中选择不同的算法。
Given an unsorted list, for example, we can change the sorting algorithm under different circumstances.
### 基类 The base class:
~~~
class StringSorter
constructor:(@algorithm)->
sort: (list) -> @algorithm list
~~~
### 策略 The strategies:
~~~
bubbleSort = (list) ->
anySwaps = false
swapPass = ->
for r in [0..list.length-2]
if list[r] > list[r+1]
anySwaps = true
[list[r], list[r+1]] = [list[r+1], list[r]]
swapPass()
while anySwaps
anySwaps = false
swapPass()
list
reverseBubbleSort = (list) ->
anySwaps = false
swapPass = ->
for r in [list.length-1..1]
if list[r] < list[r-1]
anySwaps = true
[list[r], list[r-1]] = [list[r-1], list[r]]
swapPass()
while anySwaps
anySwaps = false
swapPass()
list
~~~
### 使用策略 Using the strategies:
~~~
sorter = new StringSorter bubbleSort
unsortedList = ['e', 'b', 'd', 'c', 'x', 'a']
sorter.sort unsortedList
# => ['a', 'b', 'c', 'd', 'e', 'x']
unsortedList.push 'w'
# => ['a', 'b', 'c', 'd', 'e', 'x', 'w']
sorter.algorithm = reverseBubbleSort
sorter.sort unsortedList
# => ['a', 'b', 'c', 'd', 'e', 'w', 'x']
~~~
## 讨论 Discussion
“遇到敌人后一切战斗计划都失效了”,用户也同样,但是我们可以使用已掌握的知识来适应环境。例如,在上面的例子中,新加项打乱了兴趣。了解细节,针对确切的场景,我们可以通过切换算法来加快排序,仅仅只需一次简单的再赋值即可。
“No plan survives first contact with the enemy”, nor users, but we can use the knowledge gained from changing circumstances to adapt. Near the end of the example, for instance, the newest item in the array now lies out of order. Knowing that detail, we can then speed the sort up by switching to an algorithm optimized for that exact scenario with nothing but a simple reassignment.
### 练习 Exercises
* 把`StringSorter`扩展成一个`AlwaysSortedArray`类,实现原生数组的所有功能,而且有通过插入方法新项时能够自动地排序(例如,`push`和`shift`)。
* Expand `StringSorter` into an `AlwaysSortedArray` class that implements all of the functionality of a regular array but which automatically sorts new items based on the method of insertion (e.g. `push` vs. `shift`).
- 贡献
- 作者
- 授权协议
- 1、Syntax
- 在服务端和客户端重用代码
- For循环
- 嵌入JavaScript代码
- 值域
- 2、Classes and Objects
- 类方法和实例方法
- CoffeeScript式的Type函数
- 链式调用
- 克隆对象(深度克隆)
- 不存在就赋值为对象字面量
- 类变量
- 3、Strings
- 分割字符串
- 字符串匹配
- 查找子字符串
- 让整个字符串小写
- 大写整个字符
- 去掉字符串首尾的空白
- 生成唯一的ID
- 首字母大写
- 重复字符串
- 字符串插值
- 4、Arrays
- Python式的Zip函数 Python-like Zip Function
- 数组去重 Removing Duplicate Elements from Arrays
- 基于数组构建字典对象 Creating a dictionary Object from an Array
- 数组转成字符串 Creating a String from an Array
- 检查每一个元素 Testing Every Element
- 数组最大值
- 过滤数组 Filtering Arrays
- 定义区间数组 Define Ranges Array
- 转置数组 Reversing Arrays
- 化简数组 Reducing Arrays
- 使用数组来做值交换 Using Arrays to Swap Variables
- 列表解析 List Comprehensions
- 检查值的类型是否是数组
- 连接数组
- 搅乱数组中的元素 Shuffling Array Elements
- 数组映射 Mapping Arrays
- 5、Dates and Times
- Calculate Phase of the Moon for a Date
- 找出某月的最后一天是几号 Finding the Last Day of the Month
- 获取两个日期相差的天数 Get Days Between Two Dates
- 计算复活节岛日期 Calculate the Date of Easter Sunday
- 计算感恩节的日期(美国和加拿大) Calculate the Date of Thanksgiving (USA and Canada)
- 计算上一个(下一个)月份 Finding Last (or Next) Month
- 6、Math
- 快速逆平方根
- 一个随机整数的函数
- 更快的斐波那契算法
- 生成可预测的随机数
- 弧度与度转换
- 生成随机数
- 数学常数
- 7、Functions
- 反抖动函数 Debounce Functions
- 参数数组化 Splat Arguments
- 当函数调用的括号不可以省略时 When Function Parentheses Are Not Optional
- 递归函数 Recursive Functions
- 8、Metaprogramming
- 扩展内置对象 Extending Built-in Objects
- 检测并创建缺失的函数 Detecting and Creating Missing Functions
- 9、jQuery
- 回调绑定
- 创建jQuery插件
- AJAX
- 10、Ajax
- 不依赖jQuery的Ajax请求 Ajax Request Without jQuery
- 11、Regular Expressions
- 替换子字符串 Replacing Substrings
- 使用定点 Using Heregexes
- 使用HTML字符实体替换HTML标签 Replacing HTML Tags with HTML Named Entities
- 搜索子字符串 Searching for Substrings
- 12、Networking
- 简单的服务器
- 双向客户端
- 最简单的HTTP客户端
- 最简单的HTTP服务器
- 简单的客户端
- 双向服务端 Bi-Directional Server
- 13、Design Patterns
- 命令模式
- 单例模式
- 策略模式 Strategy Pattern
- 建造者模式 Builder Pattern
- 备忘录模式 Memento Pattern
- 解释器模式 Interpreter Pattern
- 装饰者模式
- 桥接模式
- 工厂方法模式
- 14、Databases
- MongoDB
- SQLite
- 15、Testing
- 使用Jasmine测试