Сегодня опять немного спорили на работе. Ситуация примерно следующая.
Есть некий интерфейс плагина
public interface IPlugin
{
...
void Init();
void Shutdown();
}
В текущей реализации нескольких плагинов Shutdown не делает ничего. Но когда то он точно понадобится.
Init используется только в одном плагине и в дальнейшем вероятно не понадобится.
Первая сторона утверждает, что эти две фукнции мертвый код, который сейчас никому не нужен (вызов Shutdown действительно забыли), Init с первого плагина можно можно перенести в конструктор и удалить эти две фукнции как ненужный код. Когда они действительно понадобятся их можно будет добавить.
Вторая сторона утверждает что лучше сделать забытый вызов Shutdown и оставить пустые функции с комментариями для чего они нужны. Зато когда они действительно понадобятся можно будет без проблем добавить в функции код и все будет работать.
Здравствуйте, AlexNek, Вы писали:
AN>Первая сторона утверждает, что эти две фукнции мертвый код, который сейчас никому не нужен (вызов Shutdown действительно забыли), Init с первого плагина можно можно перенести в конструктор и удалить эти две фукнции как ненужный код. Когда они действительно понадобятся их можно будет добавить.
AN>Вторая сторона утверждает что лучше сделать забытый вызов Shutdown и оставить пустые функции с комментариями для чего они нужны. Зато когда они действительно понадобятся можно будет без проблем добавить в функции код и все будет работать.
AN>Чъя сторона имеет все же больший вес?
Третья. Вынесите инициализацию плагина в отдельный интерфейс (IPluginLifecycle?) и пусть хост проверяет, что плагин реализует этот интерфейс и если да, то обрабатывает его специфическим образом.
Здравствуйте, rusted, Вы писали:
R>Здравствуйте, AlexNek, Вы писали:
AN>>Зато когда они действительно понадобятся можно будет без проблем добавить в функции код и все будет работать.
R>Может оказаться, что когда "действительно понадобится", то оно понадобится способом, конфликтующим с тем, что было напроектировано заранее.
Каким образом? Есть функции "начало" и "конец" фактически это получаются события по котором и можно что то делать.
При этом они там как бы согласно концепта, там пока минимум просто лог ведется. Если их убрать, то потом прийдется как бы придумывать все по новому, и искать куда засунуть вызовы. Иначе можно просто поместить код в известные функции практически ни о чем не думая.
Здравствуйте, Lloyd, Вы писали:
L>Третья. Вынесите инициализацию плагина в отдельный интерфейс (IPluginLifecycle?) и пусть хост проверяет, что плагин реализует этот интерфейс и если да, то обрабатывает его специфическим образом.
В этом направдении как и не думали, пожалуй это будет лучший выход.
Тогда может обсудим проблмы "живой" правки интерфейса? Интерфейс то от плагина, хоть и будет полное обновление, но не хочется иметь проблем. Но и лишнего усложнения также. По крайней мере, номер версии интерфейса в IPlugin имеется.
Нужно ведь будет старый интерфейс менять (удалять функции)
Здравствуйте, AndrewVK, Вы писали:
L>>Третья. Вынесите инициализацию плагина в отдельный интерфейс (IPluginLifecycle?)
AVK>Проблема, судя по стартовому сообщению, не в инициализации, а в Shutdown. И для последнего лучше использовать стандартный IDisposable.
Здравствуйте, AndrewVK, Вы писали:
L>>Имхо, не принципиально. Можно и так, и так.
AVK>Для IDisposable есть куча полезных хелперов, начиная от using и заканчивая DisposeAll в некоторых библиотеках.
С другой стороны, вариант со своим интерфейсом гибче. Если понадобится передавать в плагин какую-то информацию при "выключении" плагина, то придется придумывать workaround.
Надо смотреть по ситуации, исходя из общих соображений не могу сказать, что лучше, что хуже.
Здравствуйте, AlexNek, Вы писали:
AN>Здравствуйте, rusted, Вы писали:
R>>Здравствуйте, AlexNek, Вы писали:
AN>>>Зато когда они действительно понадобятся можно будет без проблем добавить в функции код и все будет работать.
R>>Может оказаться, что когда "действительно понадобится", то оно понадобится способом, конфликтующим с тем, что было напроектировано заранее. AN>Каким образом? Есть функции "начало" и "конец" фактически это получаются события по котором и можно что то делать. AN>При этом они там как бы согласно концепта, там пока минимум просто лог ведется. Если их убрать, то потом прийдется как бы придумывать все по новому, и искать куда засунуть вызовы. Иначе можно просто поместить код в известные функции практически ни о чем не думая.
Сейчас у вас есть два места для инициализации (конструктор и Init) и два места для деинициализации (Shutdown и что там в вашем языке вместо деструктора). Раз оно есть, то со временем начнет использоваться — причем и то и то. А потом могут появится плагины, которым для работы важно наличие других плагинов, и понадобится механизм контроля очередности инициализации/деинициализации. И имеющиеся Init/Shutdown не только не решают эту задачу, но еще и усложняют её.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Lloyd, Вы писали:
L>>Третья. Вынесите инициализацию плагина в отдельный интерфейс (IPluginLifecycle?)
AVK>Проблема, судя по стартовому сообщению, не в инициализации, а в Shutdown. И для последнего лучше использовать стандартный IDisposable.
Не подойдет. Плагину можно сделать Shutdown, но не выгружать из памяти. Нужен именно контроллируемый процесс входа/выхода.
Конструктор в общем случае не эквивалентен иниту, а деструктор Shutdown. Хотя в частных случаях это может быть и неважно.
Важно, что инит будет всегда после конструктора, когда объект уже в "устойчивом состоянии".
Здравствуйте, AlexNek, Вы писали:
AVK>>Проблема, судя по стартовому сообщению, не в инициализации, а в Shutdown. И для последнего лучше использовать стандартный IDisposable. AN>Не подойдет. Плагину можно сделать Shutdown, но не выгружать из памяти.
И?
AN>Конструктор в общем случае не эквивалентен иниту, а деструктор Shutdown.
А что, кто то предлагал использовать конструктор и деструктор?
... << RSDN@Home 1.2.0 alpha 5 rev. 31 on Windows 7 6.1.7601.65536>>
Здравствуйте, AlexNek, Вы писали:
AN>В текущей реализации нескольких плагинов Shutdown не делает ничего. Но когда то он точно понадобится. AN>Init используется только в одном плагине и в дальнейшем вероятно не понадобится.
Как вариант — сделать класс BasicPlugin с пустыми имплементациями методов и пусть плагины наследуются от него
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, AlexNek, Вы писали:
AVK>>>Проблема, судя по стартовому сообщению, не в инициализации, а в Shutdown. И для последнего лучше использовать стандартный IDisposable. AN>>Не подойдет. Плагину можно сделать Shutdown, но не выгружать из памяти.
AVK>И?
Ты прав, будет работать, только непонятно для чего городить такой огород.
Да и желательно иметь "симметричные" функции, а не только одну
Здравствуйте, jpr111a, Вы писали:
J>Здравствуйте, AlexNek, Вы писали:
AN>>В текущей реализации нескольких плагинов Shutdown не делает ничего. Но когда то он точно понадобится. AN>>Init используется только в одном плагине и в дальнейшем вероятно не понадобится.
J>Как вариант — сделать класс BasicPlugin с пустыми имплементациями методов и пусть плагины наследуются от него
Вот что значит, зациклится на одном вопросе
Класс то и так есть, только нужно всего то заменить абстракт на виртуал. Это похоже будет хорошим компромиссом.
Да уж, огромный огород — один метод без параметров и возвращаемого значения.
AN>для второго предложения тот же огород — старт и стоп
Понимаешь, если делать двухфазную инициализацию, то разнесение начала и конца инициализации очень полезно. А если нет — я вообще не понимаю зачем тебе вторая инициализация.
... << RSDN@Home 1.2.0 alpha 5 rev. 31 on Windows 7 6.1.7601.65536>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, AlexNek, Вы писали:
AN>>>>Ты прав, будет работать, только непонятно для чего городить такой огород. AVK>>>Какой такой? AN>>сорри ссылку забыл AN>>http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
AVK>Да уж, огромный огород — один метод без параметров и возвращаемого значения.
Так этот метод уже и так был в примере же рекомендуется делать гораздо больше. И любой кто потм будет разбираться первым делом нарвется на эту ссылку.
AN>>для второго предложения тот же огород — старт и стоп
AVK>Понимаешь, если делать двухфазную инициализацию, то разнесение начала и конца инициализации очень полезно.
В теории — может быть. AVK>А если нет — я вообще не понимаю зачем тебе вторая инициализация.
Допустим, я хочу глянуть только список доступных плагинов, без их реального использования. А перед использованием нужно сделать немного больше.