Pull to refresh
13
0

Software Developer

Send message

Про ИТ-бизнес и не только

Reading time4 min
Views15K

Всем доброго нового года!


Навеяно статьей Бизнес, я люблю тебя коллеги Verovir, а также ее же статьей Уходя — уходи? Ночной разговор об увольнениях (хотя последняя заслуживает отдельного развернутого ответа).


Коллега, вы в статье хорошо выделили ключевые проблемные точки, с которыми можно встретиться в ИТ- (и не только) бизнесе.

А вот объективная оценка и рекомендации по каждой этих точек ("что, собственно, произошло, и что делать") — вопрос ой какой дискуссионный.

// Кстати, то же касается и вашей предыдущей статьи

Читать дальше →
Total votes 46: ↑37 and ↓9+28
Comments47

Методы расширения для типов стандартной библиотеки .NET

Reading time5 min
Views12K

Наверное, почти каждый .NET-разработчик сталкивался со случаями, когда для удобства кодирования рутинных действий и сокращения boilerplate-кода при работе со стандартными типами данных не хватает возможностей стандартной же библиотеки.


И практически в каждом проекте появляются сборки и пространства имен вида Common, ProjectName.Common и т.д., содержащие дополнения для работы со стандартными типами данных: перечислениями Enums, Nullable-структурами, строками и коллекциями — перечислениями IEnumerable<T>, массивами, списками и собственно коллекциями.


Как правило, эти дополнения реализуются с помощью механизма extension methods (методов расширения). Часто можно наблюдать наличие реализаций монад, также построенных на механизме методов расширения.


(Забегая вперед — рассмотрим и вопросы, неожиданно возникающие, и которые можно не заметить, когда созданы свои расширения для IEnumerable<T>, а работа ведется с IQueryable<T>).


Написание этой статьи инспирировано прочтением давней статьи-перевода Проверки на пустые перечисления и развернувшейся дискуссии к ней.


Статья давняя, но тема по-прежнему актуальная, тем более, что код, похожий на пример из статьи, приходилось встречать в реальной работе от проекта к проекту.

Читать дальше →
Total votes 21: ↑16 and ↓5+11
Comments58

О сравнении объектов по значению — 6: Structure Equality Implementation

Reading time5 min
Views7.3K

В предыдущей публикации мы рассмотрели особенности устройства и работы структур платформы .NET, являющихся "типами по значению" (Value Types) в разрезе сравнения по значению объектов — экземпляров структур.


Теперь рассмотрим готовый пример реализации сравнения по значению объектов — экземпляров структур.


Поможет ли пример для структур более точно определить с предметной (доменной) точки зрения область применимости сравнения объектов по значению в целом, и тем самым упростить образец сравнения по значению объектов — экземпляров классов, являющихся ссылочными типами (Reference Types), выведенный в одной из предыдущих публикаций?

Читать дальше →
Total votes 14: ↑12 and ↓2+10
Comments15

О сравнении объектов по значению — 5: Structure Equality Problematic

Reading time4 min
Views10K

В предыдущей публикации мы вывели наиболее полный и корректный способ реализации сравнения по значению объектов — экземпляров классов (являющихся ссылочными типами — Reference Types) для платформы .NET.


Каким образом нужно модифицировать предложенный способ для корректной реализации сравнения по значению объектов — экземпляров структур (являющихся "типами по значению" — Value Types)?


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


Для предопределенных типов, таких как Boolean или Int32, под сравнением по значению понимается сравнение непосредственно значений экземпляров структур.


Если структура определена разработчиком — пользователем платформы (User defined struct), то сравнение по умолчанию автоматически реализуется как сравнение значений полей экземпляров структур. (Подробности см. в описании метода ValueType.Equals(Object) и операторов == и !=). Также при этом автоматически определенным образом реализуется метод ValueType.GetHashCode(), перекрывающий метод Object.GetHashCode().


И в этом случае есть несколько существенных подводных камней:

Читать дальше →
Total votes 14: ↑13 and ↓1+12
Comments40

О сравнении объектов по значению — 4, или Inheritance & Equality operators

Reading time6 min
Views7.3K

В предыдущей публикации мы получили вариант реализации сравнения объектов по значению для платформы .NET, на примере класса Person, включающий:


  • перекрытие методов Object.GetHashCode(), Object.Equals(Object);
  • реализацию интерфейса IEquatable (Of T);
  • реализацию Type-specific статических метода Equals(Person, Person) и операторов ==(Person, Person), !=(Person, Person).

Каждый из способов сравнения для любой одной и той же пары объектов возвращает один и тот же результат:


Пример кода
Person p1 = new Person("John", "Smith", new DateTime(1990, 1, 1));
Person p2 = new Person("John", "Smith", new DateTime(1990, 1, 1));
//Person p2 = new Person("Robert", "Smith", new DateTime(1991, 1, 1));

object o1 = p1;
object o2 = p2;

bool isSamePerson;

isSamePerson = o1.Equals(o2);
isSamePerson = p1.Equals(p2);
isSamePerson = object.Equals(o1, o2);
isSamePerson = Person.Equals(p1, p2);
isSamePerson = p1 == p2;
isSamePerson = !(p1 == p2);

При этом, каждый из способов сравнения является коммутативным:
x.Equals(y) возвращает тот же результат, что и y.Equals(x), и т.д.


Таким образом, клиентский код может сравнивать объекты любым способом — результат сравнения будет детерминирован.


Однако, требует раскрытия вопрос:


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

Читать дальше →
Total votes 11: ↑8 and ↓3+5
Comments7

О сравнении объектов по значению — 3, или Type-specific Equals & Equality operators

Reading time7 min
Views6.5K

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


Теперь рассмотрим Type-specific реализацию сравнения объектов по значению, включающую реализацию Generic-интерфейса IEquatable(Of T) и перегрузку операторов "==" и "!=".


Type-specific сравнение объектов по значению позволяет достичь:


  • Более стабильного, масштабируемого и мнемонического (читаемого) кода (последнее за счет перегруженных операторов).
  • Более высокой производительности.

Кроме того, реализация Type-specific сравнения по значению необходима по причинам:


  • Стандартные Generic-коллекции (List(Ot T), Dictionary(Of TKey, TValue) и др.) рекомендуют наличие реализации IEquatable(Of T) для всех объектов, помещаемых в коллекции.
  • Стандартный компаратор EqualityComparer(Of T).Default использует (по умолчанию — при наличии) реализацию IEquatable(Of T) у операндов.

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


  • Соответствие результатов сравнения у различных способов (включая сохранение соответствия при наследовании).
  • Минимизацию copy-paste и общего объема кода.
  • Учет того, что операторы сравнения технически являются статическими методами и, соответственно, у них отсутствует полиморфность (а также, что не все CLS-совместимые языки поддерживают операторы или их перегрузку).

Рассмотрим Type-specific реализацию сравнения объектов по значению с учетом вышеизложенных условий, на примере класса Person.


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

Читать дальше →
Total votes 23: ↑18 and ↓5+13
Comments13

О сравнении объектов по значению — 2, или Особенности реализации метода Equals

Reading time9 min
Views12K
В предыдущей публикации мы рассмотрели общие принципы реализации минимально необходимых доработок класса для возможности сравнения объектов класса по значению с помощью стандартной инфраструктуры платформы .NET.

Эти доработки включают перекрытие методов Object.Equals(Object) и Object.GetHashCode().

Остановимся подробнее на особенностях реализации метода Object.Equals(Object) для соответствия следующему требованию в документации:

x.Equals(y) returns the same value as y.Equals(x).

Класс Person, созданный в предыдущей публикации, содержит следующую реализацию метода Equals(Object):

Person.Equals(Object)
public override bool Equals(object obj)
{
    if ((object)this == obj)
        return true;

    var other = obj as Person;

    if ((object)other == null)
        return false;

    return EqualsHelper(this, other);
}

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

В соответствии с примером, приведенным в документации, приведение производится с помощью оператора as. Проверим, дает ли это корректный результат.
Читать дальше →
Total votes 21: ↑16 and ↓5+11
Comments13

О сравнении объектов по значению — 1: Beginning

Reading time7 min
Views27K

Общеизвестно, что в объектной модели .NET, как и во многих других программных платформах, сравнивать объекты можно по ссылке и по значению.


По умолчанию два объекта считаются равными, если соответствующие переменные содержат одну и ту же ссылку. В противном случае объекты считаются неравными.

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

Пусть есть класс Person, содержащий персональные данные — имя, фамилию, и дату рождения персоны.


На примере этого класса рассмотрим:

  1. минимально необходимый набор доработок класса для того, чтобы объекты этого класса сравнивались по значению с помощью стандартной инфраструктуры .NET;
  2. минимально необходимый и достаточный набор доработок, чтобы объекты этого класса всегда сравнивались по значению с помощью стандартной инфраструктуры .NET — если явно не указано, что сравнение должно производиться по ссылке.

Для каждого случая рассмотрим, каким именно образом лучше реализовать сравнение объектов по значению, чтобы получился согласованный и, насколько это возможно, компактный, copy-paste free, производительный код.

Задача является не настолько тривиальной, насколько это может показаться на первый взгляд.

А также рассмотрим, какие улучшения могли бы быть внесены в платформу, чтобы упростить реализацию этой задачи.
Читать дальше →
Total votes 24: ↑17 and ↓7+10
Comments58

Композиция и интерфейсы

Reading time17 min
Views28K

В мире объектно-ориентированного программирования уже достаточно давно подвергается критике концепция наследования.


Аргументов достаточно много:


  • дочерний класс наследует все данные и поведение родительского, что нужно не всегда (а при доработке родительского в дочерний класс вообще попадают данные и поведение, которые не предполагались на момент разработки дочернего);
  • виртуальные методы менее производительные, а в случае, если язык позволяет объявить невиртуальный метод, то как быть, если в наследнике нужно его перекрыть (можно пометить метод словом new, но при этом не будет работать полиморфизм, и использование такого объекта может привести к неожидаемому поведению, в зависимости от того, к какому типу приведен объект в момент его использования);
  • если возникает необходимость множественного наследования, то в большинстве языков оно отсутствует, а там, где есть (C++), считается трудоемким;
  • есть задачи, где наследование как таковое не может помочь — если нужен контейнер элементов (множество, массив, список) с единым поведением для элементов разных типов, и при этом нужно обеспечить статическую типизацию, то здесь помогут обобщения (generics).
  • и т.д., и т.п.

Альтернативой наследованию являются использование интерфейсов и композиция. (Интерфейсы давно используется в качестве альтернативы множественному наследованию, даже если в иерархии классов активно используется наследование.)

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

А как можно решить эту задачу (отсутствие дублирования кода) в случае композиции и интерфейсов?
Этой теме и посвящена настоящая статья.
Читать дальше →
Total votes 16: ↑14 and ↓2+12
Comments38

C#: как не «выстрелить себе в ногу»

Reading time4 min
Views4.9K
Сегодня мы рассмотрим более детально, как стало возможным «выстрелить себе в ногу» на C#, а также в целом на .NET, при работе с логическими значениями, в каких практических кейсах это может произойти, и как этого не допустить.

Какие же строки выводятся на экран этим консольным приложением?
Запустив приложение, предварительно собрав его в среде Visual Studio Community 2013, получим следующий результат:

Unsafe Mode
01: b1        : True
02: b2        : True
03:  b1 ==  b2: False
04: !b1 == !b2: True
05: b1 && b2  : True
06: b1 &  b2  : True
07: b1 ^  b2  : True
08: b1 && b3  : True
09: b1 &  b3  : False
10: b1 ^  b3  : True

Safe Mode
11: b1        : True
12: b2        : True
13:  b1 ==  b2: True
14: !b1 == !b2: True
15: b1 && b2  : True
16: b1 &  b2  : True
17: b1 ^  b2  : False
18: b1 && b3  : True
19: b1 &  b3  : True
20: b1 ^  b3  : False

Исходя из допущения, что в каждой из логических переменных b1, b2, b3 находится либо «истинное» значение, либо значение, отличное от «ложного» (а, значит, тоже «истинное»? — ведь это булевы переменные?), возникают несколько вопросов:
  1. Почему в блоках Unsafe и Safe Mode разные результат в позициях 03 и 13, 07 и 17, 09 и 19, 10 и 20 соответственно?
    (а почему тогда значения в других соответствующих друг другу позициях в блоках Unsafe и Safe совпадают?)
  2. Почему внутри блока Unsafe результаты в позициях 05 и 06 одинаковы, а в 08 и 09 — разные?
    И почему результаты в 08 и 09 разные?

Попробуем разобраться:
Читать дальше →
Total votes 22: ↑8 and ↓14-6
Comments10

C#: как «выстрелить себе в ногу»

Reading time2 min
Views16K
Рассмотрим, как можно «выстрелить себе в ногу» на C# (и в целом в .NET).
Оказывается, такое можно сделать не только на C++.

Ниже представлен код, «играющийся» с типом bool (System.Boolean) и выводящий на экран 20 строк True или False.
Для первых десяти строк поведение детерминировано только для первой строки, а поведение для 2-10 строк зависит от реализации компилятора.

Код вполне самодокументированный, поэтому добавлю только, что на подобное поведение вполне можно наткнуться при вызове неуправляемых функций через P/Invoke, в случае их некорректного использования (на эту тему будет продолжение).
Читать дальше →
Total votes 28: ↑11 and ↓17-6
Comments7

Региональный малый и средний бизнес в ИТ — 3

Reading time2 min
Views3.3K

Рассмотрим принципы современной организации процесса разработки, в большей степени присущие современным гибким (Agile) методологиям, чем «водопаду» (Waterfall).


Возможно, при этом будет определенный акцент на критике, но не стоит на ней зацикливаться. Скорее, это сравнительный обзор: каждый из подходов имеет свои плюсы и минусы.
Данный пост является продолжением предыдущих публикаций (часть 1, часть 2).

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

1. Аналитики создают модель предметной области в своих терминах, разработчики программируют ее в своих (в той или иной парадигме программирования).
Нужно, чтобы кто-то «наводил мосты» между первыми и вторыми.


Читать дальше →
Total votes 14: ↑11 and ↓3+8
Comments0

Региональный малый и средний бизнес в ИТ — 2

Reading time2 min
Views3.9K

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


Компании, о которых пойдет речь, в отличие от героев предыдущей статьи, не имеют прямого отношения к сфере ИТ, однако наблюдения и выводы в этой сфере сделаны в процессе внедрения информационных проектов, что поможет в дальнейшем для формирования общей картины.
Можно считать публикацию неформальным лирическим отступлением.

Итак, третья группа региональных субъектов среднего бизнеса (малых здесь уже нет) достаточно разношерстна, как по составу, так и по своей деятельности, но в то же время имеет и объединяющие групповые признаки.
Читать дальше →
Total votes 15: ↑12 and ↓3+9
Comments0

На тему моделирования предметной области в терминах ООП

Reading time3 min
Views15K

Эта замечательная статья подтолкнула меня опубликовать давние мысли, касающиеся моделирования предметной области с помощью объектно-ориентированного программирования.


К актуальности изложенных в статье идей, приходишь подспудно (не имея возможности выразить по причине того, что парадигме моделирования в терминах теории множеств не учат в вузах, будущих «программистов», по крайней мере), долго работая с ООП и реляционными базами данных:

Каждый раз при моделировании предметной области, оперируя терминами ООП (сейчас говорим не об этапе бизнес-анализа, а о последующем этапе реализации модели в коде), для всех сущностей предметной области приходится реализовывать в коде и схеме БД следующий паттерн, состоящий их «подсущностей», связанных между собой:
  • класс/таблицу вида «Машины» (здесь и далее класс употребляю в терминах ООП);
  • класс/таблицу вида «Список машин»;
  • класс/таблицу вида «Машина».

Далее с помощью механизмов ООП и реляционной модели «подсущности» связываются между собой.

Причем термины «сущность» и «подсущность» применимы именно к модели предметной области в терминах теории множеств,
а в терминах ООП/реляционной модели уместны термины «метасущность» и «сущность» соответственно.
Надеюсь, понятно, почему? — ООП/реляционная модель являются более низкоуровневыми механизмами, и сущность предметной области приходится конструировать, нет в них средств, которые нативными образом позволили бы отразить сущность предметной области.

А далее следуют ожидаемые проблемы:

Читать дальше →
Total votes 13: ↑8 and ↓5+3
Comments44

Региональный малый и средний бизнес в ИТ

Reading time5 min
Views15K

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


Тот путь, который прошел малый и средний ИТ-бизнес за последние 25-30 лет, оказался долгим и тернистым, а качество бизнес-процессов и благосостояние бизнеса зачастую до сих пор оставляет желать лучшего.
Хотелось бы, чтобы в случае каких-то тектонических сдвигов бизнес не откатился на 25-30 лет назад, и чтобы продолжалось движение вперед.

Этой публикацией я начну цикл статей на данную тему с поиском решений.
Рассмотрим историю и текущее состояние бизнеса, связанного с информационными технологиями, на примере следующих групп:
Читать дальше →
Total votes 15: ↑14 and ↓1+13
Comments1

Information

Rating
Does not participate
Location
Россия
Registered
Activity