Как у меня может быть Singleton, это получено из абстрактного типа в Java?

Если вы используете C ++ 17, вы можете сделать следующее (скомпилировано с помощью команды g++ -std=c++17 -Wall -Wpedantic main.cc, используя g++ версию 7.3.0 в Debian):

#include <iostream>
#include <cstdint>
#include <climits>
#include <type_traits>

template<typename InputType>
constexpr auto ConcatenateBits(InputType highPart, InputType lowPart) {
  constexpr bool is_uint8 = std::is_same<InputType, uint8_t>::value;
  constexpr bool is_uint16 = std::is_same<InputType, uint16_t>::value;
  constexpr bool is_uint32 = std::is_same<InputType, uint32_t>::value;
  static_assert(is_uint8 || is_uint16 || is_uint32,
                "Input type to ConcatenateBits must be uint{8,16,32}_t.");
  if constexpr (is_uint8) {
    uint16_t output = lowPart;
    output |= (static_cast<uint16_t>(highPart) << (sizeof(InputType) * CHAR_BIT));
    return output;
  } else if constexpr (is_uint16) {
    uint32_t output = lowPart;
    output |= (static_cast<uint32_t>(highPart) << (sizeof(InputType) * CHAR_BIT));
    return output;
  } else {
    uint64_t output = lowPart;
    output |= (static_cast<uint64_t>(highPart) << (sizeof(InputType) * CHAR_BIT));
    return output;
  }
}

int main() {
  uint16_t explicitly_typed_variable = 1;
  std::cout << ConcatenateBits(explicitly_typed_variable, explicitly_typed_variable) << "\n";
  std::cout << ConcatenateBits<uint8_t>(1, 2) << "\n";
}

С выводом:

65537
258
11
задан Hanno Fietz 15 May 2009 в 15:47
поделиться

4 ответа

Это невозможно в Java. Существование статических методов не может быть принудительным; ни с помощью аннотации , ни с помощью интерфейса .

Мое решение состояло в том, чтобы использовать IoC определенным образом: я создал фабричный класс для синглтонов. Это сохранит одиночные объекты на карте. Ключом будет класс. Таким образом, я мог бы сказать:

A singleton = Factory.create (A.class);

Основное преимущество этого дизайна: я могу создать метод Factory.replace () , в котором тестовые примеры могут переопределить синглтоны.

14
ответ дан 3 December 2019 в 05:59
поделиться

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

На самом деле в этом нет необходимости, поскольку статические методы будут вызываться только непосредственно в дочерних классах ( A.init () и A.getInstance () в вашем примере) и никогда через ссылку на базовый класс (т. е. статические методы не поддерживают полиморфизм ).

2
ответ дан 3 December 2019 в 05:59
поделиться

Почему бы вам не пройти весь путь и не передать вашей фабрике (в базовом классе) параметр, указывающий, какой подкласс вы хотите вернуть. У такого способа есть много преимуществ и мало недостатков.

То, как вы это пытаетесь сделать, не имеет большого смысла, поскольку статические методы не работают с наследованием точно так же, как обычные методы.

1
ответ дан 3 December 2019 в 05:59
поделиться

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

public class UsefulThing {

}

public final class SingletonOfUsefulThing {
    private static UsefulThing instance;

    private SingletonOfUsefulThing() {}

    public UsefulThing getInstance() {
        if (instance == null) {
            instance = new UsefulThing(); 
        }

        return instance;
    }
}

Это позволяет вам предоставить некоторые из основных преимуществ синглтона классу без некоторых последствий, которые реализация семантики синглтона в классе напрямую вынуждает вас иметь дело и дает некоторое пространство для изменения конкретного типа класс, который вы представляете как одноэлементный (например, используя фабрику для создания экземпляра вместо new .

3
ответ дан 3 December 2019 в 05:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: