И тут возник один интересный вопрос. Преамбула этого вопроса изложена в этом посте http://forum.yurclub...50#entry4437601
Кратенький предметный ликбез
Если мы берем исходники любой программы, то там будут функции высокой абстрации, как бы на все случаи жизни и будут функции высокой конкретики, которые кроме как в этом продукте больше нигде и не нужны.
например функция, которая по ключу сначала проверяет есть ли в списке эта запись, если есть, то возвращает её, если нет, то возвращает пустую строку
string safeGet(stringHash list, string key)
{
return list.contains(key) ? list[key] : "";
}
это пример очень функции высокой абстракции, потому что она применяется в коде постоянно и сложно представить себе компьютерную программу без этой функции. эта функция есть во всех наших программах
и более того, если бы например даже мы продадим эту функцию в составе исходников, на которые мы продали исключительные права, то если мы захотим написать себе снова эту функцию, то иначе как вот так, мы больше её никак и не напишем
единственное, что тут можно менять - это сигнатуры, то есть имя функции и имена переменных
например
string safe_get_string(stringHash listString, string keyPosition)
{
return listString.contains(keyPosition) ? listString[keyPosition] : "";
}
эта функция будет делать 100% того, что и первая. по функционалу они абсолютно идентичны
при этом обратите внимание
string и stringHash - это тоже сигнатуры, то есть реально есть некие участки кода, которые задают и их, но мы не можем их менять, потому что они прописаны в библиотеках, которые мы используем
библиотеки - это тоже некий программный код, написанный кем-то
как правило он состоит сплошь из функций высокой абстракции, что собственно говоря и делает эти библиотеки пригодными для повторного использования в самых разных проектах
библиотеки бывают платные и бесплатные (опенсорсные от англ. open source)
сигнатуры string и stringHash расположены в опенсорсной библиотеке, то есть при использовании мы ничего платить не должны, но и вносить изменения мы не можем, причем тут даже дело не в юридическом аспекте, а тупо, если переименовать string например my_super_string, то могут вылезти какие-то скрытые ошибки, все упадет или будет работать криво, а копаться во внутренностях чужой библиотеки - это такая форма мазохизма с точки зрения трудозатрат)))
ну и в завершении предметного ликбеза приведу пример функции низкой абстракции
milkFarmCode getMilkFarmCode(string companyId)
{
return packMilkFarmCode(dataServer()->getCompanyName(companyId) + "_farm");
}
ну вот есть такая функция в конкретном проекте и эта функция никогда больше нигде кроме как в этом проекте использоваться не будет вообще не потому, что это технические невозможно, а потому что в программе для строителей или в программе для логистической компании функция получения кода молочной фермы не нужна)))
Варианты действий
Теперь собственно по ситуации.
Если мы передаем код вместе с исключительными правами (т.е. продаем все с потрохами), то на функции низкой абстракции нам наплевать, то есть про функцию getMilkFarmCode() мы можем смело забыть, но вот что касается функций высокой абстракции, то тут как бы наплевать не получается, потому что мы точно знаем, что нам без неё никак не жить.
Классика: выделение движков.
Есть у нас в отрасли такое действие под названием "выделение движка" или "создание двигателя"
О чем речь?
Да просто разработчик берет сгребает все эти функции высокой абстракции в отдельную кучу и называет её движком. По сути он создает свою отдельную библиотеку, предназначенную для повторного использования.
Как я уже приводил пример, мы используем сторонюю библиотеку в которой живут сигнатуры string и stringHash, так и тут мы можем выделить нашу функцию safeGet() и другие подобные функции высокой абстракции в отдельную папку и назвать их движком. А потом таскать этот движок из проекта в проект.
Некоторые команды разработчиков поступают даже так: они выкладывают полученный движок в открытый доступ под свободной лицензией, чтобы все могли ей пользоваться и соотв., когда продают исключительные права на программный код, то они пишут, что заказчик сам получает лицензию на движок, который распространяется бесплатно и лежит там-то, тыры пыры.
Кто-то движок не выкладывает, а его только лицензирует, то есть выписывает разрешение на использование двигателя, но права на двигатель сохраняет у себя.
Бездвижковый вариант.
Чисто практически провести границу, где заканчивается движок, а где начинается код высокой абстракции... провести такую границу очень сложно, она постоянно плавает. То, что сегодня было конкретным, уже завтра стало абстрактным, а то, что вчера было абстрактным, оказалось, что не такое оно и абстрактное, а использовалось всего один раз только в конкретном случае и больше нафиг никому не надо. То есть выделение двигателя - это всегда такая чисто условная процедура.
Мне кажется, что юристам должно быть это очень понятно, потому что составление договоров - это тоже чем-то похоже на программирование. Бывают некоторые формулировки, которые кочуют из договора в договор, а бывают чисто только под конкретный случай.
Но в нашем случае, выделение движков, мучения с лицензиями и вся сопутствующая этому организация - это слишком затратная процедура, чреватая высоким риском ошибок. Поэтому сейчас мы размышляем на тему как можно с одной стороны передать заказчику проект с потрохами, а с другой стороны, не лишать себя возможности пользоваться очевидными паттернами типа функции safeGet(), пример которой я привел выше.
Тело этой функции настолько очевидно, что по другому как-то реализовать просто не получится. Если запись есть, то возвращаем запись, если нет, то возвращаем пустую запись. Это банально, это просто, это очевидно.
Более того, это насколько очевидно, что я убежден, что во многих проектах разных команд разработчиков по всему миру, не связанных друг с другом и не знающих о существовании друг друга в их проектах есть вот эта самая функция, только у каждого она называется по-разному, но я не исключаю, что названия могут при этом повторяться, потому что названия safeGet(), list, key это тоже очевидные названия.
Да если копнуть историю вопроса, то мы их и не придумывали, а просто их каждый программист собирает за свою карьеру, а где он их увидел, в каком из тысяч листингов, которые ему пришлось изучить за всю свою жизнь, то это уже и не вспомнить.
В итоге пока напрашивается один очень некрасивый вариант...
Мы можем автоматически (технические такая возможность есть) заменить все сигнатуры на случайные хеши.
например, мы можем превратить функцию safeGet() вот в это
string f54f65f4654f(stringHash f54f65f4, string g546g54g65)
{
return f54f65f4.contains(g546g54g65) ? f54f65f4[g546g54g65] : "";
}
и знаете, что самое веселое?
то что эта функция будет отлично работать, потому что компьютеру глубоко пофиг на красоту сигнатур, это только нам людям важно чтобы были понятные сигнатуры list, key, а компьютеру пофиг
единственное, что в этом случае будет моральное препятствие, потому что заказчику, которому мы продаем этот код вместе с исключительными правами, они скоро разместят у нас ещё один крупный заказ и если мы передадим им вот такой код, то в наших отношениях может возникнуть некая напряженность)))
Итого
Если мы не придумаем ничего лучше до 15 ноября, то запасной вариант, по которому мы собрались действовать такой:
мы проведем сигнатурные подмены на более читаемые варианты, например safeGet() можно заменить на что-то типа get_safe_position_in_list()
но
1) придумывать новые имена для всех сигнатур в проекте - это будет нехилое вскипание мозга для тех, кто это будет делать)))
2) если этот код попадет в руки специалистов компании заказчика, которые эти исходники покупает, то те обязательно почуют, что же именно было сделано с кодом, потому что и ежу понятно, что ни один программист в здравом уме и трезвой памяти не станет называть функцию высокой абстракции, которая в проекте используется сотни раз, не станет он называть её так длинно get_safe_position_in_list() и если они об этом доложат начальству, то блин опять могут возникнуть напряженности в отношениях...
поэтому может у кого-нибудь есть варианты как можно поступить в нашем случае проще?


