|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Как называете базовые абстрактные классы? пример: public abstract class UserAchievement Base vs public abstract class UserAchievement Или еще какая схема? ... |
|||
:
Нравится:
Не нравится:
|
|||
18.07.2017, 22:41 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Denis., В нашем стайлгайде так: Код: c# 1. 2. 3. 4. 5. 6. 7.
в случае, если абстрактный базовый класс не является контрактом, а всего лишь базовой реализацией. Если необходимо использовать абстрактный класс в качестве контракта, например, существуют методы, принимающие объекты наследников базового класса, или параметризация типом базового класса: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9.
тогда суффикс Base не используется. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 08:27 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Denis.Как называете базовые абстрактные классы?По настроению. Главное, чтобы название отражало суть. зы: "стайлгайды" детский сад. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 08:41 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Алексей КDenis.Как называете базовые абстрактные классы?По настроению. Главное, чтобы название отражало суть. зы: "стайлгайды" детский сад. Стайлгайды - это договоренность. А вот в детском саду обычно по настроению :) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 08:44 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Алексей КПо настроению. Главное, чтобы название отражало суть. Из разряда: — главное, чтобы было хорошо! — каковы критерии «хорошо»? — ээ.... — главное, чтобы отражало суть! — каковы критерии того, что суть отражена? — ээаэаээ... — главное, чтобы код был качественный! — каковы критерии качественного кода? — нуу... По настроению можно копать или не копать. Алексей Кзы: "стайлгайды" детский сад. Детский сад, это «по настроению». Смысла обсуждать и спорить на эту тему нет, потому что по-настроенщики могут быть только одиночки, и к командной разработке таких детишек не допускают. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 09:34 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
skyANAСтайлгайды - это договоренность. А вот в детском саду обычно по настроению :) Да вообще, Алексей удивляет. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 09:35 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttв случае, если абстрактный базовый класс не является контрактом, а всего лишь базовой реализацией. А если и то и то? Как же быть? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 11:21 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVostt— главное, чтобы отражало суть! — каковы критерии того, что суть отражена? — ээаэаээ...Всем читателям кода понятно из названия, для чего предназначен данный класс. hVostt— главное, чтобы код был качественный! — каковы критерии качественного кода? — нуу... Программа делает то, что написано в техническом задании. Программа легко модифицируется, при необходимости. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 11:33 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttskyANAСтайлгайды - это договоренность. А вот в детском саду обычно по настроению :) Да вообще, Алексей удивляет.Просто я работаю над долгоживущими проектами, в которых сменилось не одно поколение "стайлгайдов". :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 11:35 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Алексей КhVosttпропущено... Да вообще, Алексей удивляет.Просто я работаю над долгоживущими проектами, в которых сменилось не одно поколение "стайлгайдов". :-) Ну да, были времена, когда не было дженериков. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 11:57 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВhVosttв случае, если абстрактный базовый класс не является контрактом, а всего лишь базовой реализацией. А если и то и то? Как же быть? Это плохо. Надо исправить когда время будет. Речь же идёт о нейминге нового класса, следовательно ты знаешь как ты его будешь использовать. Чаще всего контрактом является интерфейс, но иногда интерфейс лишнее звено и следует использовать базовый класс как контракт. Такой нейминг нужен, чтобы было сразу понятно, как используется класс, это снимает много вопросов на взлёте. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 12:02 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Алексей КВсем читателям кода понятно из названия, для чего предназначен данный класс. Т.е. ты даёшь почитать ВСЕМ свой код, чтобы решить, угадал ты с названием или нет? У нас для этого по каждому проекту формируется словарь терминов. Есть также общий словарь для паттернов и архитектурных единиц. У каждой переиспользуемой библиотеки также есть свой словарь. Нет такого, чтобы какой-нибудь Вася назвал класс как ему вздумается только потому, что он решил, что все его правильно поймут. Вот это детский сад. Алексей КПрограмма делает то, что написано в техническом задании. Программа легко модифицируется, при необходимости. Т.е. не важно какой там говнокод, если программа делает то, что написано в тех. задании? Как же ты поймёшь, что программа будет легко модифицироваться при необходимости? Ждать, пока не произойдёт несколько модификаций, чтобы понять, хороший код или плохой? У нас для этого используется оценка обязанностей и ответственности классов, оценка связанности и связности компонентов, количественная оценка зависимостей, объёма кода, количества свойств/методов, оценка по следованию принципам проектирования и разработки. Также учитываются перегибы (слепое и бездумное следование принципам), антипаттерны. Мы можем сказать почему данный код плохой и хороший и объяснить почему на понятном всем языке в общепринятой терминологии. Вообще практикуешь code review? Занимался этим когда-нибудь? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 12:12 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Base есть, Abstract в топку. Код: c# 1. 2. 3. 4. 5. 6.
msAccessRule Aes Array Assembly AsymmetricAlgorithm AsymmetricKeyExchangeDeformatter AsymmetricKeyExchangeFormatter AsymmetricSignatureDeformatter AsymmetricSignatureFormatter Attribute AuditRule AuthorizationRule BaseChannelObjectWithProperties BaseChannelSinkWithProperties BaseChannelWithProperties Binder Calendar CodeAccessPermission CodeAccessSecurityAttribute CodeGroup CollectionBase CommonAcl CommonObjectSecurity Comparer`1 ConstructorInfo ContextBoundObject CriticalFinalizerObject CriticalHandle CriticalHandleMinusOneIsInvalid CriticalHandleZeroOrMinusOneIsInvalid CustomConstantAttribute Decoder DecoderFallback DecoderFallbackBuffer Delegate DeriveBytes DES DictionaryBase DirectoryObjectSecurity DSA EastAsianLunisolarCalendar Encoder EncoderFallback EncoderFallbackBuffer Encoding EncodingProvider Enum EqualityComparer`1 EventInfo EvidenceBase FieldInfo FileSystemInfo FileSystemSecurity FormattableString Formatter GenericAce GenericAcl GenericSecurityDescriptor HashAlgorithm HMAC IdentityReference IsolatedStorage IsolatedStoragePermission IsolatedStoragePermissionAttribute KeyedCollection`2 KeyedHashAlgorithm KnownAce MarshalByRefObject MaskGenerationMethod MD5 MemberInfo MethodBase MethodInfo Module MulticastDelegate NativeObjectSecurity ObjectAccessRule ObjectAuditRule ObjectSecurity ObjectSecurity`1 OrderablePartitioner`1 Partitioner`1 PropertyInfo QualifiedAce RandomNumberGenerator RC2 ReadOnlyCollectionBase RealProxy ReflectionContext Rijndael RIPEMD160 RSA SafeBuffer SafeHandle SafeHandleMinusOneIsInvalid SafeHandleZeroOrMinusOneIsInvalid SecurityAttribute SecurityState SerializationBinder SHA1 SHA256 SHA384 SHA512 Stream StringComparer SymmetricAlgorithm TaskScheduler TextReader TextWriter TimeZone TripleDES Type TypeInfo ValueType WaitHandle ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 12:23 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVostt... в общепринятой терминологии.Ну говорю же - детский сад. Нет никакой "общепринятой терминологии". Есть стандарты имеющие конкретные наименования: ГОСТ, СНИП, ANSI, ISO и т. п. Всё остальное - чьё-то субъективное мнение. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 12:23 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Алексей КhVostt... в общепринятой терминологии.Ну говорю же - детский сад. Нет никакой "общепринятой терминологии". Есть стандарты имеющие конкретные наименования: ГОСТ, СНИП, ANSI, ISO и т. п. Всё остальное - чьё-то субъективное мнение. :-) ГОСТ нам спустили с неба в виде скрижалей? ISO переведено с найденных манускриптов племени Майя? ANSI это научная аксиома. СНИП от инопланетян. А всё остальное.. ну да, мы поняли Уведите пациента в палату №6 ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 13:02 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVostt ГОСТ нам спустили с неба в виде скрижалей? ISO переведено с найденных манускриптов племени Майя? ANSI это научная аксиома. СНИП от инопланетян. Это общепринятые системы рекомендованные/навязанные всем заинтересованным. Сфера их применения выходит далеко за границы отдельно взятой небольшой шаражки. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 14:44 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВЭто общепринятые системы рекомендованные/навязанные всем заинтересованным. Сфера их применения выходит далеко за границы отдельно взятой небольшой шаражки. Т.е. всеми приказами, регламентами и распоряжениями отдельно взятой шаражки можно попу подтереть? Это ведь не ГОСТ и не ISO какое-то, так? Приходишь однажды в такую контору, и тебе говорят, — ты это.. код пиши по настроению, ясно тебе? Но чтобы название классов отражало суть и всем было всё понятно, окэй? Ну и чтобы модифировать было легко. Вот как-то так. Потом проходит время и какой-нибудь Алексей К смотри в код, и говорит что ему нехрена не понятно, и что вот эти названия совсем не отражают суть, потому что твои зелёные фломастеры ему кажутся синими. И ему совсем не кажется, что твой код легко модифицировать. И как он это объясняет? А вот так: я художник, я так вижу. В общем, детский сад, как он есть. Во всей красе. Ага. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 15:39 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVostt, Нафига придумывать свои "стайлгайде", отличные от общепринятых изначально, идущих от МС? Любой .NET программист привык к ним. Нафига вкрячивать слово Abstract? Ну префикс "A" еще куда не шло. Как бы ты назвал тот же Stream или TextReader? А серьезная бизнес-модель и иерархия наследования не предок-потомок? Типа Код: c# 1. 2. 3. 4.
или сложнее? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 17:56 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВНафига придумывать свои "стайлгайде", отличные от общепринятых изначально, идущих от МС? Где я такое говорил? Они вообще-то на них и базируются. ЕвгенийВЛюбой .NET программист привык к ним. Не любой, переучки (из делфи, java, C/C++...) ещё какое-то время создают локальный пздц в коде, пока не идут на поправку :) ЕвгенийВНафига вкрячивать слово Abstract? Ну префикс "A" еще куда не шло. Никто не вкорячивает слово Abstract, речь шла только о суффиксе Base. Если ты про пример, где класс называется SomeAbstract, это просто пример наименования класса, но я нигде не говорил, что это приставка какая-то. ЕвгенийВКак бы ты назвал тот же Stream или TextReader? Так бы и назвал. Хотя касательно Stream это величайшей фейл Microsoft. Нужен был интерфейс IStream, а не базовый класс. Это просто мега-отвратительное решение. А ещё лучше IReadStream и IWriteStrem, но уже поздно. ЕвгенийВили сложнее? В общем, не выдумывай. Я русскими словами описал наш стайл по поводу наименования базовых классов. Если класс выступает контрактом, никаких префиксов-суффиксов не предусмотрено. Если класс выступает только как базовая реализация и не фигурирует в контрактах, то используется суффикс Base. Смысл и польза от этого — достаточно очевидные. Как говорится, есть две самые страшные проблемы в программировании: придумывать имена переменных и инвалидировать кеш ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 18:08 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVostt Так бы и назвал. Хотя касательно Stream это величайшей фейл Microsoft. Нужен был интерфейс IStream, а не базовый класс. Это просто мега-отвратительное решение. А ещё лучше IReadStream и IWriteStrem, но уже поздно. Что тут то не так? Чем плох старина Stream? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 18:46 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВЧто тут то не так? Чем плох старина Stream? Тем, что требуется вынужденно наследоваться от класса, ты не можешь просто взять и реализовать интерфейс IStream, тебе придётся как минимум реализовать лишний адаптер. Чаще всего потоки используются только на чтение или только на запись, а клиентам теперь приходится лишний раз проверять Stream, умеет ли он то, что от него требуется (CanRead, CanWrite, CanSeek), вместо того, чтобы выяснить это ещё на стадии компиляции (IReadStream / IWriteStream / ISeekStream). ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 19:09 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVostt, То, что нечто реализует например IReadStream - не означает, что в рантайме сможем читать. Да и при введении тех же тасков, потребовалось переписать только 1 класс! А так, был бы IReadStream, от него отнаследовали бы IReadStreamAsync, и пришлось реализовывать всех потомком IReadStream, добавив им асинхронности. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 19:26 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВТо, что нечто реализует например IReadStream - не означает, что в рантайме сможем читать. Именно это и означает :) А если не сможем, то это очевидно ошибка. ЕвгенийВДа и при введении тех же тасков, потребовалось переписать только 1 класс! А так, был бы IReadStream, от него отнаследовали бы IReadStreamAsync, и пришлось реализовывать всех потомком IReadStream, добавив им асинхронности. А если твой стрим тупо не поддерживает асинхронный режим? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.07.2017, 19:58 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttЕвгенийВЧто тут то не так? Чем плох старина Stream? Тем, что требуется вынужденно наследоваться от класса, ты не можешь просто взять и реализовать интерфейс IStream, тебе придётся как минимум реализовать лишний адаптер. Чаще всего потоки используются только на чтение или только на запись, а клиентам теперь приходится лишний раз проверять Stream, умеет ли он то, что от него требуется (CanRead, CanWrite, CanSeek), вместо того, чтобы выяснить это ещё на стадии компиляции (IReadStream / IWriteStream / ISeekStream). Зелено ещё. Так делать точно не надо. Почитай "Entity interface anti-pattern". Во первых - возвращаясь к теме топика "ИЧитатПоток" странное имя. Логичнее уж IInputStream/IOutputStream Во вторых, продолжу "Архитектуру". Добавим для примера "способность" асинхронного чтения: IAsyncReadStream, IAsyncWriteStream. Теперь добавим для примера "способность" прерывать асинхронное чтение: IInterruptableStream. Вот насоздавали кучу интерфайсов. Попробуем их использоват. Пусть у нас метод, который получает как параметр поток, который одновременно IAsyncReadStream, IInterruptableStream, ISeekStream. Описать его одним интерфейсом не получится. Значит создадим комбинации: I[Random | Sequential][Async | Interruptable | Blocking] [Read | Write] Stream. Теперь можно описать параметр метода одним интерфейсом IRandomInterruptableAsyncReadStream. Вспотел? Проблема дизайна очевидна: создавая для каждого "свойства" свой интерфейс мы будем каждый раз умножать кол-во интерфейсов и при этом писать кучу "невыполняемого" бесполезного кода в угоду "архитектуре", при этом полностью теряя из вида что архитектура является не самоцелью а только методом. Ирония так же в том, что в итоге мы всё это просто выкинем, просто потому что некоторые свойства которые мы описали интерфейсами динамические и зависят от времени выполнения. К примеру тот-же поток. Под одним и тем же путём может быть и файл и канал. Но заметь, реализация у нас будет только одна FileStream. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 00:11 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikronПочитай "Entity interface anti-pattern". Не к месту. mikronВо первых - возвращаясь к теме топика "ИЧитатПоток" странное имя. Логичнее уж IInputStream/IOutputStream Логичнее, согласен, мне просто лень было набирать IReadableStream, так что придирка мимо. mikronЗначит создадим комбинации: I[Random | Sequential][Async | Interruptable | Blocking] [Read | Write] Stream. И в чём проблема оставить базовый класс Stream, наследующий все интерфейсы? И нашим и вашим. Такой подход активно практикуется Microsoft, посмотри на фильтры ASP.NET MVC. mikronТеперь можно описать параметр метода одним интерфейсом IRandomInterruptableAsyncReadStream. Вспотел? Нет, не вспотел. Серебряной пули не существует, но это не значит, что невозможно найти разумный компромисс. mikronПроблема дизайна очевидна: создавая для каждого "свойства" свой интерфейс мы будем каждый раз умножать кол-во интерфейсов Это не проблема, это расширяемость. Видеть в расширяемости проблему, это гениально. mikronи при этом писать кучу "невыполняемого" бесполезного кода в угоду "архитектуре", при этом полностью теряя из вида что архитектура является не самоцелью а только методом. Как раз таки наоборот. Если мне нужен поток только для чтения, я реализую такой поток, за каким хреном мне надо реализовывать +100500 доп. методов бросая NotImplementedException? Нахрена мне этот мусорный балласт? mikronИрония так же в том, что в итоге мы всё это просто выкинем, просто потому что некоторые свойства которые мы описали интерфейсами динамические и зависят от времени выполнения. К примеру тот-же поток. Под одним и тем же путём может быть и файл и канал. Если я принимаю поток только для чтения, мне всё равно что там, файл или канал, или ещё что-то. Главное чтобы он мог читать. Что мне даст во времени выполнения возможность файла ещё и писать, а канала только читать, если мне нужно только чтение изначально? Тут ты за уши притянул лишнего :) Пока что не убедительно. Рано говорить «зелено». ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 09:17 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttХотя касательно Stream это величайшей фейл Microsoft. Нужен был интерфейс IStream, а не базовый класс. Это просто мега-отвратительное решение. А ещё лучше IReadStream и IWriteStrem, но уже поздно. hVosttИ в чём проблема оставить базовый класс Stream, наследующий все интерфейсы? И нашим и вашим. Вспомнился детский анекдот советских времен. Бабушка дает свидетельские показания в суде: - Ну, иду значит по лесу, грибочки собираю, смотрю, в кустах - эти двое еб*тся... - (судья перебивает) Свидетель, не "еб*тся" а "сношаются" - А, ладно, иду значит по лесу, грибочки собираю, смотрю, в кустах - эти двое сношаются, пригляделась - еб*тся! ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 09:29 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
LRВспомнился детский анекдот советских времен. Бабушка дает свидетельские показания в суде: - Ну, иду значит по лесу, грибочки собираю, смотрю, в кустах - эти двое еб*тся... - (судья перебивает) Свидетель, не "еб*тся" а "сношаются" - А, ладно, иду значит по лесу, грибочки собираю, смотрю, в кустах - эти двое сношаются, пригляделась - еб*тся! Я говорил про замену контракта со Stream на I***Stream, а не убрать класс Stream вовсе. Так что анекдот из разряда, услышал звон, да не знаю где он. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 09:32 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttЯ говорил про замену контракта со Stream на I***Stream, а не убрать класс Stream вовсе. Так что анекдот из разряда, услышал звон, да не знаю где он. mikronПусть у нас метод, который получает как параметр поток, который одновременно IAsyncReadStream, IInterruptableStream, ISeekStream. Описать его одним интерфейсом не получится. Что дальше? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 09:36 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
LRЧто дальше? Элементарно, Ватсон Код: c# 1. 2. 3. 4.
Дайте уже разумные аргументы ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 09:49 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttЭлементарно, Ватсон Что ж, замечательно, согласен.)) Однако, касательно "Stream это величайшей фейл Microsoft. Нужен был интерфейс IStream, а не базовый класс" нужно заметить, что в те далекие времена дженериков еще не было - ничего другого Microsoft-у не оставалось. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 10:01 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttLRЧто дальше? Элементарно, Ватсон Код: c# 1. 2. 3. 4.
Дайте уже разумные аргументы Ограничение отписать легко, а вот кто и когда реализует TStream? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 10:31 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttИменно это и означает :) А если не сможем, то это очевидно ошибка. Если Барак Обама перегрыз провод и не льются байты - это не ошибка, это авария. hVostt А если твой стрим тупо не поддерживает асинхронный режим? Тупо синхронно выполниться метод имеющий асинхронную сигнатуру. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 10:39 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttmikronВо первых - возвращаясь к теме топика "ИЧитатПоток" странное имя. Логичнее уж IInputStream/IOutputStream Логичнее, согласен, мне просто лень было набирать IReadableStream, так что придирка мимо. vHost, скажи, как можно вести с тобой разумную полемику если ты просто из упёртости отрицаеш даже те аргументы с кототрыми сам соглашаешся? Судя по твоим ответам ты не понял. hVosttmikronЗначит создадим комбинации: I[Random | Sequential][Async | Interruptable | Blocking] [Read | Write] Stream. И в чём проблема оставить базовый класс Stream, наследующий все интерфейсы? И нашим и вашим. Такой подход активно практикуется Microsoft, посмотри на фильтры ASP.NET MVC. Вот именно это и проблема "Entity interface anti-pattern". Куча интерфеийсов и только одна реализация. Твой аргумент - ссылка на авторитеты говорит так-же против - МС не сделала ненужные интерфейсы. hVosttНет, не вспотел. Серебряной пули не существует, но это не значит, что невозможно найти разумный компромисс. mikronПроблема дизайна очевидна: создавая для каждого "свойства" свой интерфейс мы будем каждый раз умножать кол-во интерфейсов Это не проблема, это расширяемость. Видеть в расширяемости проблему, это гениально. Это не расширяемость а пустая трата ресурсов человеческих (на написание) и машинных (при выполнении). Что даст специално для под кокнретный набор своиств заточенный интерфеис? Ведь всегда можно использовать надмножество. hVosttmikronи при этом писать кучу "невыполняемого" бесполезного кода в угоду "архитектуре", при этом полностью теряя из вида что архитектура является не самоцелью а только методом. Как раз таки наоборот. Если мне нужен поток только для чтения, я реализую такой поток, за каким хреном мне надо реализовывать +100500 доп. методов бросая NotImplementedException? Нахрена мне этот мусорный балласт? Это экономически обоснованно: В 99.99 % случаев потоки не преопределяются. И значит болшинство не тянет ненужный баласт в виде интерфейсов. А в 0.01% случаев если потребуется реализовывать свой "поток" эти расходы приемлемы и оправданы. hVosttmikronИрония так же в том, что в итоге мы всё это просто выкинем, просто потому что некоторые свойства которые мы описали интерфейсами динамические и зависят от времени выполнения. К примеру тот-же поток. Под одним и тем же путём может быть и файл и канал. Если я принимаю поток только для чтения, мне всё равно что там, файл или канал, или ещё что-то. Главное чтобы он мог читать. Что мне даст во времени выполнения возможность файла ещё и писать, а канала только читать, если мне нужно только чтение изначально? Тут ты за уши притянул лишнего :) Или ты недопонял. Если тебе нужен поток для чтения и с позиционированием ты не сможеш этого гарантировать ни какими контрактами на этапе компиляции, так-как доступные интерфейсы определяются только во время выполнения. Но это доступно в других ОО подчодах, например в COM. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 10:41 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikronЕсли тебе нужен поток для чтения и с позиционированием ты не сможеш этого гарантировать ни какими контрактами на этапе компиляции, так-как доступные интерфейсы определяются только во время выполнения. Решение было приведено выше . ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 11:08 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
LRЧто ж, замечательно, согласен.)) Однако, касательно "Stream это величайшей фейл Microsoft. Нужен был интерфейс IStream, а не базовый класс" нужно заметить, что в те далекие времена дженериков еще не было - ничего другого Microsoft-у не оставалось Ну с коллекциями-то они порешали. Хоть и не идеально, но хорошо. Почему то, что верно для коллекций, коллекций с количеством, коллекций с индексацией, коллекцией с возможностью добавления/удаления и т.д. это верно, а для стримов вдруг неверно? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 11:57 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВОграничение отписать легко, а вот кто и когда реализует TStream? Реализует поставщик стримов. Реализует именно те интерфейсы, которые имеют смысл. Остальные нет. Для чтения потока данных из сети, очевидно не будет Seek и Write. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 11:58 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВТупо синхронно выполниться метод имеющий асинхронную сигнатуру. В то время, когда ты ожидаешь именно асинхронного поведения и не хочешь блокировать поток? Ну-ну :) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 11:59 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikronvHost, скажи, как можно вести с тобой разумную полемику если ты просто из упёртости отрицаеш даже те аргументы с кототрыми сам соглашаешся? Давай без демагогии? mikronВот именно это и проблема "Entity interface anti-pattern". Куча интерфеийсов и только одна реализация. Твой аргумент - ссылка на авторитеты говорит так-же против - МС не сделала ненужные интерфейсы. Куча интерфейсов далеко не одна реализация. В этом и смысл. Так что мимо опять. mikronЭто не расширяемость а пустая трата ресурсов человеческих (на написание) и машинных (при выполнении). Не вижу пояснений. Небо зелёное. mikronТвой аргумент - ссылка на авторитеты говорит так-же против - МС не сделала ненужные интерфейсы. Ничего подобного не наблюдаю, что бы подтверждало твой тезис. mikronВ 99.99 % случаев потоки не преопределяются. И значит болшинство не тянет ненужный баласт в виде интерфейсов. Откуда статистика? Мой опыт показывает обратное. Недавно реализовывал сервер WebDAV, жутко плевался на необходимость реализации нужного Stream отдельным классом и кучи NotImplementedException. Так что не надо выдумывать какую-то фигню. mikronА в 0.01% случаев если потребуется реализовывать свой "поток" эти расходы приемлемы и оправданы. Не выдумывай. Взял какие-то глупые проценты и потолка и пытаешься пихнуть их мне в виде аргументов. Совсем что ли за дураков людей держишь?? mikronЕсли тебе нужен поток для чтения и с позиционированием ты не сможеш этого гарантировать ни какими контрактами на этапе компиляции, так-как доступные интерфейсы определяются только во время выполнения. Чё ты несёшь? Если мне нужен IReadableStream, а компонент его не реализует, то будет ошибка компиляции. Если ошибки компиляции не будет, значит я ожидаю, что компонент реализует нужный мне интерфейс и ничего в рантайме чекать мне не придётся. mikronНо это доступно в других ОО подчодах, например в COM. Не знаю к чему ты упомянул COM. Ну ладно, он воплощает идеи ООП. И что? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:07 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
Когда мы обсуждаем базовые классы то в целом понятно, название должно отражать функционал. А если мы наследуемся от базового класса, и создаем класс с прикладной логикой? Что-то вроде FileSearchStream? По сути смысл указания в названии, что он CanRead и CanSeek теряет всякий смысл - не тащить же в название весь список методов и поддерживаемых интерфейсов? По сути стайлгайд в наименовании классов не может быть универсальным (не привязанным к конкретной системе) hVosttЯ говорил про замену контракта со Stream на I***Stream, а не убрать класс Stream вовсе. Почему бы не убрать вообще из всех классов параметры-классы и не оставить только интерфейсы? А к каждому классу в базовых библиотеках создать одноименный интерфейс? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:08 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
AddxА если мы наследуемся от базового класса, и создаем класс с прикладной логикой? Что-то вроде FileSearchStream? Твой пример мне говорит о том этот стрим только для чтения. Значит он должен реализовывать соответствующие интерфейсы. При чём тут наименование. Если он не умеет писать, у тебя даже не получится скомпилировать попытку записи. Это вин. Фейл, это забыть проверить CanWrite, и попытаться записать. Или проверить CanWrite и выбросить NotSupportedException, когда ты мог бы вообще этой фигнёй не заниматься изначально. AddxПо сути смысл указания в названии, что он CanRead и CanSeek теряет всякий смысл - не тащить же в название весь список методов и поддерживаемых интерфейсов? Это никак не кореллирует с названием классов. Мы говорим о контрактах. Ты либо хочешь читать из потока, либо писать в поток, либо то и другое. Плевать как называется класс, ты ведь получаешь ссылку на объект. AddxПочему бы не убрать вообще из всех классов параметры-классы и не оставить только интерфейсы? А к каждому классу в базовых библиотеках создать одноименный интерфейс? Не утрируй :) Говорим о конкретном фейле Microsoft. Интерфейсы головного мозга это тоже антипаттерн. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:12 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttЕвгенийВОграничение отписать легко, а вот кто и когда реализует TStream? Реализует поставщик стримов. Реализует именно те интерфейсы, которые имеют смысл. Остальные нет. Для чтения потока данных из сети, очевидно не будет Seek и Write. Попробуй реализовать обычный фаил ма диске. Какие интерфесы он будет реализовывать? И каие будут всегда работать? Ещё раз: контрактами на этапе компиляции невозможно гарантировать доступность интерфейса время выполнения. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:17 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttmikronТвой аргумент - ссылка на авторитеты говорит так-же против - МС не сделала ненужные интерфейсы. Ничего подобного не наблюдаю, что бы подтверждало твой тезис. Так посмотри же на класс Stream и FileStream. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:20 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikronПопробуй реализовать обычный фаил ма диске. Какие интерфесы он будет реализовывать? И каие будут всегда работать? При чём тут твой файл на диске? стандартный класс Stream реализует хоть что-то? читает файл с диска? Считаешь, что твой поток, реализующий доступ к файлу может как читать, так и писать, реализуй все интерфейсы. В чём твоя проблема? Вопрос контракта заключается не в том, как и что ты реализуешь, а как ты обеспечишь соблюдение договорённостей. Я хочу ТОЛЬКО читать из потока. В методе ты видишь, что он принимает Stream. А я хочу, чтобы ты вообще не мог сунуть объект потока, который не умеет читать. Чтобы потом не ловить ошибки в рантайме. Нафига? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:24 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttmikronЕсли тебе нужен поток для чтения и с позиционированием ты не сможеш этого гарантировать ни какими контрактами на этапе компиляции, так-как доступные интерфейсы определяются только во время выполнения. Чё ты несёшь? Если мне нужен IReadableStream, а компонент его не реализует, то будет ошибка компиляции. Если ошибки компиляции не будет, значит я ожидаю, что компонент реализует нужный мне интерфейс и ничего в рантайме чекать мне не придётся. Вот ты исползуеш FileStream как реализуюший класс. Никаких проверок в коде. Компилируется. Но во время работы программы создаётс FileStream для пути по которому находится файл/пайп в кототрый можно только писать. Очевидно что весь код болле не рабочий и твой "архитектурные" испражнения ни к чему не видут. Нужна всё та же проверка в коде IsReadable. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:30 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikronВот ты исползуеш FileStream как реализуюший класс. Никаких проверок в коде. Компилируется. Но во время работы программы создаётс FileStream для пути по которому находится файл/пайп в кототрый можно только писать. Очевидно что весь код болле не рабочий и твой "архитектурные" испражнения ни к чему не видут. Нужна всё та же проверка в коде IsReadable. И что твой код, который собрался писать в файл, будет делать в таком случае? В моём он получит эксепшен, не хватает каких-то прав доступа. Нельзя дальше работать, исключительная ситуация. Я просил объект потока, в который я собираюсь писать. Мне пофигу по каким причинам, это сделать не получилось. В общем, пример никак не аргументирует и не защищает твою позицию. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:34 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikron, Возьмём вот этот метод WebClient.OpenRead . Возвращает поток для чтения. Будешь проверять CanRead? Или сразу будешь читать? А если CanRead вернул false? А писать в поток будешь? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:37 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttmikronВот ты исползуеш FileStream как реализуюший класс. Никаких проверок в коде. Компилируется. Но во время работы программы создаётс FileStream для пути по которому находится файл/пайп в кототрый можно только писать. Очевидно что весь код болле не рабочий и твой "архитектурные" испражнения ни к чему не видут. Нужна всё та же проверка в коде IsReadable. И что твой код, который собрался писать в файл, будет делать в таком случае? В моём он получит эксепшен, не хватает каких-то прав доступа. Нельзя дальше работать, исключительная ситуация. Я просил объект потока, в который я собираюсь писать. Мне пофигу по каким причинам, это сделать не получилось. В общем, пример никак не аргументирует и не защищает твою позицию. откудого у тебя возникнет эксепшен? Может кто то всё-же будет делать проверки? hVosttзначит я ожидаю, что компонент реализует нужный мне интерфейс и ничего в рантайме чекать мне не придётся. Значит всё-таки твой интерфейс ничего не гарантирует. Значит нет в нём ползы. Исползуй базовый класс Stream. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:44 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttНу с коллекциями-то они порешали. Хоть и не идеально, но хорошо. Почему то, что верно для коллекций, коллекций с количеством, коллекций с индексацией, коллекцией с возможностью добавления/удаления и т.д. это верно, а для стримов вдруг неверно? Может быть поэтому? [Serializable] public abstract class CollectionBase : IList, ICollection,IEnumerable [SerializableAttribute] [ ComVisibleAttribute(true) ] public abstract class Stream : MarshalByRefObject , IDisposable ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:53 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttmikron, Возьмём вот этот метод WebClient.OpenRead . Возвращает поток для чтения. Будешь проверять CanRead? Или сразу будешь читать? А если CanRead вернул false? А писать в поток будешь? Ответ на твой вопрос не однозначен, но в обшем случае я не буду делать никаких проверок. Это только подчёркивает что нет смысла плодить интерфейсы IReadStream. Базового класса Stream kak это делает МС достаточно. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:56 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttЧаще всего потоки используются только на чтение или только на запись, а клиентам теперь приходится лишний раз проверять Stream, умеет ли он то, что от него требуется (CanRead, CanWrite, CanSeek), вместо того, чтобы выяснить это ещё на стадии компиляции (IReadStream / IWriteStream / ISeekStream). Надеёсь мы прояснили, что на этапе компиляции этого нелзя выяснит? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 12:59 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
LR[ ComVisibleAttribute(true) ] public abstract class Stream : MarshalByRefObject , IDisposable Похоже, именно поэтому. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 13:00 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikronоткудого у тебя возникнет эксепшен? Может кто то всё-же будет делать проверки? У тебя метод есть, загружающий данные из потока. Что тебе даст чтение CanRead? Скажет только, что о том, что поток не читабельный. А почему не скажет. Чтобы выяснить почему, надо всё таки попробовать выполнить чтение и надеяться на то, что в исключении будет больше информации. Будет ещё прикольней, если CanRead бросит исключение ))) Или CanRead вернёт false, а сам поток при этом вполне читабельный. Жопа короче. mikronЗначит всё-таки твой интерфейс ничего не гарантирует. Значит нет в нём ползы. Исползуй базовый класс Stream. Интерфейс это контракт. Контракт это гарантии. Гарантирует. Если нет, то всеми контрактами можно подтереться. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 13:03 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikronОтвет на твой вопрос не однозначен, но в обшем случае я не буду делать никаких проверок. А почему? Там ведь может быть стрим, который не умеет читать, а только писать. mikronЭто только подчёркивает что нет смысла плодить интерфейсы IReadStream. Базового класса Stream kak это делает МС достаточно. Я понял, твой единственный аргумент это авторитет Microsft. Раз MS так решила, значит это самый верный путь. Всё ясно. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 13:05 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikronhVosttЧаще всего потоки используются только на чтение или только на запись, а клиентам теперь приходится лишний раз проверять Stream, умеет ли он то, что от него требуется (CanRead, CanWrite, CanSeek), вместо того, чтобы выяснить это ещё на стадии компиляции (IReadStream / IWriteStream / ISeekStream). Надеёсь мы прояснили, что на этапе компиляции этого нелзя выяснит? Не выдумывай. На этапе компиляции выясняется соответствие интерфейсов. Т.е. выполнение контрактов, которые гарантируют соответствующую реализацию. Если что-то не реализовано по контракту, это ошибка разработчика, он идёт и исправляет её. Или ошибка глубже, например, сетевая ошибка, ошибка файловой системы. Сам контракт гарантирует реализацию, а не правильную реализацию. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 13:07 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVostt, Я устал, я умолкаю ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 14:11 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVosttОткуда статистика? Мой опыт показывает обратное. Недавно реализовывал сервер WebDAV, жутко плевался на необходимость реализации нужного Stream отдельным классом и кучи NotImplementedException. Так что не надо выдумывать какую-то фигню. 9 лет назад тоже делал WebDAV, не представляю, нафига там нужен свой Stream.... И да, друг мой Хвост, умные люди читают из потока используя например BinaryReader. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 15:02 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
mikronhVostt, Я устал, я умолкаю Ну ок :) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 15:03 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВ9 лет назад тоже делал WebDAV, не представляю, нафига там нужен свой Stream.... WebDAV представляет виртуальную файловую систему. В нашем случае, на деле ни файлов, ни каталогов не существует, они для каждого пользователя свои. Пользователи работают с файлами, открывая их и копируя, это реализовывается через сетевой интерфейс, который работает с потоками. ЕвгенийВИ да, друг мой Хвост, умные люди читают из потока используя например BinaryReader. А конструктор BinaryReader что по-твоему принимает? Тот же Stream. Который хрен ещё его знает, умеет читать или нет. Узнаешь потом. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 15:08 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
hVostt WebDAV представляет виртуальную файловую систему. В нашем случае, на деле ни файлов, ни каталогов не существует, они для каждого пользователя свои. Пользователи работают с файлами, открывая их и копируя, это реализовывается через сетевой интерфейс, который работает с потоками. Если проводник windows может выступать клиентом WebDAV, не значит, что WebDAV "представляет виртуальную файловую систему (с)". WebDAV - расширение HTTP и может и используется (в microsoft exchange) например для доступа к почте. hVostt А конструктор BinaryReader что по-твоему принимает? Тот же Stream. Который хрен ещё его знает, умеет читать или нет. Узнаешь потом. Это да, но он и сделает все проверки, которые лень делать простому программисту :) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 15:42 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВЕсли проводник windows может выступать клиентом WebDAV, не значит, что WebDAV "представляет виртуальную файловую систему (с)". WebDAV - расширение HTTP и может и используется (в microsoft exchange) например для доступа к почте. RFC устроит? Web Distributed Authoring and Versioning (WebDAV) consists of a set of methods, headers, and content-types ancillary to HTTP/1.1 for the management of resource properties, creation and management of resource collections, URL namespace manipulation, and resource locking (collision avoidance). ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 16:19 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
ЕвгенийВЕсли проводник windows может выступать клиентом WebDAV, не значит, что WebDAV "представляет виртуальную файловую систему (с)". WebDAV - расширение HTTP и может и используется (в microsoft exchange) например для доступа к почте. Я вообще не понял к чему ты это сказал. У нас есть виртуальная файловая система, индивидуальная для каждого пользователя, мы предоставляем доступ к ней через WebDAV. Есть аналогичный доступ через веб интерфейс. При желании, можно замутить FTP интерфейс или ещё какой-нибудь. ЕвгенийВЭто да, но он и сделает все проверки, которые лень делать простому программисту :) То есть мало того, что я должен сделать отдельный класс, так как я не могу просто реализовать интерфейс читателя из потока, мне нужен отдельный класс. Я должен использовать ещё какой-то дополнительный класс, чтобы реализовать чтение из класса потока, который я сам же сделал. Не находишь, что это перебор? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 17:05 |
|
Нейминг базовых классов
|
|||
---|---|---|---|
#18+
А мне плевать. Я работаю в одиночку ... |
|||
:
Нравится:
Не нравится:
|
|||
20.07.2017, 21:41 |
|
|
start [/forum/topic.php?all=1&fid=20&tid=1399791]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
143ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
77ms |
get tp. blocked users: |
1ms |
others: | 287ms |
total: | 551ms |
0 / 0 |