Интересная идея. Только для корректности поменяйте "магниты" на "электрические заряды" и "волны" на "поля". Магниты не могут лишь отталкиваться, не притягивясь. И волн в такой системе нет.
Хотите освоить — посмотрите введение к официальной документации tikz. В нем последовательным усложнением строятся полноценные примеры графиков и диагамм. Это хорошая отправная точка.
Согласен, конечно. Мы тут обсуждали оформление, а не содержание.
В тексте была откуда-то скопированная png-картинка. Моя svg-картинка сделана в латехе с пакетом tikz. Способ не без проблем: человеку без опыта тяжело сразу готовить такие картинки. Зато исходник можно править на лету, не перерисовывая картинку. Я вот за 5 минут поменял точки на столбцы, и диаграмма стала понятнее:
В простейшем случае вы можете изменить положение точки остановки. Например, если координата блока из демонстрации должна лежать между 0 и 200, а мышка уходит, например, в 400, то вычислить итоговое положение можно так: x = 200 + (400 — 200) * 0.1 = 220. Коэффициент 0.1 отвечает за силу залипания: чем меньше коэффициент, тем больше залипание. Вот доработанный пример.
В более сложных случаях придется вводить силы и честно решать дифференциальные уравнения.
Вы бы сразу написали про версионирование API :) В подходе, который я описал выше, конечно, не получится сделать версионирование без существенной доработки.
Если говорить про наш случай, то у нас не всё настолько просто, чтобы пользоваться оберткой над монгой, что бы это ни было. Иногда бывает, что поля одной сущности для API хранятся в нескольких таблицах. Иногда за сущностями обращаемся к другим приложениям по их API. Но всё и не настолько сложно, чтобы заботиться о версионировании API или сериализаторах, о которых речь шла выше.
Я понимаю ваши аргументы про MVC, но они меня не убеждают. Я всё равно вижу принципиальную разницу между приложениями, в которых есть пользовательский интерфейс, и в котором его нет. Можно взять для примера графический редактор и консольную программу конвертации графики типа ImageMagick. У них может быть много общего (библиотечного) кода. В первом случае MVC говорит, как организовать код, отвечающий за взаимодействие с пользователем. Во втором случае MVC ничего полезного не говорит. Можно, конечно, формально соотнести фрагменты кода с представлением или с моделью. Но зачем?
I don't like MVC because that's not how the web works. Symfony2 is an HTTP framework; it is a Request/Response framework. That's the big deal. The fundamental principles of Symfony2 are centered around the HTTP specification.
I don't like MVC because the web has evolved a lot in the recent years and some projects are much different than projects we had some years ago. Sometimes, you just need a way to create a REST API. Sometimes, the logic is mostly in the browser and the server is just used to serve data (think backbone.js for instance). And for these projects, you don't need an MVC framework. You need something that handles a Request and returns a Response. You need a framework that implements the HTTP specification. HTTP streaming is yet another example that does not fit well with the MVC pattern.
Напишите статью, если есть материал и желание. Вы хорошо объясняете.
Нелогично то, что для наследования контекста достаточно заменить область видимости private на protected/public. Было бы естественнее менять контекст при переопределении метода.
Можно сколько угодно заниматься казуистикой и утверждать, что json на выходе REST API — это "представление". Это не отменяет принципиальной разницы между организацией (десктопного) приложения, в котором пользователь нажимает на кнопки и HTTP API. В первом действительно можно сделать активную модель, события и настоящее управление представлением из модели. Во втором жизненный цикл "приложения" ограничен обработкой запроса и формированием ответа, по крайней мере на PHP.
Мало того, что MVC "притянут за уши". В контексте веб-программирования MVC — это вредный паттерн. Он приводит к тому, что у неопытных разработчиков роль модели играет слой работы с БД, роль представления — шаблоны, а бизнес-логика располагается в толстых контроллерах.
V не может быть одновременно и на клиенте, и на сервере.
Вообще, MVC — это шаблон проектирования не любого приложения, а приложения с пользовательским интерфейсом. Об этом часто забывают. У API нет пользовательского интерфейса. Если всё равно внедрять MVC через силу, получится притянутое за уши V и каша в M. Лучше сразу честно признать, что слоев на бекенде REST API много, и они не MVC: https://habrahabr.ru/post/267125/
Со статическим свойством в абстрактном классе тоже на самом деле были проблемы. Если я правильно помню, код там примерно такой, и он работает не так как хотелось бы для кеширования в контексте класса:
<?php
class A
{
protected static $cache;
public function printClass ()
{
if (static::$cache === null) {
static::$cache = get_class($this);
}
echo static::$cache, ' ', get_class($this), "\n";
}
}
class B extends A
{
}
class C extends A
{
}
class D extends C
{
}
class E extends A
{
public function printClass()
{
parent::printClass();
}
}
$b = new B();
$b->printClass(); // B B
$c = new C();
$c->printClass(); // B C
$d = new D();
$d->printClass(); // B D
$e = new E();
$e->printClass(); // B E
Если подумать, то один сериализатор может быть тривиальным. У нас это клиентский сериализатор :)
Для понимания контекста замечу, что речь идет о REST API для одностраничного приложения на JS. Большинство операций — CRUD. Часть данных сохраняется в БД, часть уходит в API других сервисов, например, в биллинг. Кроме валидации особой бизнес-логики у нас нет.
Бывший коллега придумал интерфейс сущности с двумя методами сериализации: EntityInterface::toStoreParams() и EntityInterface::toClientModel(). Я не вижу проблемы в существовании самих этих методов. У нас такое приложение, что каждая сущность передается на клиент и почти каждая сохраняется в БД.
В этом подходе сериализация в JSON для REST API занимает выделенное положение по сравнению с сериализацией для других целей. Она происходит без дополнительных сервисов. Типичный контроллер содержит код вроде
$userCollection = $userDataMapper->findBy(...);
return new JsonResponse([
'users' => $userCollection->toClientModels()
])
Движение данных в обратную сторону уже идет через дата-маппер:
В типовом дата-маппере вызывается toStoreParams(). Но если требуется более сложная логика по сохранению сущности (запись в две таблицы, запись в очередь и т. д.), мы переопределяем метод UserDataMapper::insert() и сериализуем данные, полученные через геттеры сущности.
В "Tex2Cms" пропущена буква, и по этому буквосочетанию ничего не гуглится. Так что оставлю ссылку на пост о редакторе и на сам редактор.
Интересная идея. Только для корректности поменяйте "магниты" на "электрические заряды" и "волны" на "поля". Магниты не могут лишь отталкиваться, не притягивясь. И волн в такой системе нет.
Переделать — не сложно, но и не просто :)
Хотите освоить — посмотрите введение к официальной документации tikz. В нем последовательным усложнением строятся полноценные примеры графиков и диагамм. Это хорошая отправная точка.
В тексте была откуда-то скопированная png-картинка. Моя svg-картинка сделана в латехе с пакетом tikz. Способ не без проблем: человеку без опыта тяжело сразу готовить такие картинки. Зато исходник можно править на лету, не перерисовывая картинку. Я вот за 5 минут поменял точки на столбцы, и диаграмма стала понятнее:
Вот исходник:
А смысл ждать? Для этой цели я сделал редактор математических текстов (см. пост с описанием). С тех пор формулы в большей части постов тянутся с моего сервиса.
В 2000 и ME другой оттенок окна. Не такой нейтрально-серый, чуть светлее и слегка красноват. Так что остается Windows 98.
Зависит от задачи.
В простейшем случае вы можете изменить положение точки остановки. Например, если координата блока из демонстрации должна лежать между 0 и 200, а мышка уходит, например, в 400, то вычислить итоговое положение можно так: x = 200 + (400 — 200) * 0.1 = 220. Коэффициент 0.1 отвечает за силу залипания: чем меньше коэффициент, тем больше залипание. Вот доработанный пример.
В более сложных случаях придется вводить силы и честно решать дифференциальные уравнения.
У меня такое изредка воспроизводится, если быстро водить мышкой. Я не стал полировать демо-код, извините :)
Да, было бы интересно прочитать.
Вы бы сразу написали про версионирование API :) В подходе, который я описал выше, конечно, не получится сделать версионирование без существенной доработки.
Если говорить про наш случай, то у нас не всё настолько просто, чтобы пользоваться оберткой над монгой, что бы это ни было. Иногда бывает, что поля одной сущности для API хранятся в нескольких таблицах. Иногда за сущностями обращаемся к другим приложениям по их API. Но всё и не настолько сложно, чтобы заботиться о версионировании API или сериализаторах, о которых речь шла выше.
Я понимаю ваши аргументы про MVC, но они меня не убеждают. Я всё равно вижу принципиальную разницу между приложениями, в которых есть пользовательский интерфейс, и в котором его нет. Можно взять для примера графический редактор и консольную программу конвертации графики типа ImageMagick. У них может быть много общего (библиотечного) кода. В первом случае MVC говорит, как организовать код, отвечающий за взаимодействие с пользователем. Во втором случае MVC ничего полезного не говорит. Можно, конечно, формально соотнести фрагменты кода с представлением или с моделью. Но зачем?
Даже Фабиен вот пишет:
Напишите статью, если есть материал и желание. Вы хорошо объясняете.
Нелогично то, что для наследования контекста достаточно заменить область видимости private на protected/public. Было бы естественнее менять контекст при переопределении метода.
Я про тот MVC, о котором написано в Википедии.
Можно сколько угодно заниматься казуистикой и утверждать, что json на выходе REST API — это "представление". Это не отменяет принципиальной разницы между организацией (десктопного) приложения, в котором пользователь нажимает на кнопки и HTTP API. В первом действительно можно сделать активную модель, события и настоящее управление представлением из модели. Во втором жизненный цикл "приложения" ограничен обработкой запроса и формированием ответа, по крайней мере на PHP.
Мало того, что MVC "притянут за уши". В контексте веб-программирования MVC — это вредный паттерн. Он приводит к тому, что у неопытных разработчиков роль модели играет слой работы с БД, роль представления — шаблоны, а бизнес-логика располагается в толстых контроллерах.
Тем не менее, REST API на сервере — это не приложение с пользовательским интерфейсом. Даже название — API — намекает, что это программный интерфейс.
V не может быть одновременно и на клиенте, и на сервере.
Вообще, MVC — это шаблон проектирования не любого приложения, а приложения с пользовательским интерфейсом. Об этом часто забывают. У API нет пользовательского интерфейса. Если всё равно внедрять MVC через силу, получится притянутое за уши V и каша в M. Лучше сразу честно признать, что слоев на бекенде REST API много, и они не MVC: https://habrahabr.ru/post/267125/
А почему вы считаете, что REST API — это UI?
У нас Ember, "MVC" на клиенте и всё такое. API на сервере больше к M относится, а не к V.
Со статическим свойством в абстрактном классе тоже на самом деле были проблемы. Если я правильно помню, код там примерно такой, и он работает не так как хотелось бы для кеширования в контексте класса:
Если подумать, то один сериализатор может быть тривиальным. У нас это клиентский сериализатор :)
Для понимания контекста замечу, что речь идет о REST API для одностраничного приложения на JS. Большинство операций — CRUD. Часть данных сохраняется в БД, часть уходит в API других сервисов, например, в биллинг. Кроме валидации особой бизнес-логики у нас нет.
Бывший коллега придумал интерфейс сущности с двумя методами сериализации:
EntityInterface::toStoreParams()иEntityInterface::toClientModel(). Я не вижу проблемы в существовании самих этих методов. У нас такое приложение, что каждая сущность передается на клиент и почти каждая сохраняется в БД.В этом подходе сериализация в JSON для REST API занимает выделенное положение по сравнению с сериализацией для других целей. Она происходит без дополнительных сервисов. Типичный контроллер содержит код вроде
Движение данных в обратную сторону уже идет через дата-маппер:
В типовом дата-маппере вызывается
toStoreParams(). Но если требуется более сложная логика по сохранению сущности (запись в две таблицы, запись в очередь и т. д.), мы переопределяем методUserDataMapper::insert()и сериализуем данные, полученные через геттеры сущности.