All streams
Search
Write a publication
Pull to refresh
40
0
Send message
Для разработчиков они стремятся к 0, т.к. число достойных аналогов очень велико. Но решения в вопросах на что покупать лицензию часто зависит от людей, которым важно видеть ситуацию по проекту в режиме «реального времени». И тут Microsoft есть, что продать — красивые диаграммы, отчеты по трудозатратам, интеграция с Microsoft Project и Microsoft SharePoint, и т.д.
IE8/9 используют для CORS-запросов специальный объект XDomainRequest, отличный от XMLHttpRequest и неимеющий поддержки в jQuery. Если такая поддержка нужна, рекомендую расширение jQuery ajaxTransport
for(var i = 1, s = ''; i < 101; i++) (s = (i % 3 ? '' : 'Fizz') + (i % 5 ? '' : 'Buzz')) && console.log(s);
В WebClient есть Dispose, не стесняйтесь обернуть его в using.
Ох, с ним много что не так. Особенно доставляет, что встроенный метод CheckForDetailedUpdate для проверки новой версии после определённого числа вызовов кидает COMException из-за ошибки в реализации. Чтобы этого избежать нужно самостоятельно выкачивать манифест приложения и сверять версию программы. И таких граблей там на каждом шагу. Однако, предпочитаю доработать напильником, чем изобретать свой велосипед.
По-моему, с вашим подходом всё в порядке. Данных у вас, я так понимаю, не то чтобы очень много, поэтому запросы хоть и (относительно) тяжёлые, но могут кэшироваться.


Да уж на BigData не перетендую. Кеширование поднял не сразу, так как без него работало приемлемо. Единственное, что тормозило это пересчёт количества товаров для каждой опции фильтра, но это решилось кешированием на уровне бд.

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


Шаблон уже выбирается в UI в зависимости от этой величины, культуры и задачи.

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


Магазин достаточно специфически и большая нагрузка не ожидается, но померить конечно нужно. В основном запросы оптимизировал, а в UI так чтобы уложиться в комфортное время загрузки для пользователя. Так что, мест где можно прооптимизировать достаточно.

Спасибо за ответ и статью.
Использую такую структуру Products — ProductAttributes — ProductAttributeValues.

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

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

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

Т.е. структура достаточно простая и эффективная и легко расширяется, до описанных задач. В принципе 50 000 товаров и особых проблем не испытываю + легко строить фильтры. Единственное, что пришлось перестроить мышление с традиционного подхода с наследованием и добавлением отличных свойств продукта в сторону более менее плоской структуры свойств и работы с ними как с массивом.

Хотелось бы спросить что вы думаете о таком подходе и какие подводные камни могут быть?
Тоже задумывался над вопросом локального хранилища популярных библиотек таких как jQuery. Но потом понял, то такое хранилище уже есть и предлагает много больше, чем я мог себе представить. Называется оно — кеш браузера. В самом деле, если браузеру приходится опрашивать CDN в поисках нужной библиотеки для сайта, для другого сайта она с большей степенью вероятности уже будет в кеше (естественно, если оба сайта обращаются к CDN по одному url). Уже потом я нашёл статью уважаемого Dave Ward aka Encosia, которая называется 6,953 reasons why I still let Google host jQuery for me. В этом труде 2010 года приводится аналогичная статистика и один из выводов:
sites must reference exactly the same CDN URL in order to obtain the cross-site caching benefit
Запомните! Если Вы не подписались на событие и его делегат пустой, возникнет ошибка.
Чтобы избежать этого, необходимо подписаться, или не вызывать событие вообще, как показано на примере (Т.к. событие — делегат, то его отсутствие является «нулевой ссылкой» null).


Пример, сам по себе, является образцом как не нужно делать, между проверкой и вызовом, может произойти отписывание от события и тогда получим NullReferenceException. Выходов из этой ситуации ровно два. Первый — копируем событие в локальную переменную и работаем с ней, второй — в месте инициализации класса добавляем пустой обработчик для события, исключая ситуацию, когда на него никто не подписан и оно равно null.
Kitchener это не часть Toronto, а городок на 200к жителей в GTA (Grand Toronto Area). До самого Toronto полтора часа на машине. Kitchener практически слился с городом Waterloo и недалеко есть город Cambridge. Часто говорят Kitchener-Waterloo area или Tri-City, добавляя Cambridge. В сумме в Tri-City проживает ~350к жителей, что не так плохо по сравнению с остальными городами. На фоне этого советую выбирать Vancouver, а не провинциальный Kitchener.
Пользуюсь Disconnect. Блокирует не только социальные кнопки, но также различную аналитику.
Идём во вкладку “Dashboard” и в колонке “Quick glance” кликаем по “Setup source control”. На момент написания статьи эта опция находилась в состоянии превью.

Одна картинка сто́ит тысячи слов
Интернет-магазин строят в Manning — MongoDB in Action (2011), написано без учёта Aggregation framеwork, но большая часть проблем затронута.
Всегда пожалуйста, только используйте специальный тег для ссылки на хабрапользователя Ithilgwau.
Добавьте, пожалуйста, в публикации немного устаревшую, но от этого не менее ценную статью Алгоритмы кодогенерации.
Декоратор служит для динамического подключения поведения, у меня ничего динамического тут нет.

Необязательно. Вы декорировали ваш читающий класс методами записи.
Кстати, там для получения reader'а вообще можно поставить __inline.

MethodImplOptions.AggressiveInlining, если хотите дать совет JIT.
Ок, мы добрались до места, где ваша полная реализация делегирует методы чтения реализации только для чтения, в то время как мой вариант реализации только для чтения делегирует методы чтения полной реализации. Итого, если отбросить интерфейсы, можно утверждать, что ваша read-only версия читает данные быстрее, т.к. нет дополнительного вызова, в то время как моя full версия читает быстрее по тем же причинам. И могу с увереностью сказать, что вы реализовали Декоратор))
Т.е. продублировать все read вызовы из VectorConst в Vector? А в сторонние методы передавать через Reader, чтобы избежать downcast?
Если вызывать свойство Reader каждый раз при любой операции получится то же, что и у Вас. А при передаче VectorConst в другой метод, Reader или оператор преобразования вызовется только один раз. Получается, что, как ни крути, это выгоднее «Адаптера».

С задачей передачи read-only объекта в метод ваш пример справляется на 100%
Если свойство Reader настолько уж раздражает, можно запихать его в Vector. пометив как private, и перенаправлять к нему реализацию IVectorConst (или Вашего IReadOnlyVector). И даже это всё равно будет лучше «Адаптера», т.к. вызовы будут происходить не через интерфейс и останется разделение ответственности.

Меня как пользователя не устраивает, что я должен писать в одно место и читать из другого. Если вы «запихаете VectorConst в Vector» и «пометите его как private» это никак не повлияет, что мне нужно вызывать Reader каждый раз чтобы что-то прочитать.
В данном случае, дублирования нет.

Ещё раз посмотрел на вашу реализацию и понял, что все методы чтения вы предлагаете делать через Reader. Т.е. если мне не нужен read-only доступ, я как пользователь вашего класса вынужден писать:

var v = new Vector<int>(5);

v[0] = 0;
Console.WriteLine(v.Reader[0]);    

Это так? Вы сознательно поделили read и write версии? Обращение через дополнительно свойство в данном случае не overhead и потеря производительности? Удобно ли это в использовании для конечного пользователя?

Information

Rating
Does not participate
Registered
Activity