SlideShare a Scribd company logo
1 of 71
Download to read offline
„KTO TO PISAŁ?!… A, TO JA.”
czyli sposoby, żeby znienawidzić
siebie z przeszłości
🔥🔥🔥
„KTO TO PISAŁ?! A, TO JA…”
czyli jak wiedźmin i angielski teolog
„KTO TO PISAŁ?! A, TO JA…”
czyli jak wiedźmin i angielski teolog
mogą pomóc Ci pisać lepszy kod
„KTO TO PISAŁ?! A, TO JA…”
„KTO TO PISAŁ?! A, TO JA…”
czyli jak wiedźmin i angielski teolog
mogą pomóc Ci pisać lepszy kod
albo przynajmniej zrozumieć, czemu nie
jest tak dobry, jak byś chciał(a)
✅
❌
S P Ó J N O Ś Ć
😕
😕
😠
😕
😠
😕
😠
🤬🤬🤬🤬
final class ProductVariantPriceCalculatorSpec extends ObjectBehavior
{
function it_implements_product_variant_price_calculator_interface(): void
{
$this->shouldImplement(ProductVariantPricesCalculatorInterface::class);
}
function it_gets_price_for_product_variant_in_given_channel(
ChannelInterface $channel,
ChannelPricingInterface $channelPricing,
ProductVariantInterface $productVariant,
): void {
$productVariant->getChannelPricingForChannel($channel)->willReturn($channelPricing);
$channelPricing->getPrice()->willReturn(1000);
$this->calculate($productVariant, ['channel' => $channel])->shouldReturn(1000);
}
}
final class ProductVariantPriceCalculatorSpec extends ObjectBehavior
{
function it_implements_product_variant_price_calculator_interface(): void
{
$this->shouldImplement(ProductVariantPricesCalculatorInterface::class);
}
function it_gets_price_for_product_variant_in_given_channel(
ChannelInterface $channel,
ChannelPricingInterface $channelPricing,
ProductVariantInterface $productVariant,
): void {
$productVariant->getChannelPricingForChannel($channel)->willReturn($channelPricing);
$channelPricing->getPrice()->willReturn(1000);
$this->calculate($productVariant, ['channel' => $channel])->shouldReturn(1000);
}
}
😡
1 . P O P R A W N O Ś Ć
2 . S P Ó J N O Ś Ć
S T A N D A R D Y
P U Ł A P K A
S P Ó J N O Ś C I
D O K U M E N T A C J A
T E S T Y
A D R
K O N T E K S T
P Ł O T C H E S T E R T O N A
final class GrossPriceCalculatorTest extends TestCase
{
/** @dataProvider provideGrossCalculationData */
public function testItCountsGrossPriceForGivenNetPriceAndTaxRate(
int $netPrice,
float $taxRate,
int $expectedGrossPrice
): void {
self::assertSame(
$expectedGrossPrice,
GrossPriceCalculator::calculateGrossPrice($netPrice, $taxRate)
);
}
private function provideGrossCalculationData(): iterable
{
yield 'net price 500, tax rate 7.0%' => [
'netPrice' => 500,
'taxRate' => 0.07,
'expectedGrossPrice' => 535,
];
yield 'net price 750, tax rate 7.7%' => [
'netPrice' => 750,
'taxRate' => 0.077,
'expectedGrossPrice' => 808,
];
yield 'net price 1500, tax rate 8.5%' => [
'netPrice' => 1500,
'taxRate' => 0.085,
'expectedGrossPrice' => 1628,
];
}
}
final class GrossPriceCalculatorTest extends TestCase
{
/** @dataProvider provideGrossCalculationData */
public function testItCountsGrossPriceForGivenNetPriceAndTaxRate(
int $netPrice,
float $taxRate,
int $expectedGrossPrice
): void {
self::assertSame(
$expectedGrossPrice,
GrossPriceCalculator::calculateGrossPrice($netPrice, $taxRate)
);
}
private function provideGrossCalculationData(): iterable
{
yield 'net price 500, tax rate 7.0%' => [
'netPrice' => 500,
'taxRate' => 0.07,
'expectedGrossPrice' => 535,
];
yield 'net price 750, tax rate 7.7%' => [
'netPrice' => 750,
'taxRate' => 0.077,
'expectedGrossPrice' => 808,
];
yield 'net price 1500, tax rate 8.5%' => [
'netPrice' => 1500,
'taxRate' => 0.085,
'expectedGrossPrice' => 1628,
];
}
}
❗
❗
final class GrossPriceCalculatorTest extends TestCase
{
/** @dataProvider provideGrossCalculationData */
public function testItCountsGrossPriceForGivenNetPriceAndTaxRate(
int $netPrice,
float $taxRate,
int $expectedGrossPrice
): void {
self::assertSame(
$expectedGrossPrice,
GrossPriceCalculator::calculateGrossPrice($netPrice, $taxRate)
);
}
private function provideGrossCalculationData(): iterable
{
yield 'net price 500, tax rate 7.0%' => [
'netPrice' => 500,
'taxRate' => 0.07,
'expectedGrossPrice' => 535,
];
yield 'net price 750, tax rate 7.7%' => [
'netPrice' => 750,
'taxRate' => 0.077,
'expectedGrossPrice' => 810,
];
yield 'net price 1500, tax rate 8.5%' => [
'netPrice' => 1500,
'taxRate' => 0.085,
'expectedGrossPrice' => 1630,
];
}
}
✅
✅
🤨
😡
K O N T E K S T
W I E D Z Y I
C Z A S U
D Ł U G
T E C H N I C Z N Y
https://twitter.com/vincentdnl/status/1647630936060600322
final class OrderTaxesProcessor implements OrderProcessorInterface
{
public function __construct(
private ZoneProviderInterface $defaultTaxZoneProvider,
private ZoneMatcherInterface $zoneMatcher,
private PrioritizedServiceRegistryInterface $strategyRegistry,
private ?TaxationAddressResolverInterface $taxationAddressResolver = null,
) {
}
public function process(BaseOrderInterface $order): void
{
if (OrderInterface::STATE_CART !== $order->getState()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
$zone = $this->getTaxZone($order);
if (null === $zone) {
return;
}
/** @var TaxCalculationStrategyInterface $strategy */
foreach ($this->strategyRegistry->all() as $strategy) {
if ($strategy->supports($order, $zone)) {
$strategy->applyTaxes($order, $zone);
public function process(BaseOrderInterface $order): void
{
if (OrderInterface::STATE_CART !== $order->getState()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
😡
public function process(BaseOrderInterface $order): void
{
if ($order->canBeProcessed()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
if ($order->canBeProcessed()) {
return;
}
2 0 2 0
2 0 2 0
/api/v2 header /new-api
😂
2 0 2 0
/api/v2 header
/new-api
🤡
P O S T Ę P J E S T
J A K S T A D O
Ś W I Ń
R E F A C T O R I N G
Z A S A D A S K A U T A
16608
38469
Z A S A D Y
S O L I D
K I S S
D R Y
Y A G N I
C U P I D
S R P
public function process(BaseOrderInterface $order): void
{
/** @var OrderInterface $order */
Assert::isInstanceOf($order, OrderInterface::class);
if (OrderInterface::STATE_CART !== $order->getState()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
$zone = $this->getTaxZone($order);
if (null === $zone) {
return;
}
/** @var TaxCalculationStrategyInterface $strategy */
foreach ($this->strategyRegistry->all() as $strategy) {
if ($strategy->supports($order, $zone)) {
$strategy->applyTaxes($order, $zone);
return;
}
}
throw new UnsupportedTaxCalculationStrategyException();
}
private function getTaxZone(OrderInterface $order): ?ZoneInterface
{
$taxationAddress = $order->getBillingAddress();
$zone = $this->zoneMatcher->match($taxationAddress, Scope::TAX);
return $zone ?: $this->defaultTaxZoneProvider->getZone($order);
}
private function clearTaxes(OrderInterface $order): void
{
$order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
foreach ($order->getItems() as $item) {
$item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT);
}
/** @var ShipmentInterface $shipment */
foreach ($order->getShipments() as $shipment) {
$shipment->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
}
}
public function process(BaseOrderInterface $order): void
{
/** @var OrderInterface $order */
Assert::isInstanceOf($order, OrderInterface::class);
if (OrderInterface::STATE_CART !== $order->getState()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
$zone = $this->getTaxZone($order);
if (null === $zone) {
return;
}
/** @var TaxCalculationStrategyInterface $strategy */
foreach ($this->strategyRegistry->all() as $strategy) {
if ($strategy->supports($order, $zone)) {
$strategy->applyTaxes($order, $zone);
return;
}
}
throw new UnsupportedTaxCalculationStrategyException();
}
private function getTaxZone(OrderInterface $order): ?ZoneInterface
{
$taxationAddress = $order->getBillingAddress();
$zone = $this->zoneMatcher->match($taxationAddress, Scope::TAX);
return $zone ?: $this->defaultTaxZoneProvider->getZone($order);
}
private function clearTaxes(OrderInterface $order): void
{
$order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
foreach ($order->getItems() as $item) {
$item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT);
}
/** @var ShipmentInterface $shipment */
foreach ($order->getShipments() as $shipment) {
$shipment->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
}
}
public function process(BaseOrderInterface $order): void
{
/** @var OrderInterface $order */
Assert::isInstanceOf($order, OrderInterface::class);
if (OrderInterface::STATE_CART !== $order->getState()) {
return;
}
$this->clearTaxes($order);
if ($order->isEmpty()) {
return;
}
$zone = $this->getTaxZone($order);
if (null === $zone) {
return;
}
/** @var TaxCalculationStrategyInterface $strategy */
foreach ($this->strategyRegistry->all() as $strategy) {
if ($strategy->supports($order, $zone)) {
$strategy->applyTaxes($order, $zone);
return;
}
}
throw new UnsupportedTaxCalculationStrategyException();
}
private function getTaxZone(OrderInterface $order): ?ZoneInterface
{
$taxationAddress = $order->getBillingAddress();
$zone = $this->zoneMatcher->match($taxationAddress, Scope::TAX);
return $zone ?: $this->defaultTaxZoneProvider->getZone($order);
}
private function clearTaxes(OrderInterface $order): void
{
$order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
foreach ($order->getItems() as $item) {
$item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT);
}
/** @var ShipmentInterface $shipment */
foreach ($order->getShipments() as $shipment) {
$shipment->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT);
}
}
I M P L E M E N T A C J A
Z P R Z Y P A D K U
Excellence lives inside pragmatic boundaries
D D D
D I S C O M F O R T
D R I V E N
D E V E L O P M E N T
@mpzalewski Zales0123
https://mpzalewski.com
Mateusz Zalewski
@mpzalewski Zales0123
https://mpzalewski.com
Mateusz Zalewski
@CommerceWeavers @Sylius
@mpzalewski Zales0123
https://mpzalewski.com
Mateusz Zalewski
THANK YOU
@CommerceWeavers
@mpzalewski Zales0123
https://mpzalewski.com
Mateusz Zalewski
WE’RE
HIRING!

More Related Content

Similar to [PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić siebie z przeszłości

Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
C A S Sample Php
C A S Sample PhpC A S Sample Php
C A S Sample PhpJH Lee
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
R57shell
R57shellR57shell
R57shellady36
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Masahiro Nagano
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021Ayesh Karunaratne
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm OldRoss Tuck
 
The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of TransductionDavid Stockton
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegamehozayfa999
 

Similar to [PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić siebie z przeszłości (20)

Intermediate PHP
Intermediate PHPIntermediate PHP
Intermediate PHP
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
C A S Sample Php
C A S Sample PhpC A S Sample Php
C A S Sample Php
 
Php Enums
Php EnumsPhp Enums
Php Enums
 
Database api
Database apiDatabase api
Database api
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
R57shell
R57shellR57shell
R57shell
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
PHP 8.1: Enums
PHP 8.1: EnumsPHP 8.1: Enums
PHP 8.1: Enums
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of Transduction
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegame
 

More from Mateusz Zalewski

[PHPCon 2023] Blaski i cienie BDD
[PHPCon 2023] Blaski i cienie BDD[PHPCon 2023] Blaski i cienie BDD
[PHPCon 2023] Blaski i cienie BDDMateusz Zalewski
 
[ForumPHP 2023] Lights and shadows of BDD in Sylius (and probably other compa...
[ForumPHP 2023] Lights and shadows of BDD in Sylius (and probably other compa...[ForumPHP 2023] Lights and shadows of BDD in Sylius (and probably other compa...
[ForumPHP 2023] Lights and shadows of BDD in Sylius (and probably other compa...Mateusz Zalewski
 
[PHPers Summit 2023] Business logic testing
[PHPers Summit 2023] Business logic testing[PHPers Summit 2023] Business logic testing
[PHPers Summit 2023] Business logic testingMateusz Zalewski
 
Confoo 2023 - BDD revolution, or how we came back from hell
Confoo 2023 - BDD revolution, or how we came back from hellConfoo 2023 - BDD revolution, or how we came back from hell
Confoo 2023 - BDD revolution, or how we came back from hellMateusz Zalewski
 
Confoo 2023 - Business logic testing with Behat, Twig and Api Platform
Confoo 2023 - Business logic testing with Behat, Twig and Api PlatformConfoo 2023 - Business logic testing with Behat, Twig and Api Platform
Confoo 2023 - Business logic testing with Behat, Twig and Api PlatformMateusz Zalewski
 
What is Sylius and why should you know it?
What is Sylius and why should you know it?What is Sylius and why should you know it?
What is Sylius and why should you know it?Mateusz Zalewski
 
BDD Revolution - or how we came back from hell
BDD Revolution - or how we came back from hellBDD Revolution - or how we came back from hell
BDD Revolution - or how we came back from hellMateusz Zalewski
 
BDD revolution - or how we came back from hell
BDD revolution - or how we came back from hellBDD revolution - or how we came back from hell
BDD revolution - or how we came back from hellMateusz Zalewski
 
Why you should be doing BDD
Why you should be doing BDDWhy you should be doing BDD
Why you should be doing BDDMateusz Zalewski
 

More from Mateusz Zalewski (9)

[PHPCon 2023] Blaski i cienie BDD
[PHPCon 2023] Blaski i cienie BDD[PHPCon 2023] Blaski i cienie BDD
[PHPCon 2023] Blaski i cienie BDD
 
[ForumPHP 2023] Lights and shadows of BDD in Sylius (and probably other compa...
[ForumPHP 2023] Lights and shadows of BDD in Sylius (and probably other compa...[ForumPHP 2023] Lights and shadows of BDD in Sylius (and probably other compa...
[ForumPHP 2023] Lights and shadows of BDD in Sylius (and probably other compa...
 
[PHPers Summit 2023] Business logic testing
[PHPers Summit 2023] Business logic testing[PHPers Summit 2023] Business logic testing
[PHPers Summit 2023] Business logic testing
 
Confoo 2023 - BDD revolution, or how we came back from hell
Confoo 2023 - BDD revolution, or how we came back from hellConfoo 2023 - BDD revolution, or how we came back from hell
Confoo 2023 - BDD revolution, or how we came back from hell
 
Confoo 2023 - Business logic testing with Behat, Twig and Api Platform
Confoo 2023 - Business logic testing with Behat, Twig and Api PlatformConfoo 2023 - Business logic testing with Behat, Twig and Api Platform
Confoo 2023 - Business logic testing with Behat, Twig and Api Platform
 
What is Sylius and why should you know it?
What is Sylius and why should you know it?What is Sylius and why should you know it?
What is Sylius and why should you know it?
 
BDD Revolution - or how we came back from hell
BDD Revolution - or how we came back from hellBDD Revolution - or how we came back from hell
BDD Revolution - or how we came back from hell
 
BDD revolution - or how we came back from hell
BDD revolution - or how we came back from hellBDD revolution - or how we came back from hell
BDD revolution - or how we came back from hell
 
Why you should be doing BDD
Why you should be doing BDDWhy you should be doing BDD
Why you should be doing BDD
 

Recently uploaded

SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 

Recently uploaded (20)

SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 

[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić siebie z przeszłości

  • 1. „KTO TO PISAŁ?!… A, TO JA.” czyli sposoby, żeby znienawidzić siebie z przeszłości
  • 3. „KTO TO PISAŁ?! A, TO JA…”
  • 4. czyli jak wiedźmin i angielski teolog „KTO TO PISAŁ?! A, TO JA…”
  • 5. czyli jak wiedźmin i angielski teolog mogą pomóc Ci pisać lepszy kod „KTO TO PISAŁ?! A, TO JA…”
  • 6. „KTO TO PISAŁ?! A, TO JA…” czyli jak wiedźmin i angielski teolog mogą pomóc Ci pisać lepszy kod albo przynajmniej zrozumieć, czemu nie jest tak dobry, jak byś chciał(a)
  • 7.
  • 9. S P Ó J N O Ś Ć
  • 10.
  • 11.
  • 12.
  • 13. 😕
  • 17. final class ProductVariantPriceCalculatorSpec extends ObjectBehavior { function it_implements_product_variant_price_calculator_interface(): void { $this->shouldImplement(ProductVariantPricesCalculatorInterface::class); } function it_gets_price_for_product_variant_in_given_channel( ChannelInterface $channel, ChannelPricingInterface $channelPricing, ProductVariantInterface $productVariant, ): void { $productVariant->getChannelPricingForChannel($channel)->willReturn($channelPricing); $channelPricing->getPrice()->willReturn(1000); $this->calculate($productVariant, ['channel' => $channel])->shouldReturn(1000); } }
  • 18. final class ProductVariantPriceCalculatorSpec extends ObjectBehavior { function it_implements_product_variant_price_calculator_interface(): void { $this->shouldImplement(ProductVariantPricesCalculatorInterface::class); } function it_gets_price_for_product_variant_in_given_channel( ChannelInterface $channel, ChannelPricingInterface $channelPricing, ProductVariantInterface $productVariant, ): void { $productVariant->getChannelPricingForChannel($channel)->willReturn($channelPricing); $channelPricing->getPrice()->willReturn(1000); $this->calculate($productVariant, ['channel' => $channel])->shouldReturn(1000); } } 😡
  • 19. 1 . P O P R A W N O Ś Ć 2 . S P Ó J N O Ś Ć
  • 20. S T A N D A R D Y
  • 21. P U Ł A P K A S P Ó J N O Ś C I
  • 22. D O K U M E N T A C J A
  • 23. T E S T Y
  • 24.
  • 25.
  • 26.
  • 27. A D R
  • 28.
  • 29.
  • 30. K O N T E K S T
  • 31. P Ł O T C H E S T E R T O N A
  • 32. final class GrossPriceCalculatorTest extends TestCase { /** @dataProvider provideGrossCalculationData */ public function testItCountsGrossPriceForGivenNetPriceAndTaxRate( int $netPrice, float $taxRate, int $expectedGrossPrice ): void { self::assertSame( $expectedGrossPrice, GrossPriceCalculator::calculateGrossPrice($netPrice, $taxRate) ); } private function provideGrossCalculationData(): iterable { yield 'net price 500, tax rate 7.0%' => [ 'netPrice' => 500, 'taxRate' => 0.07, 'expectedGrossPrice' => 535, ]; yield 'net price 750, tax rate 7.7%' => [ 'netPrice' => 750, 'taxRate' => 0.077, 'expectedGrossPrice' => 808, ]; yield 'net price 1500, tax rate 8.5%' => [ 'netPrice' => 1500, 'taxRate' => 0.085, 'expectedGrossPrice' => 1628, ]; } }
  • 33. final class GrossPriceCalculatorTest extends TestCase { /** @dataProvider provideGrossCalculationData */ public function testItCountsGrossPriceForGivenNetPriceAndTaxRate( int $netPrice, float $taxRate, int $expectedGrossPrice ): void { self::assertSame( $expectedGrossPrice, GrossPriceCalculator::calculateGrossPrice($netPrice, $taxRate) ); } private function provideGrossCalculationData(): iterable { yield 'net price 500, tax rate 7.0%' => [ 'netPrice' => 500, 'taxRate' => 0.07, 'expectedGrossPrice' => 535, ]; yield 'net price 750, tax rate 7.7%' => [ 'netPrice' => 750, 'taxRate' => 0.077, 'expectedGrossPrice' => 808, ]; yield 'net price 1500, tax rate 8.5%' => [ 'netPrice' => 1500, 'taxRate' => 0.085, 'expectedGrossPrice' => 1628, ]; } } ❗ ❗
  • 34. final class GrossPriceCalculatorTest extends TestCase { /** @dataProvider provideGrossCalculationData */ public function testItCountsGrossPriceForGivenNetPriceAndTaxRate( int $netPrice, float $taxRate, int $expectedGrossPrice ): void { self::assertSame( $expectedGrossPrice, GrossPriceCalculator::calculateGrossPrice($netPrice, $taxRate) ); } private function provideGrossCalculationData(): iterable { yield 'net price 500, tax rate 7.0%' => [ 'netPrice' => 500, 'taxRate' => 0.07, 'expectedGrossPrice' => 535, ]; yield 'net price 750, tax rate 7.7%' => [ 'netPrice' => 750, 'taxRate' => 0.077, 'expectedGrossPrice' => 810, ]; yield 'net price 1500, tax rate 8.5%' => [ 'netPrice' => 1500, 'taxRate' => 0.085, 'expectedGrossPrice' => 1630, ]; } } ✅ ✅ 🤨
  • 35.
  • 36. 😡
  • 37. K O N T E K S T W I E D Z Y I C Z A S U
  • 38. D Ł U G T E C H N I C Z N Y
  • 40. final class OrderTaxesProcessor implements OrderProcessorInterface { public function __construct( private ZoneProviderInterface $defaultTaxZoneProvider, private ZoneMatcherInterface $zoneMatcher, private PrioritizedServiceRegistryInterface $strategyRegistry, private ?TaxationAddressResolverInterface $taxationAddressResolver = null, ) { } public function process(BaseOrderInterface $order): void { if (OrderInterface::STATE_CART !== $order->getState()) { return; } $this->clearTaxes($order); if ($order->isEmpty()) { return; } $zone = $this->getTaxZone($order); if (null === $zone) { return; } /** @var TaxCalculationStrategyInterface $strategy */ foreach ($this->strategyRegistry->all() as $strategy) { if ($strategy->supports($order, $zone)) { $strategy->applyTaxes($order, $zone);
  • 41. public function process(BaseOrderInterface $order): void { if (OrderInterface::STATE_CART !== $order->getState()) { return; } $this->clearTaxes($order); if ($order->isEmpty()) { return; } 😡
  • 42. public function process(BaseOrderInterface $order): void { if ($order->canBeProcessed()) { return; } $this->clearTaxes($order); if ($order->isEmpty()) { return; } if ($order->canBeProcessed()) { return; }
  • 43.
  • 44.
  • 45. 2 0 2 0
  • 46. 2 0 2 0 /api/v2 header /new-api 😂
  • 47. 2 0 2 0 /api/v2 header /new-api 🤡
  • 48.
  • 49. P O S T Ę P J E S T J A K S T A D O Ś W I Ń
  • 50. R E F A C T O R I N G
  • 51.
  • 52.
  • 53. Z A S A D A S K A U T A
  • 54. 16608
  • 55. 38469
  • 56. Z A S A D Y
  • 57. S O L I D K I S S D R Y Y A G N I C U P I D
  • 58. S R P
  • 59. public function process(BaseOrderInterface $order): void { /** @var OrderInterface $order */ Assert::isInstanceOf($order, OrderInterface::class); if (OrderInterface::STATE_CART !== $order->getState()) { return; } $this->clearTaxes($order); if ($order->isEmpty()) { return; } $zone = $this->getTaxZone($order); if (null === $zone) { return; } /** @var TaxCalculationStrategyInterface $strategy */ foreach ($this->strategyRegistry->all() as $strategy) { if ($strategy->supports($order, $zone)) { $strategy->applyTaxes($order, $zone); return; } } throw new UnsupportedTaxCalculationStrategyException(); } private function getTaxZone(OrderInterface $order): ?ZoneInterface { $taxationAddress = $order->getBillingAddress(); $zone = $this->zoneMatcher->match($taxationAddress, Scope::TAX); return $zone ?: $this->defaultTaxZoneProvider->getZone($order); } private function clearTaxes(OrderInterface $order): void { $order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT); foreach ($order->getItems() as $item) { $item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT); } /** @var ShipmentInterface $shipment */ foreach ($order->getShipments() as $shipment) { $shipment->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT); } }
  • 60. public function process(BaseOrderInterface $order): void { /** @var OrderInterface $order */ Assert::isInstanceOf($order, OrderInterface::class); if (OrderInterface::STATE_CART !== $order->getState()) { return; } $this->clearTaxes($order); if ($order->isEmpty()) { return; } $zone = $this->getTaxZone($order); if (null === $zone) { return; } /** @var TaxCalculationStrategyInterface $strategy */ foreach ($this->strategyRegistry->all() as $strategy) { if ($strategy->supports($order, $zone)) { $strategy->applyTaxes($order, $zone); return; } } throw new UnsupportedTaxCalculationStrategyException(); } private function getTaxZone(OrderInterface $order): ?ZoneInterface { $taxationAddress = $order->getBillingAddress(); $zone = $this->zoneMatcher->match($taxationAddress, Scope::TAX); return $zone ?: $this->defaultTaxZoneProvider->getZone($order); } private function clearTaxes(OrderInterface $order): void { $order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT); foreach ($order->getItems() as $item) { $item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT); } /** @var ShipmentInterface $shipment */ foreach ($order->getShipments() as $shipment) { $shipment->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT); } }
  • 61. public function process(BaseOrderInterface $order): void { /** @var OrderInterface $order */ Assert::isInstanceOf($order, OrderInterface::class); if (OrderInterface::STATE_CART !== $order->getState()) { return; } $this->clearTaxes($order); if ($order->isEmpty()) { return; } $zone = $this->getTaxZone($order); if (null === $zone) { return; } /** @var TaxCalculationStrategyInterface $strategy */ foreach ($this->strategyRegistry->all() as $strategy) { if ($strategy->supports($order, $zone)) { $strategy->applyTaxes($order, $zone); return; } } throw new UnsupportedTaxCalculationStrategyException(); } private function getTaxZone(OrderInterface $order): ?ZoneInterface { $taxationAddress = $order->getBillingAddress(); $zone = $this->zoneMatcher->match($taxationAddress, Scope::TAX); return $zone ?: $this->defaultTaxZoneProvider->getZone($order); } private function clearTaxes(OrderInterface $order): void { $order->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT); foreach ($order->getItems() as $item) { $item->removeAdjustmentsRecursively(AdjustmentInterface::TAX_ADJUSTMENT); } /** @var ShipmentInterface $shipment */ foreach ($order->getShipments() as $shipment) { $shipment->removeAdjustments(AdjustmentInterface::TAX_ADJUSTMENT); } }
  • 62. I M P L E M E N T A C J A Z P R Z Y P A D K U
  • 63.
  • 64.
  • 65. Excellence lives inside pragmatic boundaries
  • 66. D D D
  • 67. D I S C O M F O R T D R I V E N D E V E L O P M E N T