Какая цель программного продукта
При создании любого программного продукта всегда возникают две цели: «разработать правильный продукт» и «разрабатывать продукт правильно». Для того, чтобы итоговый продукт был успешным нужно всегда стремиться достичь обе указанные выше цели, а не сосредотачиваться только на одной из них, как это часто бывает. Иначе, если победит партия сейлзов, то в итоге быстро создается продукт, первая версия которого нравится клиентам, но при попытке выпустить вторую версию, процесс начинает буксовать, число багов только увеличиваться, а сроки релиза срываться. А если наоборот, безоговорочно побеждают технари, то в результате получается интересное с технической точки зрения решение, которое отлично работает, функционал которого может быть легко расширен, но вот сам продукт не востребован рынком и просто проедает деньги инвесторов.
Разработать правильный продукт
Для создания правильного продукта вы должны полностью понимать потребности ваших потенциальных клиентов. Поэтому первым делом надо начинать с исследования рынка. Необходимо ответить самому себе на следующие вопросы:
- Вы планируете выйти на существующий рынок, на котором еще есть незанятые ниши?
- Это потенциальный рынок, которые еще требуется создать?
- Если мы реализуем задумку, то сможем ли эффективно донести до клиентов выгоду от ее использования?
Если вы сможете ответить на эти вопросы и ответ внушает оптимизм, то можно начинать. Наихудшая из возможных ситуаций – это реализовать решение для некой гипотетической проблемы, а при попытке выйти на рынок убедиться, что проблемы в реальности не существует. Правильно сначала найти проблему, а затем придумать решение для нее. Итого: программный продукт должен соответствовать реальным потребностям клиентов, а не представлениям разработчиков о них.
После того, как потенциальный проект определен, вам нужно определить список требуемой функциональности. Для этого надо сделать аккуратный сбор и анализ требований. Далеко не всегда возможно сразу определить всю необходимую функциональность, но чем точнее вы очертите рамки будущего продукта, тем больше у вас шансы на успех.
Кроме собственно реализации определенной функциональности, вам будет необходимо создать подходящий интерфейс пользователя. Если планируется, что ваш продукт будет использоваться людьми со слабым знанием компьютера, то вы должны спроектировать простой и интуитивно понятный UI в соответствии с их навыками. И наоборот, если вы создаете софт для IT-профессионалов, то нужно делать UI который они смогут сами настроить под свои потребности. Кроме этого интерфейс должен соответствовать стандартам области использования, например, использовать общепринятую терминологию.
Надо выбрать правильные технологии для реализации программного продукта. Разработчики имеют тенденцию к использованию самых свежих технологий, которые только-только появились на рынке, но будет обидно если готовый продукт будет отвергнут рынком, так как требует софта или железа, которые еще не получили широкого распространения. Совместимость со стандартами часто более важна для клиента, чем производительность или богатая функциональность. Так как менять всю работающую инфраструктуру только ради одного решения никто не будет.
И последнее, на что требуется обратить внимание, при разработке – это экономическая составляющая проекта. Если у вас нет достаточного финансирования для завершения проекта, то будет лучше не тратить имеющиеся ресурсы на бесполезную затею. Более того, даже если в принципе возможно реализовать задуманный продукт, но цена для клиентов будет больше получаемой ими выгоды от использования вашего решения, то у вас также не получится продать продукт и получить прибыль. К слову сказать, все это верно и для шароварных проектов, разрабатываемых дома по вечерам.
Итого пять простых правил для выбора правильного продукта:
- Ориентируйтесь на требования клиентов.
- Реализуйте требуемую клиентам функциональность.
- Интерфейс пользователя должен быть рассчитан на целевую аудиторию.
- Используйте подходящие технологии.
- Прибыль от проекта должна быть больше, чем стоимость реализации.
Разрабатывайте продукт правильно
Правильная разработка программного продукта подразумевает использование правильных технологий и практик процесса разработки. Удивительно, но многие девелоперские команды используют принцип «главное, что все сделано, а как неважно». Если вы не контролируете процесс разработки, то вы никогда точно не знаете, что вы сделали и как вы это сделали, а успех проекта в большей или меньшей степени становится зависим от слепой удачи.
Правильные подходы к разработке программного кода обеспечат создание продукта, который не теряет данные, не имеет логических ошибок, утечек памяти и не крешется. Необходимо использовать практики на вроде «безопасного программирования», проверяя корректность значений переменных перед их использованием и анализируя коды возврата функций. Устаревший подход «мусор на вход, мусор на выход», нужно заменять на «мусор на вход, диагностика на выход». Эти дополнительные проверки немного замедляют скорость разработки и перформанс продукта, но в результате окупаются с лихвой.
Хороший код должен быть производительным. Он не должен создавать излишнюю нагрузку на процессор, память, жесткий диск или сеть. В связи с появлением дешевого производительного железа проблема перформанса сейчас стоит не так остро, как в прошлом, но она все еще актуальна. Разработчики часто недооценивают размер инфраструктуры пользователя. Продукт отлично работающий в тестовой лаборатории может безжалостно тормозить или выедать всю память в реальной инфраструктуре.
Любая команда разработки софта должна использовать coding style. Каждый программист имеет тенденцию к изобретению своего собственного, совершенного, стиля кодирования. Если попросить 10 программистов описать стандарт кодирования, то вы получите 10 разных стандартов, а если попытаетесь выбрать лучший из них, то можете разжечь религиозную войну. Поэтому coding style должен быть выбран в ультимативной форме менеджером или тимлидом.
Повторное использование кода – это еще один подход к повышению качества кода. Если вы реализовали и протестировали какой-нибудь функционал, то использование его повторно не только уменьшает время на разработку, но и увеличивает стабильность и поддерживаемость продукта. Главное не увлекаться, не нужно реюзать код только ради реюзанья.
Продукт должен быть поддерживаемым. Это означает, что код не только хорошо задокументирован, но и используемые алгоритмы, и их реализация должны быть легко понимаемы новыми программистами, присоединившимися к команде. Также необходимо создавать исходный код таким образом, чтобы его можно было легко менять с минимальными рисками разломать продукт. Избегайте в архитектуре продукта неочевидных взаимосвязей, когда изменения в одной части продукта могут привезти к багу в другой. Не забывайте о платформе, на которой будет работать ваше приложение. Будет ли ваш продукт продолжать работать, если изменится операционная система, железо и браузер?
Правильно разработанный продукт должен быть работоспособным на будущих версиях операционных систем, на которых он работает сейчас. Для этого продукт необходимо разрабатывать с учетом требований производителя операционки, а специфика конкретной версии должна влиять только на небольшие изолированные участки кода. Чаще всего, проблемы с переходом на новые версии OS связанны с ошибками дизайна, а не выбором языка программирования или фреймворка.
Тестирование, тестирование и еще раз тестирование. Необходимо тестировать продукт на всех стадиях процесса разработки, и чем раньше вы начнете это делать, тем лучше. Одна из распространенных ошибок программистов — сначала написать большой кусок кода, а затем пытаться протестировать его целиком. Результат будет гораздо лучше, если вы будете тестировать отдельно каждую функцию и каждый интерфейс, например, используя юнит тесты. Да, иногда для этого придется писать моки и другие вспомогательные вещи, но время, потраченное на тесты, в итоге будет меньше, чем отладка и тестирование уже целиком написанного продукта.
Как только код начал разрабатываться, необходимо сразу реализовать и протестировать процедуру сборки продукта. Новый билд продукта должен собираться каждый день, или даже каждый час. Постоянное использование стабильной билд процедуры позволяет сразу же находить ошибки, ломающие сборки. Гораздо проще пофиксить проблему сразу, пока еще все сделанные изменения сидят в голове, нежели найти проблему через неделю и мучительно вспоминать зачем так было сделано.
Кроме этого, необходимо как можно быстрей выделить отдельную машину для сборки билда, которая только для этого и будет использоваться. Машины разработчиков быстро обрастают всевозможным «мусором», разными версиями фреймворков, SDK, результатами экспериментов и т.п. Все это может приводить к неожиданным проблемам в релизном билде. Необходимо собирать «эталонный билд» и именно его отдавать на ручное тестирование и в релиз.
В заключении хочется отметить, что правильно разработанный продукт позволяет отслеживать все ваши изменения, а сам процесс и результат делает воспроизводимым. В дополнение к этому, правильно поставленные процессы разработки обеспечивают вам возможность постоянного улучшения процесса, ведь не существует такой организации процесса разработки, в которой было бы нечего улучшать.
Все новости сайта в телеграм канале:
@pmlife_ru
Источник
Вторым процессом начального этапа проектирования программных систем является разработка (постановка) и описание целей для создаваемой программной системы. При правильной постановке целей не делается никаких предположений о конкретной реализации, но указывается, каким образом на последующих этапах проектирования следует принимать компромиссные решения. Например, невероятно важно иметь в качестве целей конкретного проекта такую формулировку [11]: «Обеспечить максимальную надежность, эффективность, адаптируемость и безопасность системы, минимизируя стоимость и время разработки, требуемую память и время реакции терминала». Такого рода формулировки бессмысленны, поскольку многие из перечисленных факторов противоречат друг другу. Таким образом, назначение раздела проекта постановки целей программного продукта – не только сами цели, но и, если нужно, компромиссы между этими целями.
К общим ошибкам, совершаемым в процессе разработки и описания целей, относятся следующие:
- 1) цели не формулируются явно;
- 2) противоречивость в описании сформулированных целей (конфликт целей);
- 3) наличие поверхностно выявленных целей, не отражающих специфические особенности разрабатываемой программной системы;
- 4) цели программной системы с точки зрения пользователя (цели продукта) и цели проекта с точки зрения разработчика противоречивы.
Работы по созданию программной системы должны обеспечить выполнение двух различных множеств задач (целей): задач продукта разработки, определяющих его цели с точки зрения пользователя (цели продукта), и задач проекта, отображающих цели в рамках проекта (график выполнения работ, стоимость, степень тестирования, степень надежности и др.). В силу противоречивости целей ошибка, выражающаяся в отсутствии необходимого уровня достижения компромисса на системной основе, является достаточно распространенной. Для понимания путей нахождения компромисса между противоречивыми целями следует рассмотреть отношения между различными категориями компромиссов. Поскольку одной из важнейших задач разработки программных систем является достижение надежной работы системы, далее рассмотрим компромиссы между надежностью и другими наиболее важными требованиями.
- 1. Универсальность (общность) выступает в качестве меры количества, мощности и объема функций, запрашиваемых пользователем. Не следует ставить перед проектировщиком задачу достижения максимальной универсальности, необходимо представить ему перечень специфических функций применения продукта. Следует помнить, что универсальность и надежность работы ПС противоречат друг другу. Уже одно увеличение объема ПС при росте числа выполняемых функций приведет к росту числа ошибок при программировании. Поэтому каждая функция должна быть взвешена в смысле ее реальной пользы для потребителя и сопоставления с ее влиянием на надежность.
- 2. Человеческие факторы являются мерой легкости понимания результатов, легкости использования, защищенности от неправильного употребления и, как результат, частоты ошибок пользователя. Хотя интеллектуальность интерфейса пользователя может увеличить сложность системы и, таким образом, иметь отрицательное влияние на надежность, психологические факторы и надежность обычно не вступают в конфликт. Хороший учет психологических факторов позволяет свести к минимуму возможность неожиданных действий пользователя, что уменьшает возможность проявления скрытых ошибок в программном коде.
- 3. Адаптируемость ПС к различным условиям применения и классам пользователей является качественной мерой легкости использования и расширения за счет добавления новых функций. Адаптируемость и надежность в общем случае могут рассматриваться как совместимые. Более того, реализация мер по повышению надежности оказывает положительное влияние на адаптируемость и расширяемость системы в процессе ее сопровождения.
- 4. Удобство сопровождения характеризует меру затрат времени и средств на исправление ошибок в работающей системе. Это требование согласуется с требованиями надежности, поскольку оно тесно связано с адаптируемостью. Кроме того, такие методы обеспечения надежности, как обнаружение и изоляция ошибок, способствуют повышению надежности.
- 5. Безопасность определяется мерой вероятности того, что один пользователь может случайно или преднамеренно уничтожить данные, являющиеся собственностью другого пользователя, или препятствовать действию системы. Меры безопасности включают анализ ожидаемых угроз, тщательную взаимную изоляцию пользователей по данным и программам, обособление программ пользователей от операционной системы, разработку контрмер по противодействию проникновения в систему. Разработка и внедрение мер безопасности положительно сказывается на надежности.
- 6. Документация. Задачи документации связаны с количеством и качеством публикаций в интересах пользователей. Документация и человеческие факторы сходны в том, что они связаны с облегчением понимания и использования программной системы. В связи с этим решение проблем документирования не противоречит достижению заданного уровня надежности.
- 7. Стоимость программной системы включает затраты, связанные с созданием и сопровождением системы. Стоимость в значительной мере связана с количеством ошибок в программном продукте, а следовательно, с затратами на их исправление. Поэтому достижение высокой надежности и минимизация затрат на проектирование и разработку ПС в известной степени противоречат друг другу.
- 8. График работ. Одной из ключевых задач любого проекта является получение программного продукта к определенной дате. При этом предполагается, что экономический эффект продукта связан с датой его доступности. Многие из связей между надежностью и стоимостью также существенны и для графика работы и надежности. Одной из причин изменения графика работ является задача обеспечения заданной надежности. Например, имеет место тенденция недооценивать время, необходимое для тестирования. Фактическое время тестирования связано с числом ошибок, оставшихся в продукте. Отсюда задача довести до минимума время, затрачиваемое на разработку, и до максимума – надежность является совместимой при условии, что сроки не сокращены до такой крайности, когда на надлежащее проектирование просто не остается времени.
- 9. Эффективность (производительность). Связи между производительностью ПС и надежностью достаточно сложны. Многие приемы повышения надежности работы программ связаны с увеличением объема системы в числе таких команд, как, например, контроль и обработка исключений, контрольные точки, двойной (а иногда тройной) просчет и др. Это приводит к увеличению времени выполнения программ и росту объема необходимой памяти. С другой стороны, ненадежная программная система не может считаться эффективной независимо от того, как быстро она работает.
К этому надо добавить стремительный рост производительности компьютеров и их ресурсов, в том числе памяти, что ставит на первое место надежность работы ПС, так как именно ненадежность программ становится основной причиной, сдерживающей дальнейшее развитие информационных технологий во всех сферах деятельности человеческого общества. Практика отработки и сопровождения программных систем показывает, что неэффективность системы, если в этом есть необходимость, может быть исправлена позднее, в то время как ненадежность достаточно трудно устранить. Абсолютная надежность программных систем была и остается недостижимой целью.
В порядке обсуждения ниже автором предлагается подход, который может быть использован для выбора тех требований, предъявляемых к системе, которые наиболее совместимы с другими требованиями [14]. Для наглядности рассмотрения и анализа рассмотренных зависимостей между основными требованиями, предъявляемыми к программным системам, и установления оптимального компромисса между конфликтующими требованиями, можно построить матрицу оценки уровня совместимости (или конфликтности) требований конкретного проекта (рис. 4.9). Элементы /и,у матрицы М принимают конкретные значения в зависимости от совместимости требований:
- • т,у — 1, если г-е требование 7} полностью совместимо с требованием 7);
- • ш;у = 0,75, если г-е требование Г, скорее совместимо с требованием 7};
- • ш,у = 0,5, если г-е требование Г, частично совместимо с требованием 7};
- • ту – 0,25, если г-е требование 7) скорее несовместимо с требованием 7};
- • пу — 0, если г-е требование 7} несовместимо с требованием 7}.
Матрица совместимости строится экспертом (опытным высококвалифицированным разработчиком) следующим образом. Рассматривается г-я строка матрицы и, учитывая введенную шкалу совместимости, для каждого у-го требования 7} определяется, по мнению эксперта, значение ту, определяющее его совместимость с требованием Г,. Заметим, что матрица не является симметричной относительно диагонали. Это связано с тем, что, рассматривая некоторое требование 7} как основное, можно определить его совместимость с некоторым другим требованием 7} иначе, чем в том случае, когда требование 7} рассматривается как основное.
Сбалансированность требований можно оценить следующим образом. Если для каждой г-й строки матрицы получить сумму ее элементов, то значение этой суммы 7?, будет характеризовать степень (рейтинг) совместимости требований 7} (гдеу = 1, 2, …, п, у Ф г) с требованием 7), которое считается основным. Таким образом, для каждой строки матри-цы г = 1, 2, …, п находим значение:
к; = Е“=1ти ’ ) ф 1 (4-3)
С другой стороны, получив сумму для каждого столбца матрицы, найдем рейтинг совместимости требования Г, для тех случаев, когда оно не является основным. Рейтинг совместимости в этом случае определяется следующим образом: для каждого столбца матрицы/= 1, 2, …, п находим значение
(4.4)
Общее значение рейтинга совместимости Я- некоторого требования 7} можно определить, складывая соответствующие ему значения Я, и 7?/, т.е.
(4.5)
Я? – Я1 +Я , у – г.
У П А С Б Д Ст. Г Пр. Н Рейт.
Универсальность ^И0Д5 1 0,25 0,3 0,3 0,3 0,25 0,25 0 2,8 5,25
Псих, факторы 1 1 1 0,8 0,75 1 1 6,3 11,75
Адаптируемость 1 0Д5]^И0Д5 0,5 0,3 0,3 0,25 0,25 0,5 2,5 5,5
Сопровождаемость 0,3 1 1 Щ 1 1 0,3 0,25 0,25 1 5,8 9,75
Безопасность 0,3 1 0,3 0,3 0,5 0,5 1 4,8 10,25
Документация 0,3 1 0,8 1 1~ЩИ(^5 0,5 0,5 1 6,3 11
Стоимость 0,3 0,25 0,3 0,25 0,3 ТГ1Щ0Д5 0,25 0,3 2 4,75
График 0,3 0,25 0,3 0,25 0,3 0,3 оТ^ЩоД5 0,3 2 4,75
Производительность 0,3 0,5 0,3 0,5 0,5 0,5 0,3 ОД5|^Що^5 3,3 6,5
Надежность 0 1 0,3 0,5 1 0,5 0,3 0,25 0Д5^Н 4 9,5
Рис. 4.9. Матрица уровня совместимости
Проведенные вычисления для матрицы, изображенной на рис. 4.9, показывают, что наилучшую совместимость с другими рассмотренными выше требованиями имеют требования по психологическим факторам, документации, безопасности, сопровождаемости и надежности.
Источник