Padrão de Estratégia de Padrão de Design Comportamental [Série de Padrões de Design]

Diretório de artigos da série

Série de habilidades C++
Série de arquitetura de comunicação Linux
Série de programação de otimização de alto desempenho C++
Compreensão profunda da série de design de arquitetura de software Série avançada de padrão de design
de programação de thread simultânea C++

Olhando para a frente a sua atenção! ! !
insira a descrição da imagem aqui

现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。
Now everything is for the future of dream weaving wings, let the dream fly in reality.

1. Introdução ao modo de estratégia

⚠️ 意图:
Defina uma série de algoritmos, encapsule-os um por um e torne-os intercambiáveis.

⚠️ 主要解决:
No caso de vários algoritmos semelhantes, usar if...else é complicado e difícil de manter.

⚠️ 何时使用:
Um sistema tem muitas, muitas classes, e o que as distingue é seu comportamento imediato.

⚠️ 如何解决:
Encapsule esses algoritmos em classes, uma a uma, e substitua-os arbitrariamente.

No Strategy Pattern o comportamento de uma classe ou seu algoritmo pode ser alterado em tempo de execução. Esse tipo de padrão de design é um padrão comportamental.
O padrão de estratégia define uma série de algoritmos ou estratégias e encapsula cada algoritmo em uma classe independente para que possam substituir uns aos outros. Usando o padrão de estratégia, diferentes algoritmos podem ser selecionados em tempo de execução, conforme necessário, sem modificar o código do cliente.
No padrão de estratégia, criamos objetos que representam várias estratégias e um objeto de contexto cujo comportamento muda à medida que o objeto de estratégia muda. Um objeto de estratégia altera o algoritmo de execução de um objeto de contexto.

insira a descrição da imagem aqui

Figura 1_1 Diagrama de classe de padrão de estratégia

Em segundo lugar, as vantagens e desvantagens do modelo de estratégia

2.1 Vantagens

1. O algoritmo pode ser alternado livremente. 2. Evite usar vários julgamentos condicionais. 3. Boa escalabilidade.

2.2 Desvantagens

1. Haverá mais estratégias. 2. Todas as classes de políticas precisam ser expostas ao mundo externo.

3. Cenários de uso do modo de estratégia

1. Se houver muitas classes em um sistema e a diferença entre elas for apenas seu comportamento, usar o padrão de estratégia pode permitir dinamicamente que um objeto escolha um comportamento entre muitos comportamentos. 2. Um sistema precisa escolher dinamicamente um dos vários algoritmos. 3. Se um objeto tiver muitos comportamentos, se não houver um modo apropriado, esses comportamentos deverão ser realizados usando várias instruções de seleção condicional.

4. Realização do modo de estratégia

ReplaceAlgorithm é uma classe abstrata que define a interface do algoritmo.Existem três classes herdadas dessa classe abstrata, ou seja, a implementação específica do algoritmo. O algoritmo de substituição precisa ser usado na classe Cache, portanto, um objeto ReplaceAlgorithm é mantido.

Primeiramente, é dada a definição do algoritmo de substituição.

//抽象接口
class ReplaceAlgorithm
{
    
    
public:
	virtual void Replace() = 0;
};
//三种具体的替换算法
class LRU_ReplaceAlgorithm : public ReplaceAlgorithm
{
    
    
public:
	void Replace() {
    
     cout<<"Least Recently Used replace algorithm"<<endl; }
};
 
class FIFO_ReplaceAlgorithm : public ReplaceAlgorithm
{
    
    
public:
	void Replace() {
    
     cout<<"First in First out replace algorithm"<<endl; }
};
class Random_ReplaceAlgorithm: public ReplaceAlgorithm
{
    
    
public:
	void Replace() {
    
     cout<<"Random replace algorithm"<<endl; }
};

Em seguida, é dada a definição de Cache. Este é o ponto chave. A implementação do Cache afeta diretamente a forma como os clientes o utilizam. A chave está em como especificar o algoritmo de substituição.

Método 1: Especifique diretamente por meio de parâmetros e passe um ponteiro para um algoritmo específico.

//Cache需要用到替换算法
class Cache
{
    
    
private:
	ReplaceAlgorithm *m_ra;
public:
	Cache(ReplaceAlgorithm *ra) {
    
     m_ra = ra; }
	~Cache() {
    
     delete m_ra; }
	void Replace() {
    
     m_ra->Replace(); }
};

Se esse método for usado, os clientes precisam conhecer as definições específicas desses algoritmos. Só pode ser usado da seguinte maneira, e você pode ver que muitos detalhes estão expostos.

int main()
{
    
    
	Cache cache(new LRU_ReplaceAlgorithm()); //暴露了算法的定义
	cache.Replace();
	return 0;
}

Método 2: Também é especificado diretamente através de parâmetros, mas ao invés de passar um ponteiro, é um rótulo. Dessa forma, os clientes precisam apenas conhecer o rótulo correspondente do algoritmo e não precisam saber a definição específica do algoritmo.

//Cache需要用到替换算法
enum RA {
    
    LRU, FIFO, RANDOM}; //标签
class Cache
{
    
    
private:
	ReplaceAlgorithm *m_ra;
public:
	Cache(enum RA ra) 
	{
    
     
		if(ra == LRU)
			m_ra = new LRU_ReplaceAlgorithm();
		else if(ra == FIFO)
			m_ra = new FIFO_ReplaceAlgorithm();
		else if(ra == RANDOM)
			m_ra = new Random_ReplaceAlgorithm();
		else 
			m_ra = NULL;
	}
	~Cache() {
    
     delete m_ra; }
	void Replace() {
    
     m_ra->Replace(); }
};

Comparado com o método 1, este método é muito mais conveniente de usar. Na verdade, este método combina o padrão de fábrica simples e o padrão de estratégia.A definição do algoritmo usa o padrão de estratégia, e a definição do Cache realmente usa o padrão de fábrica simples.

int main()
{
    
    
	Cache cache(LRU); //指定标签即可
	cache.Replace();
	return 0;
}

Nos dois métodos acima, o construtor requer parâmetros formais. Os construtores não podem receber parâmetros? A terceira implementação é dada abaixo.

Método 3: Use modelos para implementar. O algoritmo é especificado pelos argumentos do modelo. Claro, os parâmetros ainda são usados, mas não os parâmetros do construtor. No modo de estratégia, a passagem de parâmetros é inevitável e o cliente deve especificar um determinado algoritmo.

//Cache需要用到替换算法
template <class RA>
class Cache
{
    
    
private:
	RA m_ra;
public:
	Cache() {
    
     }
	~Cache() {
    
     }
	void Replace() {
    
     m_ra.Replace(); }
};

O uso é o seguinte:

int main()
{
    
    
	Cache<Random_ReplaceAlgorithm> cache; //模板实参
	cache.Replace();
	return 0;
}

Acho que você gosta

Origin blog.csdn.net/weixin_30197685/article/details/131927839
Recomendado
Clasificación