Re[9]: FDG
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 26.11.10 07:44
Оценка:
Здравствуйте, samius, Вы писали:

S>Например, в одной из бетта версий (не помню конкретно которой) при кастинге массива в IList<T> получался полностью иммутабельный объект, т.е. через сеттер индексатора IList<T> изменить содержимое массива было нельзя. Однако в документации той же беты было упоминание о том, что не стоит в дальнейшем рассчитывать на такое поведение. Причин отказа от этого решения я не знаю.


О, вот это решение кажется наиболее консистентным.
Re[8]: FDG
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 26.11.10 11:24
Оценка: :))
Здравствуйте, _FRED_, Вы писали:

_FR>Если вы открыто высказываете мнение об ошибках проектироващиков, но при этом не в курсе, как проктировалось осуждаемое вами и почему оно именно такое — то не оскоррбляться надо, когда вам рассказывают, как дело было и почему и зачем вышло так,


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

"а мотать на ус, испытывая чувство благодарности за то, что кто-то тратит время, рассказывая вам то, что вы ранее не знали"

Здесь не тот случай, что кто то чего то не знает, а наоборот, знают и более того, имеют свое мнение.

А ты вот объяснений внятных дать не можешь, внятно покритиковать — тоже не можешь.

Вобщем испытывай чувство благодарности когда ктото тратит своё время показывая тебе упущения в ведении дискуссии
Re[9]: int[].Add
От: vitasR  
Дата: 01.12.10 06:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>думаю, проблема в другом — вы мыслите с точки зрения программиста, а я пользователя


"пользователь массива" — это звучит гордо!
Re[10]: int[].Add
От: Мишень-сан  
Дата: 01.12.10 09:59
Оценка:
Здравствуйте, vitasR, Вы писали:

R>Здравствуйте, Аноним, Вы писали:


А>>думаю, проблема в другом — вы мыслите с точки зрения программиста, а я пользователя


R>"пользователь массива" — это звучит гордо!


"А ты веришь в Пользователей?" (с)
Re: int[].Add
От: henson Россия http://www.njt-rails.com
Дата: 01.12.10 16:21
Оценка:
Здравствуйте, Аноним, Вы писали:

А>вот такой код



А>
А>IList<int> arr = new int[10];
А> arr.Add(5);
А>



А>кто мне объяснит зачем мне доступен метод Add, который всегда будет кидать эксепшн?


Интерфейс объявил этот метод вот он и доступен. Декларативное описание не предполагает устранение эксепшенов в рантайме.
Re[4]: FDG
От: 0x7be СССР  
Дата: 01.12.10 16:24
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Это способ избавиться от комбинаторного взрыва.

Это плохой способ избавиться от комбинаторного взрыва.
Он говорит о том, что имеются расфокусированные абстракции.
Re: int[].Add
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 20:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>вот такой код


А>
А>IList<int> arr = new int[10];
А> arr.Add(5);
А>


А>кто мне объяснит зачем мне доступен метод Add, который всегда будет кидать эксепшн?


Чтобы ты знал как будут о тебе думать, если ты будешь так же проектировать свое ПО .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: int[].Add
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 20:32
Оценка:
Здравствуйте, adontz, Вы писали:

А>>кто мне объяснит зачем мне доступен метод Add, который всегда будет кидать эксепшн?


A>А какова альтернатива?


Проектировать по грамотно. Не вводить не нужных методов в интерфейсы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: int[].Add
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 20:33
Оценка:
Здравствуйте, adontz, Вы писали:

A>И как вы предлагаете это реализовать? IList<> может быть поиницилизирован очень далеко, вообще в другом модуле. С какой стати компилятору запрещать вам вызывать метод?


Запрещать нужно не компилятору, а работодателю... нанимать тех кто проектирует такие интерфейсы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: int[].Add
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 20:38
Оценка: +1
Здравствуйте, adontz, Вы писали:

S>>Я тоже считаю что в интерфейсах коллекций бардак. Другое дело — я привык к нему. Предлагать ничего не буду, не готов прямо сейчас, да и бестолку это. Но уверен, что можно было сделать лучше.


A>Без множественного наследования — нельзя.


Для справки: в дотнете для интерфейсов поддерживается множественное наследование. Ну, а интерфейс нужно было проектировать примерно так:
interface IList<T>
{
  члены для чтения данных
}
interface IMutableList<T> : IList<T>
{
  члены для изменения данных
}

Заметь, даже множественное наследование не понадобилось. Хотя можно было и его заюзать.

ЗЫ

Ром, странно от тебя слышать такое.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: int[].Add
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 20:46
Оценка:
Здравствуйте, samius, Вы писали:

S>Впрочем, можно было бы сделать аналог QueryInterface, который бы в динамике решал, возвращать ли или нет запрашиваемую грань.


Это и делать не надо. Есть механизм динамического запроса интефрейсов (динамическое приведение типов). От одного интерфейса всегда можно попросить другой даже если между ними нет никакой связи (пример на шарпе):
interface IList2
{
  this[int index] { get; }
}

interface IMutableList2
{
  this[int index] { get; set; }
}

class MyLis2 : IMutableList2, IList2 { ... }

...

IList2 lst = new MyLis2();

IMutableList2 mutableLst = (IMutableList2)lst;
...
// или с проверкой

var mutableLst = lst as IMutableList2;

if (mutableLst != null)
  ...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: int[].Add
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.12.10 21:34
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, samius, Вы писали:


S>>Впрочем, можно было бы сделать аналог QueryInterface, который бы в динамике решал, возвращать ли или нет запрашиваемую грань.


VD>Это и делать не надо. Есть механизм динамического запроса интефрейсов (динамическое приведение типов). От одного интерфейса всегда можно попросить другой даже если между ними нет никакой связи (пример на шарпе):


Речь шла о том что коллекция меняет свою мутабельность в динамике. Вот я и вспомнил, про IUnknown.QueryInterface. Правда в COM AFAIR были законы по поводу QE, что в рантайме набор поддерживаемых интерфейсов не меняется для объекта.
Re[15]: int[].Add
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.12.10 21:40
Оценка:
Здравствуйте, samius, Вы писали:

A>>Смысла в это всё равно нет, потому что я лично сам встречался со случаями когда коллекция ReadOnly/FixedSize иногда. Интерфейсами такое не обозначить.


S>Впрочем, можно было бы сделать аналог QueryInterface, который бы в динамике решал, возвращать ли или нет запрашиваемую грань.


Это фигня какая то Управление набором интерфейсов — вынос мозга.

Автор Design Guidelines пишет, что надо пользоваться например (obj is Array)

Вообще интерфейсы очень полезная штукенция, пустые интерфейсы это например аццки быстрый аналог атрибутов у класса.
Re[16]: int[].Add
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.12.10 21:45
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, samius, Вы писали:


A>>>Смысла в это всё равно нет, потому что я лично сам встречался со случаями когда коллекция ReadOnly/FixedSize иногда. Интерфейсами такое не обозначить.


S>>Впрочем, можно было бы сделать аналог QueryInterface, который бы в динамике решал, возвращать ли или нет запрашиваемую грань.


I>Это фигня какая то Управление набором интерфейсов — вынос мозга.

+1

I>Автор Design Guidelines пишет, что надо пользоваться например (obj is Array)

это по сути единственный выход, но он гарантирует решение лишь для массива. А что если мне нужно написать Array2?

I>Вообще интерфейсы очень полезная штукенция, пустые интерфейсы это например аццки быстрый аналог атрибутов у класса.

Да, но в том же Guidlines где-то написано что пустые интерфейсы использовать нежелательно. Что мне собственно не мешало их использовать.
Re[17]: int[].Add
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.12.10 22:52
Оценка:
Здравствуйте, samius, Вы писали:

S>Речь шла о том что коллекция меняет свою мутабельность в динамике.


Это где это?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[18]: int[].Add
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.12.10 22:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, samius, Вы писали:


S>>Речь шла о том что коллекция меняет свою мутабельность в динамике.


VD>Это где это?

здесь
Автор: adontz
Дата: 25.11.10
Re[9]: int[].Add
От: adontz Грузия http://adontz.wordpress.com/
Дата: 02.12.10 05:29
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Заметь, даже множественное наследование не понадобилось. Хотя можно было и его заюзать.


Я о множестве стандартных реализаций на все случаи жизни. Они, кстати, должны ещё уметь агрегировать друг друга, чтобы MutableList можно было кое-кому выдавать как ReadOnlyList. Экспоненциальный рост количестве классов получается без множественного наследования. Да и с них фигня входит в общем-то, но уже другого рода.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[10]: int[].Add
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.12.10 15:29
Оценка:
Здравствуйте, adontz, Вы писали:

A>Я о множестве стандартных реализаций на все случаи жизни. Они, кстати, должны ещё уметь агрегировать друг друга, чтобы MutableList можно было кое-кому выдавать как ReadOnlyList. Экспоненциальный рост количестве классов получается без множественного наследования. Да и с них фигня входит в общем-то, но уже другого рода.


Не выдумывай. Никакого экспоненциально роста не будет. Будте грамотный дизайн. А то что есть — это бардак.

В одном ты правл, уже вряд ли кто-то что-то станет менять.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: int[].Add
От: adontz Грузия http://adontz.wordpress.com/
Дата: 02.12.10 16:58
Оценка: 1 (1) -1
Здравствуйте, VladD2, Вы писали:

VD>Не выдумывай. Никакого экспоненциально роста не будет. Будте грамотный дизайн. А то что есть — это бардак.


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

Ладно, я сделаю эту работу за тебя. Для полноты картины и в назидание потомкам.

public interface IEnumerable<T>
{
    IEnumerator<T> GetEnumerator();
}

public interface ICollection<T> : IEnumerable<T>
{
    bool Contains(T item);
    bool CopyTo(T[] array, int arrayIndex);

    int Count {get;}
}

// Это ничего, что Clear Вместе с Add/Remove или ещё делить?
// Где обоснованная граница? Бывает же, что Add/Remove можно, а Clear - нельзя.
// А ещё бывает, что можно Add, но нельзя Remove.
public interface IMutableCollection<T> : ICollection<T>
{
    void Clear();
    void Add(T item);
    bool Remove(T item);
}

// Опять таки, всегда ли делать доступным IndexOf?
// Метод весьма сомнительный, в колелкции с неуникальными элементами вводит в заблуждение,
// лучше уж IList<int> IndicesOf(T item), но такой метод плох в коллекции с уникальными элементами.
public interface IList<T> : ICollection<T>
{
    int IndexOf(T item);

    T this[int index] { get; }
}

public interface IMutableAddRemoveList<T> : IList<T>, IMutableCollection<T>
{
    int Insert(int index, T item);
    bool RemoveAt(int index);
}

public interface IMutableModifyList<T> : IList<T>
{
    // Это полностью новое свойство, нельзя доопределить сеттер.
    T this[int index] { get; set; }
}

////////////////////////////////////////////////////////////////////////////////

// Реализация по умолчанию, как List<T>
public class MutableAddRemoveList<T> : IMutableAddRemoveList<T>
{
...
}

// Реализация по умолчанию, как List<T>
public class MutableModifyList<T> : IMutableModifyList<T>
{
...
}

// Реализация по умолчанию, как List<T>
// Copy+Paste их двух предыдущих классов.
public class MutableList<T> : IMutableAddRemoveList<T>, IMutableModifyList<T>
{
...
}


Уже три класса вместо одного, и двойное повторение кода. В два раза больше кода, полученного обычной копипастой. Сомнительный признак хорошей архитектуры. И заметь, есть ещё куча возможностей улучшить архитектуру разбив интерфейсы на более мелкие! Теперь добавим сюда observable collections и разные другие фенечки и получим ещё одну волну увеличения количества классов и копий кода. В Си++ эта проблема решалась: MutableList<T> унаследовался бы от MutableAddRemoveList<T> и MutableModifyList<T>. В .Net эта проблема не решается непосредственно.

Кроме того, что делать с ситуациями, когда доступно операции величина не постоянная? Вот скажем у меня коллекция связана с каким-то хранилищем (БД или что-то ещё) и менять её (писать в хранилище) можно только наложив блокировку. То есть в каких-то случаях (когда блокировки нет) IsReadOnly вернёт true, а Add(T) выбросит InvalidOperationException, а в каких-то других случаях IsReadOnly вернёт false и Add(T) отработает штатно. Как такие сценарии сочетаются с идеей fine grained interfaces?

То есть, если резюмировать, то что ты предлагаешь вызывает бурный рост количества сущностей, кучу копирования кода при реализации коллекций и лишь частичное покрытие возможных сценариев.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[12]: int[].Add
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.12.10 17:25
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, VladD2, Вы писали:


VD>>Не выдумывай. Никакого экспоненциально роста не будет. Будте грамотный дизайн. А то что есть — это бардак.


A>Влад, если бы сам сел и внимательно расписал все классы, то не стал бы спорить. Впрочем с твоим опытом проектирования необходимости в ручке и бумаге быть не должно, так что ты меня попросту удивляешь.


A>Ладно, я сделаю эту работу за тебя. Для полноты картины и в назидание потомкам.


A>
A>public interface IMutableAddRemoveList<T> : IList<T>, IMutableCollection<T>
A>{
A>    int Insert(int index, T item);
A>    bool RemoveAt(int index);
A>}

A>public interface IMutableModifyList<T> : IList<T>
A>{
A>    // Это полностью новое свойство, нельзя доопределить сеттер.
A>    T this[int index] { get; set; }
A>}

A>////////////////////////////////////////////////////////////////////////////////

A>// Реализация по умолчанию, как List<T>
A>public class MutableAddRemoveList<T> : IMutableAddRemoveList<T>
A>{
A>...
A>}

A>// Реализация по умолчанию, как List<T>
A>public class MutableModifyList<T> : IMutableModifyList<T>
A>{
A>...
A>}

A>// Реализация по умолчанию, как List<T>
A>// Copy+Paste их двух предыдущих классов.
A>public class MutableList<T> : IMutableAddRemoveList<T>, IMutableModifyList<T>
A>{
A>...
A>}
A>


Это чушь какая-то. Зачем все эти классы? Если у нас скажем SCG.List<T> поддерживает индексированный доступ и изменение, то реализуем в нем IMutableList<T>. Если это скажем однонаправленный связанный список являющийся неизменяемой структурой данных, то реализуем в нем только ICollection<T> и т.д.

A>Уже три класса вместо одного, и двойное повторение кода. В два раза больше кода, полученного обычной копипастой.


Дык ты намеренно глупость же сделал.

A>СВ .Net эта проблема не решается непосредственно.


Да нет никакой проблем на самом то деле. Ты ее сам из пальца высосал.

В прочем, на самом деле нет особой нужды в Mutable-интерфейсах. Вот скажи, ты сам то часто на практике добавлял элементы через IList<T> или ICollection<T>? Я — ни разу. Когда коллекция заполняется, то обычно работа идет с конкретными типами. А вот кода мы ее передам в некий обработчик, то тут хорошо бы иметь дело с абстракцией. Но при этом обычно речь идет о чтении данных, а не об их изменении. По сему на практике в большинстве случаев достаточно IEnumerable<T>. Вот по этому то наличие всех этих лишних методов на практике особых проблем и не вызывает. Но это никак не доказывает необходимость наличия этих методов.

A>Кроме того, что делать с ситуациями, когда доступно операции величина не постоянная? Вот скажем у меня коллекция связана с каким-то хранилищем (БД или что-то ещё) и менять её (писать в хранилище) можно только наложив блокировку. То есть в каких-то случаях (когда блокировки нет) IsReadOnly вернёт true, а Add(T) выбросит InvalidOperationException, а в каких-то других случаях IsReadOnly вернёт false и Add(T) отработает штатно. Как такие сценарии сочетаются с идеей fine grained interfaces?


Это какая-то выдуманная фигня. Что ее разбирать то?

A>То есть, если резюмировать, то что ты предлагаешь вызывает бурный рост количества сущностей, кучу копирования кода при реализации коллекций и лишь частичное покрытие возможных сценариев.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.