Стратегия (шаблон проектирования): различия между версиями

[непроверенная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
→‎Использование: викификация
м →‎Примеры: Ruby отступы, удаление XML-комментариев C#, чистка
Строка 245:
namespace DesignPatterns.Behavioral.Strategy
{
// Класс реализующий конкретную стратегию, должен наследовать этот интерфейс
/// <summary>
// Класс контекста использует этот интерфейс для вызова конкретной стратегии
/// Интерфейс «Стратегия» определяет функциональность (в данном примере это метод
/// Algorithm), которая должна быть реализована
/// конкретными классами стратегий. Другими словами, метод интерфейса определяет
/// решение некой задачи, а его реализации в конкретных классах стратегий определяют,
/// КАК, КАКИМ ПУТЁМ эта задача будет решена.
/// </summary>
public interface IStrategy
{
Строка 257 ⟶ 252 :
}
 
// Первая конкретная реализация-стратегия.
/// <summary>
/// Первая конкретная реализация-стратегия.
/// </summary>
public class ConcreteStrategy1 : IStrategy
{
Строка 268 ⟶ 261 :
}
 
// Вторая конкретная реализация-стратегия.
/// <summary>
// Реализаций может быть сколько угодно много.
/// Вторая конкретная реализация-стратегия.
/// Реализаций может быть сколько угодно много.
/// </summary>
public class ConcreteStrategy2 : IStrategy
{
Строка 280 ⟶ 271 :
}
 
// Контекст, использующий стратегию для решения своей задачи.
/// <summary>
/// Контекст, использующий стратегию для решения своей задачи.
/// </summary>
public class Context
{
// Ссылка на интерфейс IStrategy
/// <summary>
// позволяет автоматически переключаться между конкретными реализациями
/// Ссылка на интерфейс <see cref="IStrategy">IStrategy</see>
// (другими словами, это выбор конкретной стратегии).
/// позволяет автоматически переключаться между конкретными реализациями
/// (другими словами, это выбор конкретной стратегии).
/// </summary>
private IStrategy _strategy;
 
/// <summary>Конструктор контекста.
// Инициализирует объект стратегией.
/// Конструктор контекста.
/// Инициализирует объект стратегией.
/// </summary>
/// <param name="strategy">
/// Стратегия.
/// </param>
public Context(IStrategy strategy)
{
Строка 304 ⟶ 286 :
}
 
// Метод для установки стратегии.
/// <summary>
/// МетодСлужит для установкисмены стратегии во время выполнения.
// В C# может быть реализован также как свойство записи.
/// Служит для смены стратегии во время выполнения.
/// В C# может быть реализован также как свойство записи.
/// </summary>
/// <param name="strategy">
/// Новая стратегия.
/// </param>
public void SetStrategy(IStrategy strategy)
{
Строка 317 ⟶ 294 :
}
 
// Некоторая функциональность контекста, которая выбирает
/// <summary>
//стратегию и использует её для решения своей задачи.
/// Некоторая функциональность контекста, которая выбирает
/// стратегию и использует её для решения своей задачи.
/// </summary>
public void ExecuteOperation()
{
Строка 327 ⟶ 302 :
}
 
// Класс приложения.
/// <summary>
// В данном примере выступает как клиент контекста.
/// Класс приложения.
/// В данном примере выступает как клиент контекста.
/// </summary>
public static class Program
{
/// <summary>
/// Точка входа в программу.
/// </summary>
public static void Main()
{
Строка 558 ⟶ 531 :
}}
 
'''Примеры на [[PHP]]'''
'''Пример с использованием динамических (first-class) функций'''
{{Hider|
title = '''Пример реализации''' |
content-style = text-align: left; |
hidden = true |
content =
<source lang="javascript">
function Context(fn) {
this.exec = function() {
fn.apply(this, arguments || []);
};
};
 
var showInWindowStatus = new Context( function(message) {
window.status = message;
} );
var showInNewWindow = new Context( function(message) {
var win = window.open("", "_blank");
win.document.write("<html>"+ message +"</html>");
} );
var showInAlert = new Context( function(message) {
alert(message);
} );
 
showInWindowStatus.exec("сообщение");
showInNewWindow.exec("сообщение");
showInAlert.exec("сообщение");
</source>
}}
 
'''Примеры на [[PHP5]]'''
{{Hider|
title = '''Пример реализации''' |
Строка 700 ⟶ 643 :
sasha.write(u'Нет, уж лучше я напишу конспект')
# Саша (ручкой) Нет, уж лучше я напишу конспект
</source>
}}
 
'''Пример на [[VB.NET]]'''
{{Hider|
title = '''Пример реализации''' |
content-style = text-align: left; |
hidden = true |
content =
<source lang="vbnet">
Namespace DesignPatterns.Behavioral.Strategy
''' <summary>
''' Интерфейс «Стратегия» определяет функциональность (в данном примере это метод
''' <see cref="Algorithm">Algorithm</see>), которая должна быть реализована
''' конкретными классами стратегий. Другими словами, метод интерфейса определяет
''' решение некой задачи, а его реализации в конкретных классах стратегий определяют,
''' КАК, КАКИМ ПУТЁМ эта задача будет решена.
''' </summary>
Public Interface IStrategy
Sub Algorithm()
End Interface
 
''' <summary>
''' Первая конкретная реализация-стратегия.
''' </summary>
Public Class ConcreteStrategy1
Implements IStrategy
 
Public Sub Algorithm() Implements IStrategy.Algorithm
Console.WriteLine("Выполняется алгоритм стратегии 1.")
End Sub
End Class
 
''' <summary>
''' Вторая конкретная реализация-стратегия.
''' Реализаций может быть сколько угодно много.
''' </summary>
Public Class ConcreteStrategy2
Implements IStrategy
 
Public Sub Algorithm() Implements IStrategy.Algorithm
Console.WriteLine("Выполняется алгоритм стратегии 2.")
End Sub
End Class
 
''' <summary>
''' Контекст, использующий стратегию для решения своей задачи.
''' </summary>
Public Class Context
''' <summary>
''' Ссылка на интерфейс <see cref="IStrategy">IStrategy</see>
''' позволяет автоматически переключаться между конкретными реализациями
''' (другими словами, это выбор конкретной стратегии).
''' </summary>
Private _strategy As IStrategy
 
''' <summary>
''' Конструктор контекста.
''' Инициализирует объект стратегией.
''' </summary>
''' <param name="strategy">
''' Стратегия.
''' </param>
Public Sub New(ByVal strategy As IStrategy)
_strategy = strategy
End Sub
 
''' <summary>
''' Метод для установки стратегии.
''' Служит для смены стратегии во время выполнения.
''' В C# может быть реализован также как свойство записи.
''' </summary>
''' <param name="strategy">
''' Новая стратегия.
''' </param>
Public Sub SetStrategy(ByVal strategy As IStrategy)
_strategy = strategy
End Sub
 
''' <summary>
''' Некоторая функциональность контекста, которая выбирает
''' стратегию и использует её для решения своей задачи.
''' </summary>
Public Sub ExecuteOperation()
_strategy.Algorithm()
End Sub
End Class
 
''' <summary>
''' Класс приложения.
''' В данном примере выступает как клиент контекста.
''' </summary>
Public NotInheritable Class Program
 
Private Sub New()
End Sub
 
''' <summary>
''' Точка входа в программу.
''' </summary>
Shared Sub Main()
' Создём контекст и инициализируем его первой стратегией.
Dim context As New Context(New ConcreteStrategy1())
' Выполняем операцию контекста, которая использует первую стратегию.
context.ExecuteOperation()
' Заменяем в контексте первую стратегию второй.
context.SetStrategy(New ConcreteStrategy2())
' Выполняем операцию контекста, которая теперь использует вторую стратегию.
context.ExecuteOperation()
 
Console.Read()
End Sub
 
End Class
End Namespace
</source>
}}
 
'''Пример на [[ActionScript]]'''
{{Hider|
title = '''Пример реализации''' |
content-style = text-align: left; |
hidden = true |
content =
<source lang="actionscript">
package patterns.strategy
{
public interface IAlgorithm
{
function get length () : int
 
function apply (scope:Object = null, args:Array = null):*
}
}
package patterns.strategy
{
public class Strategy
{
protected var _protect:Boolean;
protected var _isFunctionStrategy:Boolean;
protected var _numberOfArguments:int;
protected var _algorithm:Object;
protected var _key:String;
public function Strategy(key:String, algorithm:Object, protect:Boolean = false)
{
_protect = protect;
_key = key;
_algorithm = algorithm;
init();
}
protected function init():void
{
_isFunctionStrategy = _algorithm is Function;
_numberOfArguments = _algorithm.length
}
public function execute(args:Array = null):*
{
return _algorithm.apply(this, args);
}
public function get isFunctionStrategy():Boolean
{
return _isFunctionStrategy;
}
public function get numberOfArguments():int
{
return _numberOfArguments;
}
public function get key():String
{
return _key;
}
public function get protect():Boolean
{
return _protect;
}
}
 
}
package patterns.strategy
{
public class SimpleAlgorithm extends Object implements IAlgorithm
{
private var _executeMethod:Function;
public function SimpleAlgorithm()
{
super();
if (!this.hasOwnProperty('execute'))
throw(new Error('strategy algorithm or child must have public field "execute"'));
}
public function apply(scope:Object = null, args:Array = null):*
{
return this['execute'].apply(scope, args);
}
public function get length():int
{
return this['execute'].length;
}
}
 
}
package patterns.strategy
{
public class StrategyController
{
protected var strategies:/*Strategy*/Object;
public function StrategyController()
{
init();
}
private function init():void
{
strategies = { };
}
public function addStrategy(strategy:Strategy):void
{
var key:String = strategy.key;
var isProtected:Boolean = false;
if (hasStrategy(key))
isProtected = strategies[key].protect;
if (!isProtected)
{
strategies[key] = strategy;
}
else
{
throw(new Error('try to override protected strategy'));
}
}
public function removeStrategy(key:String):void
{
strategies[key] = null;
}
public function hasStrategy(key:String):Boolean
{
return strategies.hasOwnProperty(key);
}
public function crateNewStrategy(key:String, algorithm:*, protect:Boolean = false):void
{
addStrategy(new Strategy(key, algorithm, protect));
}
public function execute(key:String, ...args:Array):*
{
if(hasStrategy(key))
return strategies[key].execute.apply(null, args || null);
else
return null;
}
}
}
package patterns.strategy
{
public class SomeALG extends SimpleAlgorithm
{
public function SomeALG()
{
super();
}
public function execute(a1:int, a2:int, a3:int):*
{
return math(a1, a2, a3);
}
private function math(a1:int, a2:int, a3:int):int
{
return a1 + a2 + a3;
}
}
 
}
</source>
}}
Строка 1020 ⟶ 656 :
 
Strategy = interface {
required_methods :use
}
 
class StrategyOne
def use
puts "Strategy one"
end
implements Strategy
end
 
class StrategyTwo
def use
puts "Strategy two"
end
implements Strategy
end
 
class StrategyThree
def use
puts "Strategy three"
end
implements Strategy
end
 
class Context
attr_accessor :strategy
def initialize strategy
@strategy = strategy
end
def useStrategy
strategy.use
end
end