Automatizando a criação de objetos usando um pipeline

Olá, Habr!





Não sou um especialista muito famoso, mas estou muito interessado no processo de processamento de dados, bem como em escrever código para processar esses mesmos dados. No processo de escrever vários métodos de processamento desses mesmos dados, tive a ideia de automação parcial, ahem, escrever métodos de processamento.





Introdução

Suponha que temos um conjunto de ferramentas (entidades) para processar algum tipo de fluxo de dados, ou construir outras entidades complexas, bem como condições em constante mudança para a sequência de composição dessas entidades para reproduzir o algoritmo de processamento.





Usando veículos como exemplo

Temos um conjunto de componentes atômicos:





	class EngineA;
	class EngineB;

	class WingsA;
	class WingsB;

	class FrameA;
	class FrameB;

	class WheelsA;
	class WheelsB;
      
      



etc.





Se precisarmos de um carro, simplesmente declaramos a classe Car , que possui a carroceria, rodas, motor desejados etc. Da mesma forma com um barco, declararíamos uma classe Barco e rapidamente esboçaríamos a agregação das peças necessárias do barco.





Se precisarmos de um barco, um carro e até mesmo um avião, podemos usar o padrão de fábrica, mas o que fazer se precisarmos de carros, barcos, aviões, e não sabemos com antecedência quantos, quando e em que ordem .





, Car, Boat, Plane ITransport. 2 , 5 - . , , . -









, !





, ITransport





class ITransport
{
	public:

	virtual void move() = 0; 
};
      
      



Car, Boat, Plane.





class Car final : public virtual ITransport
{
public:

	Car() = default; 
	~Car() = default;

	void move() override
	{
		std::cout << "Car is move" << std::endl;
		// do something with parts
	}
      
 private:
      
    std::unique_ptr < IFrame >	_frame; 
    std::unique_ptr < IWheels >	_wheels; 
		std::unique_ptr < IEngine > _engine;
};


class Boat final : public virtual ITransport
{
public:

	Boat() = default; 
	~Boat() = default;

	void move() override
	{
		std::cout << "Boat is move" << std::endl;
		// do something with parts
	}
      
private:

	std::unique_ptr < IFrame >	_frame; 
	std::unique_ptr < IEngine>  _engine;
};

class Plane final : public virtual ITransport
{
public:

	Plane() = default; 
	~Plane() = default;

	void move() override
	{
		std::cout << "Plane is move" << std::endl;
		// do something with parts
	}

private:

	std::unique_ptr < IFrame > _frame;
	std::unique_ptr < IEngine> _engine;
	std::unique_ptr < IWings > _wings;
};
      
      



2 , , 3 , .





, . .





enum class VehTypes
{
	Car,
	Boat,
	Plane
};
	 
static std::map < std::string, VehTypes > VehCast{
	{"Car", VehTypes::Car},
	{"Boat", VehTypes::Boat},
	{"Plane", VehTypes::Plane}
};

      
      



, .





class Conveyor final
{
		
public:
			 
	using _TyParameters = std::map < std::string, std::string >; 
	using _TyStorage = std::vector < _TyParameters >;

	Conveyor(const _TyStorage& blueprints)
		: _blueprints(blueprints) { }

	~Conveyor() = default;

	std::vector < Vehicles::ITransport* > vehicles()
	{
		std::vector < Vehicles::ITransport* > result;

		for (auto&& blueprint : _blueprints)
		{

			switch (VehCast[blueprint["type"]])
			{
				case VehTypes::Car: result.emplace_back(new Vehicles::Car());
				break;

				case VehTypes::Boat: result.emplace_back(new Vehicles::Boat());
				break;

				case VehTypes::Plane: result.emplace_back(new Vehicles::Plane());
				break;
			}
		}

		return result;
	}
			 
private: 

	_TyStorage _blueprints;
};
      
      



, .





:





  • -





  • - , .





using _TyParameters = std::map < std::string, std::string >; 
using _TyStorage = std::vector < _TyParameters >;
      
      



, ( ).





, - , .









( ) .





.





.





Conveyor::_TyStorage blueprints
{
  {
    {"type", "Car"}, {"engineType", "EngineA"}, {"wheelsType", "WheelsB"}, etc..
  },		
  {
    {"type", "Car"},  
  },		
  {
    {"type", "Boat"},  
  },		
  {
    {"type", "Plane"},  
  },		
  {
    {"type", "Plane"},  
  },		
  {
    {"type", "Plane"}
  },		
  {
    {"type", "Boat"}
  },
};

Conveyor conveyor(blueprints);

for (auto&& transport : conveyor.vehicles())
{
	transport->move();
}
      
      







, , .





, , / .





Dos pontos fracos dessa abordagem para construir objetos, posso notar a necessidade de adicionar novos tipos ao dicionário todas as vezes, bem como adicionar constantemente o interpretador de novos parâmetros de texto se você estiver constantemente adicionando novos componentes atômicos.








All Articles