All streams
Search
Write a publication
Pull to refresh
56
0

Пользователь

Send message
Как у вас реализован рендеринг, что у вас возникают большие задержки?

На практике даже на телефоне (Windows Phone) можно редактировать фотографии в 8Мп без значительных задержек с масштабированием и сохранением истории!

Посмотрите приложение Ease (Мольберт). Возможно, вам будут полезны исходные коды его прототипа. Используются стандартные примитивы xaml-разметки (например, Polyline), рендеринг которых выполняется встроенным видеоадаптером.

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

Конечно, функционал не такой богатый, как в десктоп-редакторах, но мощности ПК намного выше, чем в телефонах…
Утрированно провожу обратный эксперимент — что будет, если писать программы так, как строят дома, машины и переносить архитектурные аналогии из реального в виртуальный мир программирования.
Поддерживается и тестируется организм достаточно легко, а бонусом является мощнейшая система самодиагностики и восстановления. Изменяемость и подстраиваемость под внешние условия на очень высоком уровне. Такого остаётся только пожелать современным программам.

Но вы, конечно же, имеете ввиду внешнее вмешательство… Но тогда вам другой пример — автомобиль.

Автомобиль — набор деталей, каждая из которых выполняет свою функцию. Есть, конечно, второстепенные компоненты, которые можно выбросить, но в целом даже без одного колеса это неполноценный автомобиль. По вашей логике — в данной системе высокая связность, но, если это качесвенная машина, то тестируется и модифицируется она достаточно легко.
Да, художник, вы чертовски правы. И для меня программирование — и ремесло, и искусство. А вдохновение — окружающий мир.
Вы уверены, что хотите лезть в такие абстрактные дебри?

Что такое объект?

Этому понятию можно дать множество определений… Счётная конструкция, единица логического мышления, обладающая некоторым набором атрибутов. Множества объектов с аналагичным набором атрибутов образуют классы. Вот, кстати лекция интересная по безатрибутным моделям данных www.youtube.com/watch?v=Ioi68tNLmYw.
Ещё можете статью прочитать habrahabr.ru/post/250135.

Как вы решаете какие переменные и методы принадлежат одному объекту?

Объекты со сходным набором атрибутов и поведением, относящиеся к одному классу, по определению обладают одними и теми же методами и свойствами.
С чувством юмора у вас всё в порядке, так держать :)

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

В человеческом теле множество органов — каждый выполняет свою функцию (Single Responsibility), но вот друг без друга они функционировать не могут. Скажете, сильная связность, природа и миллионы лет эволюции плохой архитектор?

В окружающем мире множество аналогий, которые можно перенести в программирование. Возможно, вы посмеётесь над этим, но в устройстве мира достаточно красоты и стройности.
Вы думаете, что автору не доводилось видеть подобных решений до того момента, как делать другое? К слову AvalonDock, который используется в Poet, работает схоже, но ведь не на пустом месте возникли мысли сделать иначе. В ваших примерах сохранение и загрузка layout встроены в сам контрол, но как вы поступите, если у вас есть другой готовый контрол, который такой функциональности не поддерживает?

Насчёт тестов, если вы будете их писать, то вы изначально вызовете Expose у тестируемой вью-модели, а когда потребуется инжектировать в неё что-то ещё, то это никак не повлияет на результаты тестов тех методов, которые не связаны с новыми изменениями. Так что тут вы даже выигрываете.

Фреймворк прекрасно подходит для любых xaml-ориентированных приложений и покрывает очень большой круг задач.
Что ещё немаловажно, текущее решение является кроссплатформенным и вью-модели запросто разделяются между различными проектами, причём с различным UI. Насколько видоизменится ваше решение, если добавить ещё и такое условие?
Мне интересен реальный пример, оправдывающий такой overhead. Он у вас есть? Из проекта, из кода, чтобы без Exposable было сложнее, чем с ним.

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

Что касается наследования, то в подавляющем большинстве случаев вью-модели наследуются от BaseViewModel, как минимум, реализующей INotifyPropertyChanged, поэтому касательно этого вопроса критика не обоснована. Атрибуты плохи для сохранения UI-настроек, поскольку в сложных интерфейсах могут быть десятки свойств, а неявное их сохранение значительно лаконичнее и проще. Пример такого проекта — текстовый редактор Poet, можно взглянуть на служебные файлы с настройками и убедиться, что их там действительно много.

Насчёт инжекций в конструктор — долгий вопрос. Во-первых, конструктор часто не вызывается при десериализации. Во-вторых, стоит убрать или добавить параметр в конструктор, как ломаются тесты тех методов, которые вообще не связаны с этой логикой. Меня это очень бесило на некоторых проектах :) О каком удобстве тестирования тут можно говорить?

Если с какими-то пунктами критики по первой части (Renewable Unit) ещё соглашусь, то по второй у меня очень много аргументов в запасе. Тут нужно просто прочувствовать на практике насколько удобно всё организовано в предложенном фреймворке.
Используйте try-finally и никаких утечек точно не будет. Ровно также можно сказать, что в Disposble-паттерне открытые утечки, если не обернуть его в using, а ведь бывает и так! Но это же не повод не применять Disposable.
В данном случае речь идет не о мнении, а об аргументах.

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

Вы так и не смогли обосновать его необходимость.

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

По крайней мере существует сценарий совместного использования Expose/Dispose, который уже тесно перекликается со второй частью статьи. Например, дата-контракт сериализаторы, используемые для хранения состояния вью-моделей, не вызывают конструктора при создпании объекта (см. FormatterServices.GetUninitializedObject). Собственно из этого и родился паттерн Exposable. Если же ещё вью-модель имеет дело с unmaged-ресурсами, то очень логично использовать Dispose-метод, как минимум, в финализаторе. Но это уже спецефический случай, поэтому не привожу его в качестве примера.
Вы можете не принимать пример, но в нём не вижу ничего действительно опасного и нахожу более универсальным в плане использования. Хотя и ваш классический варинт хорош, поэтому не отрицаю его, как одно из решений.
Извиняюсь, но не обратил внимание на параметр в кострукторе. Подправьте немного и покроется ваш вариант.

    private readonly UserData _userData;

    public UserDataProvider(UserData userData)
    {
      _userData = userData;
       Expose();
    }


Вы, вероятно, придерживаетесь консервативного стиля в программировании, когда объект пишется под конкретный сценарий использования (using). Мне же ближе вариант, когда объект можно использовать в различных сценарях даже в самых неожиданных.

Я вас уже некоторое время прошу привести пример такой необходимости.

Да просто протестировать соединение с сервером (иногда бывает такая кнопка в некоторых приложениях). Мне не нравятся такие примеры, но можно динамически переоткрыть соединение в целях информационной безопасности.
Мою реализацию вы можете использовать точно таким же образом с помощью using, как и свою. Никаких дополнительных утечек, про которые вы говорите, в таком случае не будет. Если же нужно более тонкое управление поведением установки соединения, а порой возникает и такая необходимость, то ваша реализация не столь удобна. Понятно, что если действительно возникла такая необходимость в тонкой настройке, то разработчик должен понимать, что делает, чтобы получить от этого выигрыш, но даже в случае ошибки ничего очень серьёзного из-за этого не произойдёт.

То есть представленная реализация более универсальна и покрывает вашу. Но чтобы получить от этой универсальности выигрыш нужно просто понимать, как всё работает, а какой-то сверхсложной логики тут нет, поэтому разберётся даже начинающий разработчик. И такой способ имеет место быть.
… и мы вернемся к ситуации «что будет, если вызвать GetSomeData до вызова Expose».

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

А когда это произойдет для объекта, лежащего в сессии? Через полчаса после того, как пользователь покинет сайт? А сколько на сайте одновременных пользователей?

Нет ничего нерешаемого в данной ситуации, если это достаточно критично для приложения.

А смысл? Поведение между Expose/GetSomeData и просто GetSomeData ничем не отличается. Второе даже лучше, потому что сеодинение захватывается попозже.

С помощью вызовов Expose/Dispose можно более точно контролировать время жизни соединения, если это нужно. Более того так очень легко проверить доступность сервера базы данных (протестировать соединение).

Вы не понимаете, похоже. В моем случае не надо ничего оборачивать в try-catch (параноики могут обернуть вызов _conn.Open в конструкторе, но это не обязательно), потому что объект хоть и будет создан, но на него не будет ни одной ссылки, поэтому он будет сразу собран GC. А в вашем случае некорректно инициализированное соединение будет висеть внутри вашего объекта, и никакого способа избавиться от него нет (если, конечно, вы не реализуете try-catch внутри Expose).

Как так не нужно оборачивать? Если у вас в конструкторе возникнет исключение, а вы его нигде не обработаете, то приложение упадёт с UnhandledException. Или вы что-то другое имеете в виду?

А ничего, что TimeoutException бывает не только в таких случаях, и не всегда гарантировано, что соединение закрыто?

Не помню точного названия исключения, которое возникает при превышении интервала бездействия и автоматическом его разрыве сервером, но оно точно есть и отличается от остальных. Что-то вроде ConnectionHasBeenClosedByServer.

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

Давайте больше конкретики. В простейшем случае реализацию можно использовать почти точно так же, как и вашу, но при необходимости можно точно контролировать время жизни соединения.
Зато теперь все стало еще смешнее. Теперь при вызове GetSomeData незаметно для пользователя откроется соединение. А когда оно закроется? Никто не знает.

Если вас эта строчка очень смущает, то можете её убрать. Гарантировано Dispose вызовется, когда ссылок на объект не останется.

Но ладно бы у вас было неявное состояние, это еще можно понять, но какой тогда смысл в методе Expose? Можно просто вызывать GetSomeData, поведение будет ровно таким же.

Есть ещё свойство HasConnection, поэтому при желании можно контролировать наличие соединения методами Expose/Dispose, или можно не контролировать если лень или это не критично.

Собственно, один минус никуда не делся — что случится, если внутри Expose, на вызове _conn.Open, произойдет ошибка?

Вызов можно обернуть в try-catch блок и произвести нужные действия в зависимости от типа исключения. В вашем же случае нужно оборачивать в try-catch весь блок using, что уже смотрится не очень, поскольку последний тоже разворачивается в try-finally.

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

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

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

Information

Rating
Does not participate
Registered
Activity