|
129 | 129 | Given I am an author user |
130 | 130 | And I have an article |
131 | 131 | When I go to the article page |
132 | | - pre |
| 132 | + pre.fragment |
133 | 133 | code.python. |
134 | 134 | @given('I am an author user') |
135 | 135 | def author_user(ctx): |
@@ -177,39 +177,117 @@ html |
177 | 177 | p мы начали пилить dry-python |
178 | 178 | p набор библиотек, который навязывает писать бизнеслогику |
179 | 179 | section |
180 | | - p сториз |
181 | | - section |
182 | | - p пример dsl |
183 | | - p именно dsl начали делать больше случайно |
184 | | - p но потом получили профиты (о них дальше) |
185 | | - p это работает ... |
186 | | - section |
187 | | - p пример реализации шагов |
188 | | - section |
189 | | - p решение: |
190 | | - p начали отвязывать код того проекта написанного на обсерверах |
191 | | - p мы так же получили раздельные шаги с хорошым переиспользованием |
192 | | - p DDD - тот самый ясный язык |
| 180 | + img(src="https://raw.githubusercontent.com/dry-python/brand/master/logo/stories.png").plain |
| 181 | + p Define a user story in the business transaction DSL. |
| 182 | + p Separate state, implementation and specification. |
193 | 183 | section |
194 | | - p жили не тужили всё было хорошо |
195 | | - p всё было в постгресе |
196 | | - p все данные и правила с ними связанные в realtion mapper |
197 | | - p пришёл бизнес |
198 | | - p сказал что так-то так-то интегрируемся переезжаем |
199 | | - p половина данных переехала в firebase |
200 | | - section |
201 | | - p google firebase это |
202 | | - section |
203 | | - p в результате отвалилась вся возможность работы с данными |
204 | | - p проблема: нет явно прописанных правил о данных, которыми живёт проект |
205 | | - p DDD: нет модели |
| 184 | + h2 Specification DSL |
| 185 | + pre |
| 186 | + code.python. |
| 187 | + from stories import story, arguments |
| 188 | + |
| 189 | + class Purchase: |
| 190 | + @story |
| 191 | + @arguments("invoice_id", "user") |
| 192 | + def buy(I): |
| 193 | + I.find_order |
| 194 | + I.find_price |
| 195 | + I.find_invoice |
| 196 | + I.check_balance |
| 197 | + I.persist_payment |
| 198 | + I.persist_purchase |
| 199 | + I.send_purchase_notification |
| 200 | + aside.notes |
| 201 | + p пример dsl |
| 202 | + p именно dsl начали делать больше случайно |
| 203 | + p но потом получили профиты (о них дальше) |
| 204 | + p это работает ... |
206 | 205 | section |
207 | | - p attrs/dataclasses dry-structures lombok |
| 206 | + h2 Steps implementation |
| 207 | + pre |
| 208 | + code.python. |
| 209 | + from stories import Failure, Success |
| 210 | + |
| 211 | + class Purchase: |
| 212 | + # ... |
| 213 | + |
| 214 | + def find_invoice(self, ctx): |
| 215 | + invoice = Invoice.objects.get(pk=ctx.invoice_id) |
| 216 | + return Success(invoice=invoice) |
| 217 | + |
| 218 | + def check_balance(self, ctx): |
| 219 | + if ctx.user.can_pay(ctx.invoice): |
| 220 | + return Success() |
| 221 | + else: |
| 222 | + return Failure() |
| 223 | + aside.notes |
| 224 | + p пример реализации шагов |
| 225 | + p решение: |
| 226 | + p начали отвязывать код того проекта написанного на обсерверах |
| 227 | + p мы так же получили раздельные шаги с хорошым переиспользованием |
| 228 | + p DDD - тот самый ясный язык |
| 229 | + section |
| 230 | + img(src=require("./pics/postgresql.png") height="100" style=" padding-right: 70px;").plain |
| 231 | + img(src=require("./pics/firebase.png") height="100" style=" padding-right: 70px;").plain |
| 232 | + aside.notes |
| 233 | + p жили не тужили всё было хорошо |
| 234 | + p всё было в постгресе |
| 235 | + p все данные и правила с ними связанные в realtion mapper |
| 236 | + p пришёл бизнес |
| 237 | + p сказал что так-то так-то интегрируемся переезжаем |
| 238 | + p половина данных переехала в firebase |
| 239 | + section |
| 240 | + h2 Problems |
| 241 | + h4 we does not have tooling to work with data |
| 242 | + h4 there is no data contracts writted in code |
| 243 | + aside.notes |
| 244 | + p в результате отвалилась вся возможность работы с данными |
| 245 | + p проблема: нет явно прописанных правил о данных, которыми живёт проект |
| 246 | + p DDD: нет модели |
| 247 | + section |
| 248 | + img(src=require("./pics/attrs.png") height="100" style=" padding-right: 70px;").plain |
| 249 | + img(src=require("./pics/dry-rb.png") height="100" style=" padding-right: 70px;").plain |
| 250 | + img(src=require("./pics/lombok.png") height="100" style=" padding-right: 70px;").plain |
| 251 | + aside.notes |
| 252 | + p attrs/dataclasses dry-structures lombok |
208 | 253 | section |
209 | | - p начали прописывать в этих самых датаклассах контракты данных |
| 254 | + h2 dataclasses |
| 255 | + pre |
| 256 | + code.python. |
| 257 | + from dataclasses import dataclass |
| 258 | + from typing import List, NewType |
| 259 | + |
| 260 | + OrderId = NewType("OrderId", int) |
| 261 | + |
| 262 | + @dataclass |
| 263 | + class LineItem: |
| 264 | + product_id: ProductId |
| 265 | + |
| 266 | + @dataclass |
| 267 | + class Order: |
| 268 | + primary_key: OrderId |
| 269 | + items: List[LineItem] |
| 270 | + aside.notes |
| 271 | + p начали прописывать в этих самых датаклассах контракты данных |
210 | 272 | section |
211 | | - p захотелось чтобы рантайм проверял эти контракты во время попадания этих переменных в контекст |
212 | | - p а не писать эти проверки как часть сценариев каждый раз |
| 273 | + h2 State Contract |
| 274 | + pre |
| 275 | + code.python. |
| 276 | + from pydantic import BaseModel |
| 277 | + |
| 278 | + class Subscription: |
| 279 | + @story |
| 280 | + def buy(I): |
| 281 | + ... |
| 282 | + |
| 283 | + @Subscription.buy.contract |
| 284 | + class Context(BaseModel): |
| 285 | + user: User |
| 286 | + invoice_id: InvoiceId |
| 287 | + invoice: Optional[Invoice] |
| 288 | + aside.notes |
| 289 | + p захотелось чтобы рантайм проверял эти контракты во время попадания этих переменных в контекст |
| 290 | + p а не писать эти проверки как часть сценариев каждый раз |
213 | 291 | section |
214 | 292 | p уныло перегонять руками таблички бд и ответы api в нормальное представление |
215 | 293 | p начали писать мапперс |
|
0 commit comments