2017-01-29 4 views
0

Я сделать игру в Unity C# с использованием SingletonGameManager и я был предупрежден, что с помощью ссылки класса в других сценариях, как GameManager.instance.someVar делает код хрупким и трудным для последующего использования редактировать. Поэтому я искал , как получить доступ к одноэлементному интерфейсу с интерфейсами, но не нашел, что было после. Поскольку я хочу правильно закодировать, я хотел бы, чтобы кто-то указал мне на достойный источник, который говорит мне, как это сделать, или попросите его кратко рассказать мне.Выставьте Singleton к другим классам, используя интерфейс

+0

Одноэлементный шаблон чрезвычайно распространен в играх - информация о игроке, например, хорошо подходит для него - каким образом это _fragile_? Также укажите свой код, чтобы были видны некоторые изъяны (а также источники, связанные с этим недостатком). –

ответ

1

Ну, есть общее решение этого вопроса, я не уверен, насколько это возможно для вас.

Предположим, что мы имеем истинное синглтон:

public static class Highlander //cos, there can be only one. Sorry. couldn't resist 
{ 
    public static void Quicken(string name) 
    { 
     Console.WriteLine("{0} gets their quickening on",name); 
    } 
} 

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

public interface IImmortal 
{ 
    void Quicken(); 
} 

Ну, вы не можете реализовать интерфейс на статический класс или член, так как вы передаете ссылки на этот класс вокруг интерфейсом?

Простой - создать класс обертку/адаптер, который реализует интерфейс, который вы хотите:

public class McLeod: IImortal 
{ 
    public void Quicken() 
    { 
     Highlander.Quicken("Conor"); 
    } 
} 

public class Kurgen: IImortal 
{ 
    public void Quicken() 
    { 
     Highlander.Quicken("The Kurgen"); 
    } 
} 

Теперь вы можете пройти IImortal вокруг, и реализация (s) обертывание просто позвоните через к Singleton. Обратите внимание, как Wrapper может передавать данные в Singleton изнутри, как указано выше, и в этом случае это больше похоже на Adapter. Но концепция такая же.

В случае единства, я не знаю, если это устраивает, так как класс GameManager вероятно выставляет массу других свойств и методов, которые вы также должны обернуть/адаптировать - это может быть не стоит создавать обертка интерфейсы для всего этого, поэтому рассмотрим, возможно, что в этом случае вы должны принять его :)

0

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

Истинное ограничение программирования Singlton находится в области модульного тестирования - поскольку ваш код привязан непосредственно к определенному классу GameManager, вы не можете заменить его в модульном тесте другой «тестовой версией» GameManager. Чтобы поддерживать модульное тестирование, вы должны попытаться убедиться, что любые существенные классы, от которых зависит ваш код, могут быть заменены тестовой версией класса без вашего кода. При использовании синглтонов это трудно (если не невозможно).

0

Обычно я стараюсь, чтобы создать пустой GameObject, дать ему имя или метку и прикрепить компонент сценария к Это.

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

+0

Мне также было интересно узнать, какова была настоящая цель этого класса и почему OP хотел использовать шаблон Singleton. Большую часть времени, предлагая решение без раскрытия проблемы, может привести к очень вводящим в заблуждение ответам. – MizRaeL

+0

Я думал, что вы задаете вопрос и отвечаете, поэтому я удалил вопросную часть (которая не входит в ответ). Если я допустил ошибку, не стесняйтесь снова редактировать. Возможно, ваши вопросы были риторическими (в этом случае я бы предложил сформулировать эти идеи по-разному). Благодарю. – Moritz

+0

Если так, тогда вы были правы, я действительно спрашивал и отвечал. В этом случае, что такое обычная практика? Должен ли я спросить, а затем создать комментарий? Благодаря! – MizRaeL

Смежные вопросы