يعتبر **نموذج الإستراتيجية (نمط الاستراتيجية) (بالإنجليزية: Strategy Pattern)‏** أو **(خطة العمل) (The policy pattern)** واحداً من أنماط تصميم البرمجيات التصرفية (السلوكية) في مجال هندسة البرمجيات التي وضعها جماعة الأربعة في كتابهم المعروف (نماذج التصميم). يستعمل هذا النموذج (النمط) بالتحديد كي يتم اختيار الخوارزمية المناسبة أثناء تشغيل البرنامج (بالإنجليزية: runtime )‏. بدلا من تنفيذ خوارزمية واحدة مباشرة، الكود يستقبل التعليمات اثناء التشغيل (بالإنجليزية: run-time)‏ ليحدد الخوارزمية المناسبة لاستخدامها. بعبارة أخرى، فإن هذا النموذج يعرّف عددا من الخوارزميات ويجعلهم مغلفين (بالإنجليزية: encapsulated)‏ بحيث يمكن أن تحل إحداها محل الأخرى.

على سبيل المثال، يمكن تطبيق نموذج الإستراتيجية في حالة صنف (Class) يقوم بعملية التحقق من صحة البيانات المدخلة (بالإنجليزية: validation )‏. حيث يمكن أن يكتب البرنامج بطريقة تجعله يختار الخوارزمية المناسبة تلقائيا بناءً على نوع البيانات المدخلة أو على مصدر هذه البيانات أو على أي عامل آخر. ما يهم هنا هو أن هذا العامل لا تتم معرفته، وبالتالي تحديد الخوارزمية، إلا أثناء تشغيل البرنامج.
يمكن استخدام خوارزميات التحقق (الاستراتيجيات)، المغلفة (بالإنجليزية: encapsulated)‏ بشكل منفصل عن كائن التحقق (بالإنجليزية: validating object)‏ ، من قبل كائنات التحقق الأخرى في مجالات مختلفة من النظام (أو حتى أنظمة مختلفة) دون تكرار الكود البرمجي (بالإنجليزية: code duplication)‏.
عادة يقوم نمط الإستراتيجية بتخزين عنوان مرجعي (بالإنجليزية: reference)‏ لبعض الكود في بنية بيانات (بالإنجليزية: data structure)‏ ويستردها (بالإنجليزية: retrieves )‏. يمكن تحقيق ذلك من خلال آليات مثل مؤشر الدالة الأصلية (بالإنجليزية: native function pointer)‏ ، أو دالة من الصنف الأول (بالإنجليزية: first-class function)‏ ، أو الاصناف أو مثيلات الصنف (بالإنجليزية: class instances)‏ في لغات البرمجة الكائنية (بالإنجليزية: object-oriented)‏ ، أو الوصول (بالإنجليزية: accessing )‏إلى التخزين الداخلي (بالإنجليزية: internal storage)‏ لتطبيق اللغة (بالإنجليزية: the language implementation)‏ الخاص بالكود عبر الانعكاس (بالإنجليزية: reflection)‏.

هيكل
----

### مخطط الصنف في لغة النمذجة الموحدة (UML) ومخطط التتابع

A sample UML class and sequence diagram for the Strategy design pattern.
.في مخطط الصنف UML (بالإنجليزية: UML class diagram)‏ أعلاه، لا يطبق صنف السياق (بالإنجليزية: Context class)‏ خوارزمية مباشرة. بدلاً من ذلك، يشير السياقContext إلى واجهة الإستراتيجية Strategy interface لتنفيذ خوارزمية (()Strategy.algorithm)، مما يجعل السياقContext مستقلاً عن كيفية تطبيق (بالإنجليزية: implemented)‏ الخوارزمية. صنفا الإستراتيجية Strategy1 (بالإنجليزية:  Strategy1)‏ والاستراتيجية 2 (بالإنجليزية:  Strategy2)‏ ينفذا (بالإنجليزية: implement)‏ واجهة الإستراتيجية (بالإنجليزية:  Strategy interface)‏، أي تنفيذ (تغليف) (بالإنجليزية:  implement (encapsulate))‏ خوارزمية.
يعرض مخطط التتابع UML (بالإنجليزية: UML sequence diagram)‏ تفاعلات وقت التشغيل (بالإنجليزية:  run-time interactions)‏ : يقوم كائن السياق (بالإنجليزية: Context object)‏ بتفويض (بالإنجليزية: delegates)‏ خوارزمية لكائنات إستراتيجية (بالإنجليزية: Strategy objects)‏ مختلفة. أولاً، يستدعيContext السياق خوارزمية ()algorithm على كائن Strategy1 ، الذي ينفذ الخوارزمية ويعيدreturns النتيجة إلى السياقContext. بعد ذلك، يغير السياقContext استراتيجيته ويستدعي ()algorithm على كائن Strategy2 ، الذي ينفذ الخوارزمية ويعيد (بالإنجليزية: returns)‏ النتيجة إلى السياق(بالإنجليزية: Context)‏.

### مخطط الفئة

Strategy Pattern in UML 
Strategy pattern in LePUS3
(legend)

مثال
----

### #C

المثال التالي بلغة برمجة سي شارب (بالإنجليزية: #C)‏:

```
public class StrategyPatternWiki
{
 public static void Main(String[] args)
 {
 // Prepare strategies
 var normalStrategy = new NormalStrategy();
 var happyHourStrategy = new HappyHourStrategy();

 var firstCustomer = new Customer(normalStrategy);

 // Normal billing
 firstCustomer.Add(1.0, 1);

 // Start Happy Hour
 firstCustomer.Strategy = happyHourStrategy;
 firstCustomer.Add(1.0, 2);

 // New Customer
 Customer secondCustomer = new Customer(happyHourStrategy);
 secondCustomer.Add(0.8, 1);
 // The Customer pays
 firstCustomer.PrintBill();

 // End Happy Hour
 secondCustomer.Strategy = normalStrategy;
 secondCustomer.Add(1.3, 2);
 secondCustomer.Add(2.5, 1);
 secondCustomer.PrintBill();
 }
}

class Customer
{
 private IList<double> drinks;

 // Get/Set Strategy
 public IBillingStrategy Strategy { get; set; }

 public Customer(IBillingStrategy strategy)
 {
 this.drinks = new List<double>();
 this.Strategy = strategy;
 }

 public void Add(double price, int quantity)
 {
 this.drinks.Add(this.Strategy.GetActPrice(price \* quantity));
 }

 // Payment of bill
 public void PrintBill()
 {
 double sum = 0;
 foreach (var drinkCost in this.drinks)
 {
 sum += drinkCost;
 }
 Console.WriteLine($"Total due: {sum}.");
 this.drinks.Clear();
 }
}

interface IBillingStrategy
{
 double GetActPrice(double rawPrice);
}

// Normal billing strategy (unchanged price)
class NormalStrategy : IBillingStrategy
{
 public double GetActPrice(double rawPrice) => rawPrice;
}

// Strategy for Happy hour (50% discount)
class HappyHourStrategy : IBillingStrategy
{
 public double GetActPrice(double rawPrice) => rawPrice \* 0.5;
}

```

### جافا Java

مثال بلغة برمجة جافا Java

مخطط الصنف UML للمثال

```
import java.util.ArrayList;

interface BillingStrategy {
 // Use a price in cents to avoid floating point round-off error
 int getActPrice(int rawPrice);
 
 // Normal billing strategy (unchanged price)
 static BillingStrategy normalStrategy() {
 return rawPrice -> rawPrice;
 }
 
 // Strategy for Happy hour (50% discount)
 static BillingStrategy happyHourStrategy() {
 return rawPrice -> rawPrice / 2;
 }
}

class Customer {
 private final List<Integer> drinks = new ArrayList<>();
 private BillingStrategy strategy;

 public Customer(BillingStrategy strategy) {
 this.strategy = strategy;
 }

 public void add(int price, int quantity) {
 this.drinks.add(this.strategy.getActPrice(price\*quantity));
 }

 // Payment of bill
 public void printBill() {
 int sum = this.drinks.stream().mapToInt(v -> v).sum();
 System.out.println("Total due: "+ sum);
 this.drinks.clear();
 }

 // Set Strategy
 public void setStrategy(BillingStrategy strategy) {
 this.strategy = strategy;
 }
}

public class StrategyPattern {
 public static void main(String[] arguments) {
 // Prepare strategies
 BillingStrategy normalStrategy = BillingStrategy.normalStrategy();
 BillingStrategy happyHourStrategy = BillingStrategy.happyHourStrategy();

 Customer firstCustomer = new Customer(normalStrategy);

 // Normal billing
 firstCustomer.add(100, 1);

 // Start Happy Hour
 firstCustomer.setStrategy(happyHourStrategy);
 firstCustomer.add(100, 2);

 // New Customer
 Customer secondCustomer = new Customer(happyHourStrategy);
 secondCustomer.add(80, 1);
 // The Customer pays
 firstCustomer.printBill();

 // End Happy Hour
 secondCustomer.setStrategy(normalStrategy);
 secondCustomer.add(130, 2);
 secondCustomer.add(250, 1);
 secondCustomer.printBill();
 }
}

```

إستراتيجية ومبدأ مفتوح/مغلق
---------------------------

إستراتيجية ومبدأ مفتوح مغلق (بالإنجليزية: Strategy and open/closed principle)‏ وفقًا لنمط الإستراتيجية، لا ينبغي أن تُتوارث (بالإنجليزية: inherited )‏ سلوكيات الصنف (بالإنجليزية: the behaviors of a class)‏. بدلاً من ذلك، يجب تغليفها (بالإنجليزية:  encapsulated)‏ باستخدام الواجهات (بالإنجليزية: interfaces)‏. هذا متوافق مع مبدأ مفتوح / مغلق (بالإنجليزية: OCP)‏، الذي يقترح أن الأصناف (بالإنجليزية: classes)‏ يجب أن تكون مفتوحة للتمديد (بالإنجليزية: open for extension)‏ ولكن مغلقة للتعديل (بالإنجليزية: closed for modification)‏.

كمثال، ضع في اعتبارك صنف السيارة(بالإنجليزية: car class)‏. وظيفتان محتملتان للسيارة (بالإنجليزية: functionalities )‏ هما الفرملة (بالإنجليزية: *brake*)‏ والتسارع (بالإنجليزية: *accelerate*)‏. نظرًا لأن سلوكيات التسارع (بالإنجليزية: accelerate )‏ والفرملة (بالإنجليزية: brake )‏ تتغير بشكل متكرر (بالإنجليزية: frequently)‏ بين النماذج (بالإنجليزية: models)‏، فإن النهج المشترك (بالإنجليزية: common approach)‏ هو تنفيذ (بالإنجليزية: implement )‏ هذه السلوكيات (بالإنجليزية: behaviors )‏ في الأصنف الفرعية (بالإنجليزية: subclasses)‏. هذا النهج (بالإنجليزية: approach )‏ له عيوب كبيرة (بالإنجليزية: significant drawbacks)‏: يجب الإعلان (بالإنجليزية: declared )‏ عن سلوكيات التسارع (بالإنجليزية: accelerate )‏والفرامل (بالإنجليزية: brake)‏ في كل طراز سيارة جديد (بالإنجليزية: new Car model)‏. يزداد عمل إدارة (بالإنجليزية: work of managing)‏ هذه السلوكيات (بالإنجليزية: behaviors )‏ بشكل كبير مع زيادة عدد النماذج (بالإنجليزية: as the number of models increases)‏ ، ويتطلب تكرار الكود (بالإنجليزية: duplicated )‏عبر النماذج (بالإنجليزية: models)‏. بالإضافة إلى ذلك، ليس من السهل تحديد الطبيعة الدقيقة (بالإنجليزية:  exact nature)‏ للسلوك (بالإنجليزية: behavior )‏ لكل نموذج (بالإنجليزية: model )‏ دون التحقق من الكود في كل نموذج.

يستخدم نمط الاستراتيجية (بالإنجليزية: strategy pattern)‏ التركيب بدلاً من الوراثة (بالإنجليزية: composition over inheritance)‏. في نمط الاستراتيجية، يتم تعريف السلوكيات (بالإنجليزية: behaviors are defined)‏ على أنها واجهات منفصلة (بالإنجليزية: interfaces )‏ وأصناف محددة (بالإنجليزية: specific classes)‏ تنفذ (بالإنجليزية: implement )‏هذه الواجهات (بالإنجليزية: interfaces)‏. هذا يسمح بفصل (بالإنجليزية: better decoupling)‏ أفضل بين السلوك (بالإنجليزية: behavior )‏ والصنف (بالإنجليزية: class )‏ الذي يستخدم السلوك (بالإنجليزية: )‏. يمكن تغيير السلوك (بالإنجليزية: behavior )‏ دون كسر الاصناف (بالإنجليزية: breaking the classes)‏ التي تستخدمه، ويمكن للأصناف (بالإنجليزية: classes )‏ التبديل بين السلوكيات (بالإنجليزية: switch between behaviors)‏ عن طريق تغيير التنفيذ المحدد (بالإنجليزية: by changing the specific implementation)‏ المستخدم دون الحاجة إلى أي تغييرات كبيرة في الكود (بالإنجليزية: Code)‏. يمكن أيضًا تغيير السلوكيات (بالإنجليزية: Behaviors )‏ في وقت التشغيل (بالإنجليزية: run-time)‏ وكذلك في وقت التصميم (بالإنجليزية: design-time)‏. على سبيل المثال، يمكن تغيير سلوك فرامل كائن السيارة (بالإنجليزية: car object's brake behavior)‏ من دالة الفرملة مع ABS (بالإنجليزية: ()BrakeWithABS)‏ إلى دالة الفرملة (بالإنجليزية: ()Brake )‏ عن طريق تغيير عضو سلوك الفرامل brakeBehavior (بالإنجليزية:  by changing the brakeBehavior member )‏ إلى:

```
brakeBehavior = new Brake();

```

### مثال بلغة جافا Java

```
/\* Encapsulated family of Algorithms
 \* Interface and its implementations
 \*/
public interface IBrakeBehavior {
 public void brake();
}

public class BrakeWithABS implements IBrakeBehavior {
 public void brake() {
 System.out.println("Brake with ABS applied");
 }
}

public class Brake implements IBrakeBehavior {
 public void brake() {
 System.out.println("Simple Brake applied");
 }
}

/\* Client that can use the algorithms above interchangeably \*/
public abstract class Car {
 private IBrakeBehavior brakeBehavior;

 public Car(IBrakeBehavior brakeBehavior) {
 this.brakeBehavior = brakeBehavior;
 }

 public void applyBrake() {
 brakeBehavior.brake();
 }

 public void setBrakeBehavior(IBrakeBehavior brakeType) {
 this.brakeBehavior = brakeType;
 }
}

/\* Client 1 uses one algorithm (Brake) in the constructor \*/
public class Sedan extends Car {
 public Sedan() {
 super(new Brake());
 }
}

/\* Client 2 uses another algorithm (BrakeWithABS) in the constructor \*/
public class SUV extends Car {
 public SUV() {
 super(new BrakeWithABS());
 }
}

/\* Using the Car example \*/
public class CarExample {
 public static void main(final String[] arguments) {
 Car sedanCar = new Sedan();
 sedanCar.applyBrake(); // This will invoke class "Brake"

 Car suvCar = new SUV();
 suvCar.applyBrake(); // This will invoke class "BrakeWithABS"

 // set brake behavior dynamically
 suvCar.setBrakeBehavior( new Brake() );
 suvCar.applyBrake(); // This will invoke class "Brake"
 }
}

```

مراجع
-----

1. ↑  "The Strategy design pattern - Structure and Collaboration". *w3sDesign.com*. مؤرشف من الأصل في 2017-08-24. اطلع عليه بتاريخ 2017-08-12.
2. ↑  "The Strategy design pattern - Problem, Solution, and Applicability". *w3sDesign.com*. مؤرشف من الأصل في 2017-08-13. اطلع عليه بتاريخ 2017-08-12.
3. ↑  Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). *Design Patterns: Elements of Reusable Object-Oriented Software*. Addison Wesley. ص. 315ff. ISBN:0-201-63361-2. مؤرشف من الأصل في 2019-12-15.`{{استشهاد بكتاب}}`: صيانة CS1: أسماء متعددة: قائمة المؤلفين (link)
4. ↑  "The Strategy design pattern - Structure and Collaboration". *w3sDesign.com*. مؤرشف من الأصل في 2017-08-24. اطلع عليه بتاريخ 2017-08-12.
5. ↑   نسخة محفوظة 2020-04-14 على موقع واي باك مشين.

|  |  |
| --- | --- |
| مشاريع شقيقة | في كومنز صور وملفات عن: نموذج الإستراتيجية |



| * ع
* ن
* ت
 أنماط تصميم البرمجيات (برمجة) |
| --- |
| إنشائي (Creational) | 
* Abstract factory
* نمط تصميم الباني
* حقن التبعية
* نمط طريقة المصنع
* Lazy initialization
* Multiton
* Object pool
* Prototype
* اكتساب الموارد تهيئة
* النمط المفرد

 |
| هيكلي (Structural) | 
* نمط المحول
* نموذج التصميم جسر
* نموذج التصميم المجمع
* نموذج التصميم ديكور
* Delegation
* نمط واجهة المبنى
* نموذج التصميم وزن الذبابة
* Front controller
* Marker interface
* Module
* نمط الوكيل
* Twin

 |
| سلوكي (Behavioral) | 
* Blackboard
* Chain of responsibility
* Command
* Interpreter
* نمط المكرر
* Mediator
* Memento
* Null object
* المراقب (نموذج تصميم)
* Servant
* Specification
* State
* نموذج الإستراتيجية
* Template method
* Visitor

 |
| وظيفي (Functional) | 
* مونويد
* Functor
* Applicative
* Monad
* Comonad
* Free monad
* HOF
* Currying
* Function composition
* Closure
* المولد

 |
| متزامن (Concurrency) | 
* Active object
* Actor
* Balking
* حاجز (حوسبة)
* Binding properties
* Coroutine
* Compute kernel
* Double-checked locking
* Event-based asynchronous
* ليف
* Futex
* Futures and promises
* Guarded suspension
* Immutable object
* Join
* Lock
* صيغة التراسل
* Monitor
* Nuclear
* Proactor
* Reactor
* Read write lock
* Scheduler
* STM
* Thread pool
* Thread-local storage

 |
| معماري (Architectural) | 
* \* ADR
* نمط التسجيل النشط
* نمط الوسيط
* نموذج الخادم والعميل
* هندسة البرمجيات بالمكونات
* DAO
* كائن نقل البيانات
* تصميم موجه بالمجال
* ECB
* ECS
* EDA
* Front controller
* Identity map
* Interceptor
* Implicit invocation
* عكس التحكم
* Model 2
* MOM
* Microservices
* MVA
* نمط وعرض ومتحكم
* MVP
* MVVM
* Monolithic
* عمارة متعددة الطبقات
* Naked objects
* ORB
* ند لند
* Publish–subscribe
* PAC
* رست
* بنية خدمية
* نمط محدد موقع الخدمة
* SN
* SBA
* Specification

 |
| توزيع سحابي (Cloud Distributed) | 
* Ambassador
* Anti-Corruption Layer
* Bulkhead
* Cache-Aside
* Circuit Breaker
* CQRS
* Compensating Transaction
* Competing Consumers
* Compute Resource Consolidation
* Event Sourcing
* External Configuration Store
* Federated Identity
* Gatekeeper
* فهرس قاعدة بيانات
* Leader Election
* نموذج الهيكلة والتجميع
* Materialized View
* Pipes
* Filters
* Priority Queue
* Publisher-Subscriber
* Queue-Based Load Leveling
* Retry
* Scheduler Agent Supervisor
* Sharding
* Sidecar
* Strangler
* Throttling
* Valet Key

 |
| أخرى | 
* Business delegate
* Composite entity
* Intercepting filter
* Lazy loading
* Mangler
* غرض مقلد
* Type tunnel
* Method chaining

 |
| كتب | 
* *خطط التصميم*
* *Enterprise Integration Patterns*
* *Code Complete*
* *POSA*

 |
| أشخاص | 
* كريستوفر الكسندر
* إريك جاما
* رالف جونسن
* John Vlissides
* Grady Booch
* كينت بيك
* وورد كانينغهام
* مارتن فاولر
* روبرت سيسيل مارتن
* Jim Coplien
* دوغلاس س. شميت
* Linda Rising

 |
| مجتمعات (Communities) | 
* The Hillside Group
* The Portland Pattern Repository

 |

* أيقونة بوابةبوابة تقانة
* أيقونة بوابةبوابة تقانة المعلومات
* أيقونة بوابةبوابة علم الحاسوب