Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
«Организация бизнес-логики со сложной схемой да...
Search
WebDev
December 06, 2014
Programming
0
110
«Организация бизнес-логики со сложной схемой данных», Тимофей Кукушкин, ТриЛан Вологда
Расскажу о том, какой путь мы прошли, реализуя бизнес-логику сложного enterprise решения.
WebDev
December 06, 2014
Tweet
Share
More Decks by WebDev
See All by WebDev
«Тестирование веб-приложений», Андрей Кишкин, ТриЛан Вологда
webdevconf
0
110
«Еще раз про MVC и веб-фреймворки в enterprise решениях», Дмитрий Кукушкин, ТриЛан Вологда
webdevconf
0
77
Секретный доклад об управлении проектами, Наташа Юматова, Дмитрий Чернов, Трилан
webdevconf
0
78
«Низкокалорийный дизайн. Диета для сайта», Ольга Сбоева, ТриЛан Вологда
webdevconf
0
110
«Стек технологий и приемов при разработке серверной части мобильного приложения», Сергей Аникин, ТриЛан Вологда
webdevconf
0
450
Other Decks in Programming
See All in Programming
オープンソースソフトウェアへの解像度🔬
utam0k
17
3.1k
Claude Agent SDK を使ってみよう
hyshu
0
1.4k
Leading Effective Engineering Teams in the AI Era
addyosmani
7
640
はじめてのDSPy - 言語モデルを『プロンプト』ではなく『プログラミング』するための仕組み
masahiro_nishimi
4
16k
Foundation Modelsを実装日本語学習アプリを作ってみた!
hypebeans
0
130
Catch Up: Go Style Guide Update
andpad
0
260
Pythonに漸進的に型をつける
nealle
1
130
What Spring Developers Should Know About Jakarta EE
ivargrimstad
0
510
Google Opalで使える37のライブラリ
mickey_kubo
3
150
コードとあなたと私の距離 / The Distance Between Code, You, and I
hiro_y
0
190
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
660
CSC305 Lecture 08
javiergs
PRO
0
280
Featured
See All Featured
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
Documentation Writing (for coders)
carmenintech
75
5.1k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Testing 201, or: Great Expectations
jmmastey
45
7.7k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.1k
Building a Scalable Design System with Sketch
lauravandoore
463
33k
Code Reviewing Like a Champion
maltzj
526
40k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Making the Leap to Tech Lead
cromwellryan
135
9.6k
Transcript
Организация бизнес логики со сложной схемой данных
Особенности схемы данных заказчика: • Часть данных внешняя, часть “локальная”
• Многоязычность • Простые типы данных • Нет ссылочной целостности
Подсистемы: • Система версионирования • Система блокировок • Система ревизионирования
• API
Как все начиналось
Толстые тупые уродливые контроллеры Class Based Views
• Для каждой модели свое приложение. • Вся обработка и
получение данных в приложениях. • Views отвечают только за взаимодействие пользователя и приложения “Приложения”
class ArticleApp(BaseApp): model = Article multilingual_model = MultilingualArticle common_fields =
['author_id'] multilingual_fields = ['title', 'content'] external_fields = ['author', 'title'] search_fields = ['title'] aliases = {'author_id': 'author'} article_app = ArticleApp()
• Прослойка между системой версионирования и моделью Django ORM •
Для каждой модели свой класс интерфейса. • Работает строго с одним объектом “Интерфейсы”
class ArticleInterface(interfaces.Interface): model = Article multilingual_model = MultilingualArticle common_fields =
['author_id'] multilingual_fields = ['title', 'content'] external_fields = ['author', 'title'] interfaces.register(ArticleInterface)
class ArticleApp(BaseApp): interface_class = ArticleInterface search_fields = ['title'] aliases =
{'author_id': 'author'} article_app = ArticleApp()
• Метаданные фрагментированы • Нет четкого публичного API • Приватное
API течет внаружу Что по-прежнему плохо
Схема данных в YAML формате
Вспомогательный класс для генерации моделей
class ArticleInterface(interfaces.Interface): model = interfaces.Model( 'Article', common_fields=[ fields.IntegerField('id', label='ID', primary_key=True,
source='Site') fields.ForeignKey('author_id', label=u'автор', source='Site', required=True, to=AuthorInterface, property_name='author') ], multilingual_fields=[ fields.TextField('title', label=u'Заголовок', required=True, source='Site', searchable=True) fields.TextField('content', label=u'Содержимое', required=False, source='Local') ], label=u'Статья' ) interfaces.register(ArticleInterface) _Article = ArticleInterface.model _MultilingualArticle = ArticleInterface.multilingual_model
class ArticleApp(BaseApp): interface_class = ArticleInterface article_app = ArticleApp()
class ArticleInterface(interfaces.Interface): name = 'Article' common_fields = [ fields.IntegerField('id', label='ID',
primary_key=True, source='Site') fields.ForeignKey('author_id', label=u'автор', source='Site', required=True, to=AuthorInterface, property_name='author') ] multilingual_fields = [ fields.TextField('title', label=u'Заголовок', required=True, source='Site', searchable=True) fields.TextField('content', label=u'Содержимое', required=False, source='Local') ] label = u'Статья' interfaces.register(ArticleInterface) _Article = ArticleInterface.model _MultilingualArticle = ArticleInterface.multilingual_model
Менеджеры
>>> from articles.models import ArticleInterface >>> objects = ArticleInterface.objects.filter( ...
include_removed=True)[:3] >>> objects [<articles.models.ArticleInterface u'Starbucks'>, <articles.models.ArticleInterface u'Lorem ipsum'>, <articles.models.ArticleInterface u'Dolor sit amet'>] >>> objects.count() 3 >>> for instance in objects: ... print instance.data.id 197 196 195
Переносим все операции над данными в интерфейсы
>>> object = objects[0] >>> object.data.locales['ru'].Title 'Starbucks' >>> version =
object.change( ... user, ... common_data={'author_id': 10}, ... locales_data={'ru': {'title': 'Bartsucks', 'content': 'Lorem ipsum'}} ... ) >>> new_object, version = ArticleInterface.objects.create( ... user, ... common_data={'author_id': 1}, ... locales_data={'ru': {'title': 'foo', 'content': 'bar'}} ... ) >>> type(new_object) articles.models.ArticleInterface
В итоге • Описание схемы данных через интерфейсы полностью отражает
схему данных заказчика • Четкое публичное API • Атомарность операций
Вопросы?