Kody źródłowe/Strategia (wzorzec projektowy)

Z Wikibooks, biblioteki wolnych podręczników.
Przejdź do nawigacji Przejdź do wyszukiwania


Strategia (wzorzec projektowy)
Kod źródłowy
Kody źródłowe programów stosujących wzorzec projektowy strategii
Wikipedia
Zobacz w Wikipedii hasło Strategia

C++[edytuj]

#include <string>
#include <iostream>
#include <vector>
using namespace std;
 
/* Reprezentuje rycerza
 */
class Knight {
    private:
        unsigned int age;
        string name;
 
    public:
        Knight(unsigned int ag, string nm)
            : age(ag), name(nm) {}
 
        unsigned int getAge() const {
            return age;
        }
 
        string getName() const {
            return name;
        }
};
 
/* Interfejs validatora
 */
class KnightValidator {
    public:
        virtual ~KnightValidator() {}
        virtual bool validate(Knight const&) = 0;
};
 
/* Przyjmuje tylko rycerzy w wieku ponad 60 lat
 */
class OldKnightsValidator : public KnightValidator {
    public:
        bool validate(Knight const& kn) {
            return kn.getAge() > 60;
        }
};
 
/* Przyjmuje tylko rycerzy o imionach brzmiących męsko
 * (pomijamy Barnabę itp.)
 */
class MaleKnightsValidator : public KnightValidator {
    public:
        bool validate(Knight const& kn) {
            string name = kn.getName();
            return name.at(name.length() - 1) != 'a';
        }
};
 
/* Reprezentuje arenę
 */
class Arena {
    private:
        vector<Knight> knights;
        KnightValidator* validator;
 
    public:
        Arena(KnightValidator* valptr)
            : validator(valptr) {}
 
        void addKnight(Knight const& kn) {
            if (validator->validate(kn)) {
                knights.push_back(kn);
            }
        }
 
        void printKnights() const {
            for (vector<Knight>::const_iterator it = knights.begin();
                 it != knights.end(); ++it) {
                cout << it->getName() << '\n';
            }
        }
};
 
// Przykład użycia
int main() {
    Knight anna(20, "Anna");
    Knight zbyszko(40, "Zbyszko");
    Knight dobromil(70, "Dobromil");
    OldKnightsValidator ovalid;
    MaleKnightsValidator mvalid;
    Arena eldersArena(&ovalid);
    Arena malesArena(&mvalid);
 
    eldersArena.addKnight(anna);
    eldersArena.addKnight(zbyszko);
    eldersArena.addKnight(dobromil);
 
    malesArena.addKnight(anna);
    malesArena.addKnight(zbyszko);
    malesArena.addKnight(dobromil);
 
    cout << " === Arena seniorow ===\n";
    eldersArena.printKnights();
    cout << " === Arena bez rownoupranienia ===\n";
    malesArena.printKnights();
}

W podanym przykładzie wzorzec strategii realizują interfejs KnightValidator oraz implementujące go klasy OldKnightsValidator oraz MaleKnightsValidator, które określają, czy wskazany obiekt klasy Knight spełnia kryterium dotyczące wieku lub imienia. Klasa Arena wykorzystuje przekazany w czasie działania programu obiekt KnightValidator do kontrolowania przyjmowanych rycerzy.

Java[edytuj]

import java.util.ArrayList;
import java.util.List;


/* Reprezentuje rycerza
 */
class Knight{
	
	private String name;
	private int age;
	
	public Knight(int age, String name){
		
		this.name = name;
		this.age = age;
		
	}
	
	public int getAge(){
		
		return this.age;
		
	}
	
	public String getName(){
		
		return this.name;
		
	}
	
	
}
/* Interfejs validatora
 */
interface KnightValidator{
	
	boolean validate(Knight knight);
	
}

/* Przyjmuje tylko rycerzy w wieku ponad 60 lat
 */
class OldKnightsValidator implements KnightValidator{
	
	public boolean validate(Knight knight){
		
		return knight.getAge()>60;
	}
	
}

/* Przyjmuje tylko rycerzy o imionach brzmiących męsko
 * (pomijamy Barnabę itp.)
 */
class MaleKnightsValidator implements KnightValidator{
	
	public boolean validate(Knight knight){
		String name = knight.getName();
		return name.charAt(name.length()-1)!='a';
	}
	
}

/* Reprezentuje arenę
 */
class Arena{
	
	private List<Knight> knights;
	private KnightValidator validator;
	
	public Arena(KnightValidator validator){
		
		this.validator = validator;
		
		knights =  new ArrayList<Knight>(); 
		
	}
	
	public void addKnight(Knight knight){

		if(validator.validate(knight))
			knights.add(knight);
	
	}
	
	public String toString(){
		String out ="";
		for(Knight knight : knights)
		 out += "Rycerz " +  knight.getName() + "\n";
			
		return out;
		
	}
}

public class StrategiaTest {

	
	public static void main(String[] args) {
	
	    Knight anna = new Knight(20, "Anna");
	    Knight zbyszko = new Knight(40, "Zbyszko");
	    Knight dobromil = new Knight(70, "Dobromil");
		
	    KnightValidator oldValid = new OldKnightsValidator();
	    KnightValidator nameValid = new MaleKnightsValidator();
		
	    Arena eldersArena = new Arena(oldValid);
	    Arena malesArena = new Arena(nameValid);
		
	    eldersArena.addKnight(anna);
	    eldersArena.addKnight(zbyszko);
	    eldersArena.addKnight(dobromil);
		
	    malesArena.addKnight(anna);
	    malesArena.addKnight(zbyszko);
	    malesArena.addKnight(dobromil);
	    
	    System.out.println("=== Arena seniorow ===");
	    System.out.println(eldersArena);
	    
	    System.out.println("=== Arena bez rownouprawnienia ===");
	    System.out.println(malesArena);
		
		
	}

}

C#[edytuj]

using System;
using System.Collections.Generic;

namespace TheStrategyPattern
{
    /// <summary>
    /// Reprezentuje rycerza
    /// </summary>
    class Knight
    {
        private String name;
        private int age;

        public Knight(int age, String name)
        {
            this.name = name;
            this.age = age;
        }

        public int getAge()
        {
            return this.age;
        }

        public String getName()
        {
            return this.name;
        }

    }
    /// <summary>
    /// /* Interfejs validatora
    /// </summary>
    interface KnightValidator
    {
        bool validate(Knight knight);
    }

    /// <summary>
    /// Przyjmuje tylko rycerzy w wieku ponad 60 lat
    /// </summary>
    class OldKnightsValidator : KnightValidator
    {
        public bool validate(Knight knight)
        {
            return knight.getAge() > 60;
        }
    }

    /// <summary>
    /// Przyjmuje tylko rycerzy o imionach brzmiących męsko
    /// (pomijamy Barnabę itp.)
    /// </summary>
    class MaleKnightsValidator : KnightValidator
    {
        public bool validate(Knight knight)
        {
            String name = knight.getName();
            return !name.EndsWith("a");
        }
    }

    /// <summary>
    /// Reprezentuje arenę
    /// </summary>
    class Arena
    {
        private List<Knight> knights;
        private KnightValidator validator;

        public Arena(KnightValidator validator)
        {
            this.validator = validator;
            knights = new List<Knight>();
        }

        public void addKnight(Knight knight)
        {
            if (validator.validate(knight))
                knights.Add(knight);
        }

        public override string ToString()
        {
            String strOut = "";
            foreach (Knight knight in knights)
            {
                strOut += "Rycerz " + knight.getName() + "\n";
            }
            return strOut;
        }
    }

    public class StrategiaTest
    {

        public static void Main(String[] args)
        {
            Knight anna = new Knight(20, "Anna");
            Knight zbyszko = new Knight(40, "Zbyszko");
            Knight dobromil = new Knight(70, "Dobromil");

            KnightValidator oldValid = new OldKnightsValidator();
            KnightValidator nameValid = new MaleKnightsValidator();

            Arena eldersArena = new Arena(oldValid);
            Arena malesArena = new Arena(nameValid);

            eldersArena.addKnight(anna);
            eldersArena.addKnight(zbyszko);
            eldersArena.addKnight(dobromil);

            malesArena.addKnight(anna);
            malesArena.addKnight(zbyszko);
            malesArena.addKnight(dobromil);

            Console.WriteLine("=== Arena seniorow ===");
            Console.WriteLine(eldersArena);

            Console.WriteLine("=== Arena bez rownoupranienia ===");
            Console.WriteLine(malesArena);

            Console.ReadLine();
        }
    }
}