Обновить
8K+
53
Alex Gusev@flancer

Я кодирую, потому что я кодирую…

9,2
Рейтинг
99
Подписчики
Отправить сообщение

Код переформатировался в комменте :( Исправил. Оба фрагмента объединены:


Скрытый текст
DROP TABLE IF EXISTS obj_trassa_attr_num;
DROP TABLE IF EXISTS ctx_lep_as_trassa, ctx_lep_as_uch, ctx_trassa_as_provod, ctx_trassa_as_uch_tr;
DROP TABLE IF EXISTS ctx_uch_lep_as_uch_tr, ctx_provod_as_uch_prov, ctx_uch_tr_as_uch_prov, ctx_lep_as_uch_tr;
DROP TABLE IF EXISTS obj_lep, obj_trassa, obj_provod, obj_uch_lep, obj_uch_trassa, obj_uch_provod;

--
--  Objects (реестры объектов)
--
CREATE TABLE obj_lep (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'ЛЭП';
CREATE TABLE obj_trassa (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Трасса';
CREATE TABLE obj_provod (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Провод';
CREATE TABLE obj_uch_lep (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Участок ЛЭП между опорами';
CREATE TABLE obj_uch_trassa (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Участок трассы между опорами';
CREATE TABLE obj_uch_provod (
  id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
)
  COMMENT = 'Участок провода между опорами';

--
--  Contexts (контексты/конструкции)
--
CREATE TABLE ctx_lep_as_trassa (
  lep    INT(10) UNSIGNED NOT NULL,
  trassa INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (lep, trassa),
  CONSTRAINT ctx_lep_as_trassa_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_lep_as_trassa_to_trassa FOREIGN KEY (lep) REFERENCES obj_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 1: ЛЭП как трассы';
CREATE TABLE ctx_lep_as_uch (
  lep INT(10) UNSIGNED NOT NULL,
  uch INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (lep, uch),
  CONSTRAINT ctx_lep_as_uch_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_lep_as_uch_to_uch FOREIGN KEY (uch) REFERENCES obj_uch_lep (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 2: ЛЭП как участки';
CREATE TABLE ctx_trassa_as_provod (
  trassa INT(10) UNSIGNED NOT NULL,
  provod INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (trassa, provod),
  CONSTRAINT ctx_trassa_as_provod_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_trassa_as_provod_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 3: трасса как провода';
CREATE TABLE ctx_trassa_as_uch_tr (
  trassa INT(10) UNSIGNED NOT NULL,
  uch_tr INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (trassa, uch_tr),
  CONSTRAINT ctx_trassa_as_uch_tr_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_trassa_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 4: трасса как участки трассы';
CREATE TABLE ctx_uch_lep_as_uch_tr (
  uch_lep INT(10) UNSIGNED NOT NULL,
  uch_tr  INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (uch_lep, uch_tr),
  CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_lep FOREIGN KEY (uch_lep) REFERENCES obj_uch_lep (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 5: участок ЛЭП как участок трассы';
CREATE TABLE ctx_provod_as_uch_prov (
  provod   INT(10) UNSIGNED NOT NULL,
  uch_prov INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (provod, uch_prov),
  CONSTRAINT ctx_provod_as_uch_prov_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_provod_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 6: провод как участок провода';
CREATE TABLE ctx_uch_tr_as_uch_prov (
  uch_tr   INT(10) UNSIGNED NOT NULL,
  uch_prov INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (uch_tr, uch_prov),
  CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 7: участок трассы как участок провода';
CREATE TABLE ctx_lep_as_uch_tr (
  lep    INT(10) UNSIGNED NOT NULL,
  uch_tr INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (lep, uch_tr),
  CONSTRAINT ctx_lep_as_uch_tr_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
    ON DELETE CASCADE,
  CONSTRAINT ctx_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Конструкция 8: ЛЭП как участок трассы';

--
-- Данные (объекты)
--
INSERT INTO obj_lep VALUES (1);
INSERT INTO obj_trassa VALUES (1), (2);
INSERT INTO obj_provod VALUES (1), (2);
INSERT INTO obj_uch_lep VALUES (1), (2);
INSERT INTO obj_uch_trassa VALUES (1), (2), (3);
INSERT INTO obj_uch_provod VALUES (1), (2), (3);

--
-- Данные (связи в контекстах)
--
INSERT INTO ctx_lep_as_trassa VALUES (1, 1), (1, 2);
INSERT INTO ctx_lep_as_uch VALUES (1, 1), (1, 2);
INSERT INTO ctx_trassa_as_provod VALUES (2, 1), (2, 2);
INSERT INTO ctx_trassa_as_uch_tr VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_lep_as_uch_tr VALUES (1, 2), (1, 3);
INSERT INTO ctx_provod_as_uch_prov VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_tr_as_uch_prov VALUES (2, 2), (2, 3);
INSERT INTO ctx_lep_as_uch_tr VALUES (1, 1), (1, 2), (1, 3);

--
--  Атрибуты объектов
--
CREATE TABLE obj_trassa_attr_num (
  id INT(10) UNSIGNED NOT NULL,
  value varchar(255) NOT NULL ,
  PRIMARY KEY (id),
  CONSTRAINT obj_trassa_attr_num_to_obj FOREIGN KEY (id) REFERENCES obj_trassa (id)
    ON DELETE CASCADE
)
  COMMENT = 'Номер трассы';

Картинку лучше открывать отдельно в новой вкладке, будет более читабельно. Схема данных навеяна Anchor Modeling.

Если вы оперируете объектами, а не их атрибутами, то для их представления вполне достаточно ID объекта и его типа/класса. Классические инструменты вполне позволяют это делать, если не закапываться в дебри. Ваша схема из статьи про ЛЭП/трассы/провода/участки очень хорошо укладывается в типичную RDBMS (MySQL в моем случае). Все, что с префиксом "obj" — это таблицы для желтых элементов вашей схемы, с префиксом "ctx" — для синих:


image


Вот SQL-код для построения структуры и заполнения ее данными:


Скрытый текст
DROP TABLE IF EXISTS ctx_lep_as_trassa, ctx_lep_as_uch, ctx_trassa_as_provod, ctx_trassa_as_uch_tr;
DROP TABLE IF EXISTS ctx_uch_lep_as_uch_tr, ctx_provod_as_uch_prov, ctx_uch_tr_as_uch_prov, ctx_lep_as_uch_tr;
DROP TABLE IF EXISTS obj_lep, obj_trassa, obj_provod, obj_uch_lep, obj_uch_trassa, obj_uch_provod;

— — Objects (реестры объектов)
— CREATE TABLE obj_lep (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'ЛЭП';
CREATE TABLE obj_trassa (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Трасса';
CREATE TABLE obj_provod (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Провод';
CREATE TABLE obj_uch_lep (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Участок ЛЭП между опорами';
CREATE TABLE obj_uch_trassa (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Участок трассы между опорами';
CREATE TABLE obj_uch_provod (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Участок провода между опорами';

— — Contexts (контексты/конструкции)
— CREATE TABLE ctx_lep_as_trassa (
lep INT(10) UNSIGNED NOT NULL,
trassa INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (lep, trassa),
CONSTRAINT ctx_lep_as_trassa_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_lep_as_trassa_to_trassa FOREIGN KEY (lep) REFERENCES obj_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 1: ЛЭП как трассы';
CREATE TABLE ctx_lep_as_uch (
lep INT(10) UNSIGNED NOT NULL,
uch INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (lep, uch),
CONSTRAINT ctx_lep_as_uch_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_lep_as_uch_to_uch FOREIGN KEY (uch) REFERENCES obj_uch_lep (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 2: ЛЭП как участки';
CREATE TABLE ctx_trassa_as_provod (
trassa INT(10) UNSIGNED NOT NULL,
provod INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (trassa, provod),
CONSTRAINT ctx_trassa_as_provod_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
ON DELETE CASCADE,
CONSTRAINT ctx_trassa_as_provod_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 3: трасса как провода';
CREATE TABLE ctx_trassa_as_uch_tr (
trassa INT(10) UNSIGNED NOT NULL,
uch_tr INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (trassa, uch_tr),
CONSTRAINT ctx_trassa_as_uch_tr_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
ON DELETE CASCADE,
CONSTRAINT ctx_trassa_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 4: трасса как участки трассы';
CREATE TABLE ctx_uch_lep_as_uch_tr (
uch_lep INT(10) UNSIGNED NOT NULL,
uch_tr INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (uch_lep, uch_tr),
CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_lep FOREIGN KEY (uch_lep) REFERENCES obj_uch_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 5: участок ЛЭП как участок трассы';
CREATE TABLE ctx_provod_as_uch_prov (
provod INT(10) UNSIGNED NOT NULL,
uch_prov INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (provod, uch_prov),
CONSTRAINT ctx_provod_as_uch_prov_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
ON DELETE CASCADE,
CONSTRAINT ctx_provod_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 6: провод как участок провода';
CREATE TABLE ctx_uch_tr_as_uch_prov (
uch_tr INT(10) UNSIGNED NOT NULL,
uch_prov INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (uch_tr, uch_prov),
CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE,
CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 7: участок трассы как участок провода';
CREATE TABLE ctx_lep_as_uch_tr (
lep INT(10) UNSIGNED NOT NULL,
uch_tr INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (lep, uch_tr),
CONSTRAINT ctx_lep_as_uch_tr_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 8: ЛЭП как участок трассы';

— — Данные (объекты)
— INSERT INTO obj_lep VALUES (1);
INSERT INTO obj_trassa VALUES (1), (2);
INSERT INTO obj_provod VALUES (1), (2);
INSERT INTO obj_uch_lep VALUES (1), (2);
INSERT INTO obj_uch_trassa VALUES (1), (2), (3);
INSERT INTO obj_uch_provod VALUES (1), (2), (3);

— — Данные (связи в контекстах)
— INSERT INTO ctx_lep_as_trassa VALUES (1, 1), (1, 2);
INSERT INTO ctx_lep_as_uch VALUES (1, 1), (1, 2);
INSERT INTO ctx_trassa_as_provod VALUES (2, 1), (2, 2);
INSERT INTO ctx_trassa_as_uch_tr VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_lep_as_uch_tr VALUES (1, 2), (1, 3);
INSERT INTO ctx_provod_as_uch_prov VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_tr_as_uch_prov VALUES (2, 2), (2, 3);
INSERT INTO ctx_lep_as_uch_tr VALUES (1, 1), (1, 2), (1, 3);


Если же вы захотите еще оперировать и атрибутами объекта, то вы можете добавить любое кол-во различных атрибутов (или наборов атрибутов, если они связаны друг с другом по отношению к объекту, как, например, Имя/Отчество/Фамилия). Вот структура для сохранения «номера трассы», например:

Скрытый текст
CREATE TABLE obj_trassa_attr_num (
id INT(10) UNSIGNED NOT NULL,
value varchar(255) NOT NULL,
PRIMARY KEY (id),
CONSTRAINT obj_trassa_attr_num_to_obj FOREIGN KEY (id) REFERENCES obj_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Номер трассы';


Вам нужна гибкость? Пожалуйста. Но заплатите за нее простотой.

Вот видите, приходится выделять "ведущего" (генератор значения для identity) и от него уже плясать. Можно хоть по одной таблице на атрибут сделать (что, кстати, 6NF и предусматривает), но identity values должны хранится в одном месте, если вы хотите обеспечить их уникальность и консистентность.


Этот подход не является единственно возможным, но является достаточно классическим — как надевать штаны через ноги. Другие варианты, повторюсь, также существуют и некоторые даже имеют своих адептов.

Сложнее всего отвечать на вопросы, имеющие очевидный ответ :) Где у вас ведется учет идентификаторов для новых экземпляров сущностей User — в user_auth, в user_pass, в приложении (в каком экземпляре, если идет балансировка нагрузки)? И что будет, если два процесса одновременно вводят разные данные (auth & pass) по одному пользователю?


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

И что мы имеем в итоге? Две независимые таблицы, каждая из которых имеет свой набор полей, включающий identity-поле, по значению которого и осуществляется сопоставление данных из одной таблицы данным из другой. Никаких внешних связей (foreign keys) друг с другом на уровне структур базы данных. Связывание данных идет в объектной модели на программном уровне.


CREATE TABLE user_auth (
  id int(10) UNSIGNED NOT NULL,
  username varchar(255) NOT NULL,
  ...
  PRIMARY KEY (id)
);

CREATE TABLE user_pass (
  id int(10) UNSIGNED NOT NULL,
  firstname varchar(255) NOT NULL,
  ...
  PRIMARY KEY (id)
);

Но ведь именно это я имел в виду, говоря "бред". А вы что имели в виду, говоря "связь 1:1"?

Паспортных с аутентификационными или аутентификационных с паспортными? Кто на кого ссылается? Где находится identity для экземпляра User'а — в паспортных данных или аутентификационных? Могут ли паспортные существовать без идентификационных и наоборот?

Связь чего с чем? Левых атрибутов User'а с правыми?

Неправильно называть разные конструкции одним и тем же понятием (User), обозначающим весь объект.

Вот и я за то — иметь в программе два разных типа к одному моделируемому объекту на данный момент большинству программистов "религия не позволяет"


А на родительский объект ссылаются по id.

А вот это "религия позволяет". И если у двух разных конструкций (типов) есть совпадение по атрибутам, то ООП-религия позволяет нам ввести промежуточную конструкцию с общими атрибутами и назвать ее "абстрактным типом". И сделать для нее отдельную таблицу и встроить ее в цепочку наследования тоже допустимо.

Ага, так и есть. Вот только иметь в программе два разных типа к одному моделируемому объекту на данный момент большинству программистов "религия не позволяет". Это как иметь в БД две таблицы с различными атрибутами для одной и той же сущности User. Это же бред? Бред. Вот и сливают все атрибуты из различных моделей User'а в одну таблицу и делают одну общую, универсальную модель. Так кошерно.

Программирование — это тоже моделирование. И довольно гибкое. Если уж нельзя в программировании, то о каком "моделировании предметной области" вы сейчас говорите?

Никто не запрещает переименовать "короткую" переменную при "разрастании" однострочника. Это косяк не того, кто однострочник составил, а того, кто его развернул.

Не меняется то, что называется английским словом identity. И именно это мы связываем с объектом в целом.

Насколько я понял, предполагается в приложении иметь различные модели (с различным набором атрибутов) для одного и того же identity.

Насколько я понял, коллега maxstroy имеет в виду, что один объект реального мира может в приложении моделироваться множеством программных объектов/типов. Причем каждый программный объект описывает со своей точки зрения тот же самый объект, что и остальные программные объекты из этого множества. А приложение должно само выбирать, с какой программной моделью реального объекта ему сейчас наиболее удобно работать. Это как классическая и релятивистская механики — говорим об одном и том же (движение), но с разных точек зрения (субсветовая скорость или обычная).


Коллега michael_vostrikov же говорит о том, что программная модель является лишь приближением к реальной до некоторого уровня детализации и принципиально невозможно сделать универсальную программную модель реального объекта.


Совмещая обе точки зрения в применении к примеру с (не)делимым договором, в приложении может быть два алгоритма — для работы с сущностями, как с атомами, и для работы с ними же, как с композитами. И приложение само, в зависимости от контекста, может выбирать, является ли объект "договор" в текущем контексте атомом (листом дерева) или композитом (узлом дерева).

К сожалению не смогу :( Давно это было, сын уже институт заканчивает. Помню, что меня поразил сам факт наличия в школьном учебнике задачи с неоднозначным решением. Я ему еще тогда авторитетно объяснял, насколько калечит мышление молодого поколения такой вот подход. Каждая задача, мол, имеет одно единственное верное решение и главное — его найти. Каюсь, был неправ.


Но, если навскидку, то путей в лабиринте от входа до выхода может быть более одного. Какой из них правильный?


Сын подсказал еще вариант — тесты на знание Правил Дорожного Движения. Если есть свод правил с противоречащими пунктами (любой кодекс, если покопаться, имеет противоречащие пункты), то на их основании можно сформулировать задачи, имеющие более одного (не)правильного решения — зависит от порядка применения противоречащих пунктов. В народе даже поговорка сложилась "закон — что дышло: куда повернёшь — туда и вышло"

Весьма впечатлен, коллега. Ваша статья из серии "точек кристаллизации" — позволяет различным кусочкам пазла сложиться в единую картинку. Вроде бы все слова давно знакомы — декомпозиция, анализ, синтез, объекты, функции, операции, а вот в такой комбинации приобретают интереснейшую форму.


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


Вопрос границ применимости предлагаемых решений — весьма недооценен, КМК. И чем сложнее разрабатываемые системы, тем больше вероятность, что на одни и те же вещи придется смотреть с разных точек зрения (представлять их разными программными конструкциями).

Брокеры существуют уже не один десяток лет. И хотя непонятно, откуда они взялись, но как-то умудряются обходить те большие проблемы, которые вы видите.

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

Очевидно! Именно поэтому Агент должен выбирать такую политику, чтобы он встраивался в цепочку "Пользователь — Агент — Разработчик" по правилу "win — win — win", а не по правилу "какой-то хрен с горы".


Вот видите, вы на интуитивном уровне чувствуете, как работает эта схема :)

Информация

В рейтинге
867-й
Откуда
Рига, Латвия, Латвия
Дата рождения
Зарегистрирован
Активность

Специализация

Фулстек разработчик
Ведущий
От 3 000 €
JavaScript
HTML
CSS
Node.js
Vue.js
Веб-разработка
Progressive Web Apps
PostgreSQL
MySQL
GitHub