Как унифицировать интерфейс разных типов данных в C ++ - PullRequest
0 голосов
/ 15 октября 2019

скажем, у меня есть две разные платформы, которые по-разному обрабатывают один и тот же ресурс: одна среда использует INT в качестве дескриптора, а другая инкапсулирует ресурс в классе.

Как создать уровень абстракции поверх этих структурчто на самом деле скрывает эту разницу за общим интерфейсом?

1 Ответ

0 голосов
/ 15 октября 2019

Выберите интерфейс, который вы хотите использовать, и укажите шаблон адаптера для другого. Вы оборачиваете класс (или тип данных) в новый класс, чтобы изменить интерфейс так, чтобы он 'был совместим с другими вашими классами.

Или вы можете посмотреть шаблон фасада на случай, еслиэто соответствует вашим потребностям лучше. Вы создаете «интерфейсный» класс, который знает, как обращаться к слабо связанным интерфейсам и взаимодействует с ними для вас. Мне очень нравится пример вызова линии обслуживания клиентов, которая затем соединит вас с соответствующим отделом.

Вы можете даже использовать адаптер вместе с фасадом, чтобы упростить код фасада.

Если бы типы были достаточно похожи, вы могли бы использовать std::conditional вместе с некоторыми SFINAE. Пример можно найти здесь: * https://gitlab.com/sweenish/seeded_prng/blob/master/Random.hpp
Код:

#ifndef THIS___RANDOM_HPP
#define THIS___RANDOM_HPP

#include <algorithm>
#include <array>
#include <cstdint>
#include <functional>
#include <iterator>
#include <limits>
#include <random>
#include <type_traits>

namespace rnd {
template <typename T = std::uint32_t, typename Enable = void>
class Mersenne;

template <typename T>
using AllowForUnsigned = std::enable_if_t<std::is_unsigned_v<T>>;

template <typename T>
class Mersenne<T, AllowForUnsigned<T>>
{
public:
    Mersenne();
    T operator()();

    using result_type = T;
    static constexpr result_type min();
    static constexpr result_type max();

private:
    using Twister = std::conditional_t<sizeof(T) <= 4, std::mt19937, std::mt19937_64>;
    Twister engine_;
};

// Class is implemented here, but these details don't matter for this answer; 
// see the link if interested
#endif

Этот класс будет создаваться только в том случае, если тип шаблона не подписан, а в зависимости от размера типа без знака - типаengine_ будет 32-разрядным или 64-разрядным Mersenne Twister PRNG. Можно также сказать, что используется шаблон адаптера. Многие другие объявления вне конструктора по умолчанию существуют, поэтому этот класс по-прежнему работает с библиотекой <random>.

* Бесстыдная штепсельная вилка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...