Вызовите Шаблон "одиночка" на Классе, реализовав Интерфейс

Другая опция состоит в том, чтобы использовать битовые поля:

struct bits {
    unsigned int a:1;
    unsigned int b:1;
    unsigned int c:1;
};

struct bits mybits;

определяет 3-разрядное поле (на самом деле, это - три 1-разрядных felds). Битовые операции теперь становятся немного (ха-ха) более простым:

, Чтобы установить или очиститься немного:

mybits.b = 1;
mybits.c = 0;

Для переключения немного:

mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1;  /* all work */

Проверка немного:

if (mybits.c)  //if mybits.c is non zero the next line below will execute

Это только работает с битовыми полями фиксированного размера. Иначе необходимо обратиться к методам битового жонглирования, описанным в предыдущих сообщениях.

6
задан Duleb 30 July 2009 в 12:30
поделиться

5 ответов

Вы можете использовать отражение. Примерно так:

public interface Model {
  class Singleton {
    public static Model instance(Class<? extends Model> modelClass) {
      try {
        return (Model)modelClass.getField("instance").get(null);
     } catch (blah-blah) {
       blah-blah
     }
  }
}

public class XmlModel implements Model {
  private static final Model instance = new XmlModel();

  private XmlModel() {
  }
}

использование:

Model.Singleton.instance(XmlModel.class)

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

2
ответ дан 17 December 2019 в 02:32
поделиться

Можете ли вы преобразовать интерфейс в абстрактный класс? Это позволит вам применить определенный фабричный метод ко всем реализующим классам.

0
ответ дан 17 December 2019 в 02:32
поделиться
  1. Создайте завод, который возвращается экземпляры вашего интерфейса, Model.
  2. Сделайте все конкретные реализации модели package-private классов в том же пакете, что и ваша фабрика.
  3. Если ваша модель должна быть одноэлементной, и вы используете java 5+, используйте enum вместо традиционного singleton, так как это безопаснее.
public enum MyXMLModel{  
INSTANCE();  
//rest of class  
};

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

например:

class MyXMLModelDelegate implements Model {
public void foo() { /*does foo*/}
...
}

class MyJSONModelDelegate implements Model {
public void foo() { /*does foo*/ }
...
}

public enum Models {
XML(new MyXMLModelDelgate()),
JSON(new MyJSONModelDelegate());

private Model delegate;
public Models(Model delegate) { this.delegate=delegate; }

public void foo() { delegate.foo(); }
}
4
ответ дан 17 December 2019 в 02:32
поделиться

Я задавал себе тот же вопрос. И я предложил тот же ответ; -)

Теперь я обычно отказываюсь от "принудительного" поведения, я полагаюсь на документацию. Я не нашел ни одного случая, когда аспект синглтона был настолько убедительным, чтобы его нужно было применять всеми способами. Это просто «лучшая практика» для проекта.

Я обычно использую Spring для создания экземпляра такого объекта, и именно конфигурация Spring делает его синглтоном. Безопасно и так просто ... плюс дополнительные преимущества Spring (такие как проксирование, однократная подстановка другого объекта для выполнения некоторых тестов и т.д.)

0
ответ дан 17 December 2019 в 02:32
поделиться

Это больше ответ на ваш комментарий / пояснение к ответу kts. Неужели настоящая проблема заключается не в использовании шаблона синглтона, а в определении схемы точки расширения затмения (равноденствия), которая позволяет добавлять синглтон?

Я думаю, это невозможно, потому что каждый раз, когда вы вызываете IConfigurationElement. createExecutableExtension вы создаете новый экземпляр. Это совершенно несовместимо с вашим требованием к синглтону. И поэтому вам нужен общедоступный конструктор по умолчанию, чтобы каждый мог создавать экземпляры.

Если вы не можете изменить определение точки расширения так, чтобы плагины предоставляли ModelFactory, а не модель, например

public interface ModelFactory {

  public Model getModelInstance();

}

Таким образом, пользователь расширения создаст экземпляр ModelFactory и используйте его для получения синглтона.

Если я не угадала, оставлю комментарий и удалю ответ;)

0
ответ дан 17 December 2019 в 02:32
поделиться
Другие вопросы по тегам:

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