• Как легче освоить внедрение зависимостей, code-first, TDD и паттерны?

    Valeriy1991
    @Valeriy1991
    Разработчик .NET C# (ASP.NET MVC) в Alfa-B, Moscow
    Добрый вечер! Спасибо за приглашение.
    На мой взгляд, Вам следует придерживаться следующих приоритетов по изучению:
    1. внедрение зависимостей более важно из Вашего списка, т.к. относится к SOLID принципам;
    2. TDD - на мой взгляд, вещь более нужная для изучения, чем code-first или patterns. Сам не так давно начал разрабатывать по TDD. Это очень здорово, что изобрели такой подход. Экономит тонну времени на ручное тестирование, а также дает быстрое понимание, что и где случайно (или неслучайно) сломалось. Главное - понимать, что покрывать тестами;
    3. третьим в список я бы добавил AngularJS или KnockoutJS или BackboneJS - сам пока что не изучил их и не начал применять, но судя по их популярности и преимуществам - думаю, Вам стоит с ними ознакомиться;
    4. code-first или database-first - не так уж и важно на Вашем этапе понимания. Главное отличие подхода Code-first: 1) модель пишется вручную, в связи с чем не нужно постоянно отслеживать edmx-диаграмму (т.е. можно считать, что Ваша code-first модель всегда находится в актуальном состоянии); 2) поддерживает миграции БД. В Database-first Вам нужно самому отслеживать актуальность состояния Вашей edmx-модели - с этим тоже могут быть проблемы. Опять же - только с опытом. С другой стороны, Database-first позволяет наглядно видеть Вашу модель, а вот Code-first - нет;
    5. паттернами тоже можете пока что голову не забивать. Безусловно, это нужно, но понимание их придет только с опытом (признаюсь честно: я сам не до конца все паттерны знаю и понимаю). На мой взгляд, важно соблюдать 1 основной паттерн - 3-уровневая архитектура (клиентский слой, слой бизнес-логики, слой работы с данными).

    Теперь по MVC.
    1. Model - тут, в принципе, всё просто: модель данных. Здесь можно поспорить, что иметь в виду под Моделью: модель самих данных или модель представления. Лично я после опыта работы с шаблоном MVVM в WPF под моделью данных в терминах ASP.NET MVC понимаю модель представления, а под термином "модель данных" - саму доменную модель (EF code-first, например). Кто-то может сказать, что это "лишняя работа" - по упаковыванию модели данных из EF-объектов в объекты модели представления. Да, частично соглашусь. Но зато это дает некую гарантию безопасности, что случайно пользователь не поменяет важную часть модели данных (например, ID).
    2. Контроллер. Основная задача контроллера - сформировать данные для отображения и передать эти данные в представление. Т.е. нужно стремиться к тому, чтобы код метода действия в контроллере содержал минимум кода. В идеале - вызов метода из слоя бизнес-логики и передача полученных данных в представление. Если Вы видите, что метод действия в контроллере содержит какую-то бизнес-логику, то это сигнал к рефакторингу: Ваш метод действия слишком много знает. По опыту могу добавить, что в среднем код метода действия содержит от 2 до 20-30 строк кода (с учетом того, что скобки { и } расположены на отдельных строках).
    3. Представление. Тут тоже всё просто: отобразить данные (из модели представления). Ни в коем случае нельзя в представлении писать логику по работе с самими данными, например, так делать нельзя:
    <div id="account">
        @{
            using(var db = new MyEfDbContext()
            {
                var userAccount = db.Accounts.FirstOrDefault(e => e.Username == User.Identity.Username);
                if(userAccount != null)
                {
                    @:Имя: @userAccount.Name
                    @:Фамилия: @userAccount.LastName
                }
            }
        }
    </div>


    Если у Вас 3-уровневая архитектура, например, есть слои:
    1. MyApp.MVC - MVC-application
    2. MyApp.BL - слой бизнес-логики
    3. MyApp.DAL - слой работы с данными
    то в представлении (View) вызывать напрямую сервисы бизнес-логики тоже нельзя, особенно, если Вы используете DI-принцип (внедрение зависимостей) и IoC контейнер. Т.е. такой пример недопустим:
    <div id="account">
        @{
            var accountService = new MyApp.BL.AccountService();
            var userAccount = accountService.GetUserAccountByUsername(User.Identity.Name);
            if(userAccount != null)
            {
                @:Имя: @userAccount.Name
                @:Фамилия: @userAccount.LastName
            }
        }
    </div>

    Попробую донести мысль архитектора и разработчика Александра Шевчука (преподавателя с http://itvdn.com): "Одна из главных целей при разработке - стремиться к упрощению системы". Ослабление зависимостей позволяет нам упрощать систему благодаря тому, что изменение осуществляется только на 1 каком-то слое/уровне. Если Вы во View вынесете логику по работе с данными, а уж тем более, как в примерах выше, работу с EF-контекстом, то Вы усилите зависимость одного компонента системы (MVC-слоя) от другого (слоя работы с данными или слоя бизнес-логики). Усиление зависимостей приводит к бОльшему числу изменений, что в свою очередь сказывается на повышении расходов на эту систему. Ослабление зависимостей приводит к меньшему числу изменений (например, при переходе от EF к native SQL или NHibernate затрагивается только слой работы с данными, а слой MVC и бизнес-логики не меняются), а значит, к более раннему выпуску системы или очередного релиза, и как следствие, снижение расходов (не только денежных, но и других ресурсов) на разработку. TDD тоже можно отнести к практикам, которые снижают затраты ресурсов на содержание системы. Но это я ушел в глобальное...

    Правильным будет подход, при котором у Вас снижается зависимость компонентов системы друг от друга, в случае с ASP.NET MVC приложением, на мой взгляд, это когда:
    - View знает о модели (я по прежнему буду иметь в виду модель представления - ViewModel, которые объявлены либо в MVC-слое, либо в слое бизнес-логики);
    - контроллер знает о слое бизнес-логики, обращается к нему за выполнением операций и получением ViewModel'ей, после чего передает во View полученную ViewModel (ну или JSON-данные);
    - Model формируется по принципу, грубо говоря, почти на каждую View своя модель.

    Фразу "правильным будет подход" я обосновываю тем, что у такого подхода есть масса плюсов (которые очевидны опытным разработчикам, но могут быть не до конца или неправильно поняты менее опытными коллегами, а именно):
    + View ничего не знает о доменной модели (только о ViewModel), благодаря чему Вы можете спокойно менять свою доменную модель, не внося изменений во View (см. выше про ослабление зависимостей и снижение количества связей). Также Вы спокойно можете перейти от EF к NHibernate или к native SQL, или использовать и то, и другое - View об этом никогда не узнает;
    + контроллер (да и весь MVC-слой) знает только о существовании слоя бизнес-логики, но ничего не знает о слое работы с данными.
    + если на View делать отдельную ViewModel, то это позволяет более полноценно управлять тем, что нужно показать пользователю. Т.е. дает возможность большего контроля отображаемых данных, повышает безопасность Вашего приложения (пользователь, например, не сможет изменить ID просматриваемой записи, если этого ID нет вообще в модели представления).

    Ну а вообще все зависит от задачи/проекта: нужно ли применять разбивку на слои или использовать ViewModel'и вместо обычных доменных моделей - надо думать над каждой ситуацией отдельно.

    P.S. На мой взгляд, литературу выбрали правильно - я тоже начинал изучение MVC с нее. Понравилась тем, что дается сначала общее описание и работа с ASP.NET MVC на сквозном примере. А потом идет более глубокое погружение в ASP.NET MVC. По разработке могу посоветовать блог Александра Бындю: blog.byndyu.ru Как мне кажется, там очень хорошо некоторые моменты разжевываются, в том числе SOLID, TDD, шаблон Repository, UnitOfWork и др.
    Ответ написан
    2 комментария
  • Как в INSERT - выражении в MS SQL избежать вставки дублирующихся значений в составной Primary Key?

    @heartdevil
    плыву как воздушный шарик
    Привет.
    Надыбал три способа:

    1) Попробуйте установить параметр IGNORE_DUP_KEY

    2) В MSSQL есть оператор MERGE

    Вот пример использования:
    merge into [dbo].[table]
    using [dbo].[Stage_Table] on Stage_Table.pk = table.pk
    when not matched then insert (val1) values (1234);


    3) Использовать NOT EXISTS

    Вот пример использования:
    INSERT INTO my_table
    SELECT 1, 'foo', 3
    WHERE NOT EXISTS (
      SELECT 1 from my_table WHERE foo_col = 'foo'
    );


    А как вы данные вставляете в таблицу? У вас есть еще одна таблица? Или какой-то файл, который вы в цикле пробегаете и затем вставляете записи в таблицу?
    Ответ написан
    4 комментария
  • Как сделать Random в T-SQL с отрицательными и положительными числами?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    100-Rand()*200
    Ответ написан
    Комментировать
  • Какую книгу подарить младшему брату, который хочет стать программистом?

    vt4a2h
    @vt4a2h
    Senior software engineer (C++/Qt/boost)
    Чарльз Петцольд. Код. (если найдёте в бумажном варианте)
    Именно с этой книги и нужно начинать, а не с HTML/JS/PHP.
    Ответ написан
    Комментировать
  • Какую книгу подарить младшему брату, который хочет стать программистом?

    hahenty
    @hahenty
    ('•')
    Подарите книгу по рисованию.

    Видите ли, 100% времени в кодах не проведешь, а чем-то еще заняться хочется - стравить непрограммистскую энергию, так сказать. Вот тут-то человек, забитый с детства одной лишь клавиатурной наукой столкнется с неописуемым чувством отторжения от, казалось бы, любимого дела.
    Туризм не попер, человек домосед, тогда можно и порисовать на досуге, отвернувшись от монитора. И рисовать будет веселее, когда умеешь рисовать.
    Ответ написан
    2 комментария
  • Какую книгу подарить младшему брату, который хочет стать программистом?

    kopcap_va
    @kopcap_va
    SEO Consultant
    Подарите ему ссылку на https://codecombat.com/ - моего брата заинтересовало и ему стало понятно как связаны те или иные предметы в играх и как вообще это все работает в общих чертах)

    Из ЯП можно и в Python его направить, в книге есть примеры игр - для начинающего очень хороший вариант.
    Ответ написан
    Комментировать
  • Какую книгу подарить младшему брату, который хочет стать программистом?

    @dmitryKovalskiy
    программист средней руки
    head first вполне нормальный вариант для начала. правда есть риск что книжка воспримется как другая крайность - "написано как для дебилов". в вашем описании есть другой риск - любитель поиграть, желающий стать программистом, часто лелеет мечту сделать свою игру, а когда узнает что компьютерная графика это не "подтянуть математику", а чистейший матанализ и высшая математика - может настигнуть разочарование и идея стать программистом улетит в трубу.
    Ответ написан
    2 комментария
  • Какой использовать алгоритм сортировки, если требуется сложность не более O(n) и максимальная производительность?

    @bromzh
    Drugs-driven development
    Во-первых, есть строгое доказательство, что сортировка произвольного массива не может быть выполнена быстрее, чем за O(n*log(n)) операций (log тут по основанию 2).
    Во-вторых, у сортировок есть много параметров: время в лучшем/худшем/среднем случае, доп. память, стабильность.
    QuickSort имеет время O(n log n) в среднем и лучшем, а в худшем - за O(n^2). Ещё она нестабильная и требует O(n) памяти. В обычных условиях это устраивает, но худший случай в ней - её слабое место.
    Есть модификации быстрой сортировки, позволяющие уменьшить время худшего случая до O(n log n).
    В языках программирования встроенные сортировки - это обычно либо быстрая сортировка с улучшениями, либо какая-нибудь стабильная сортировка, какой-нибудь merge sort.

    Так что либо бери родную, либо пиши сам. Самая простая модификация быстрой сортировки, при которой худшее время станет O(n log n) - это сделать случайный выбор опорного элемента.

    Ну и читай https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D...
    Ответ написан
    3 комментария
  • Как изучить c# с основ до зарабатывания денег?

    foxmuldercp
    @foxmuldercp
    Системный администратор, программист, фотограф
    Поставьте себе цель в зависимости от направления - Modern-UI, Windows Phone, Classic Desktop, Asp.Net MVC, Sharepoint, и потихоньку её решайте - вечерами после работы (как я, например, сейчас занимаюсь MVC) или джуниором в какой-то компании
    Ответ написан
    Комментировать