As a developer, Vinai Kopp experience a wide range of feelings while working with Magento 2. It can be tedious or fun and rewarding. He tried to maximize the nice experiences.
In this presentation he shared some of the techniques, tools and principles he found to work well when working with Magento 2.
9. Next best thing after TDD
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
10. Interactive development
Poke the system with a stick & see what happens
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
11. Predeclared ObjectManager as $di
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
12. (REPL DEMO)
▸ Code Generation
▸ Testing Glue Code (e.g. ORM)
▸ Testing ObjectManager Config
▸ Inspecting the ObjectManager Config
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
13. 2.
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
14. SEPARATE CUSTOM LOGIC
FROM FRAMEWORK CODE
!(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
15. Entry Point:
any custom method that is called by Magento
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
24. What are the consequences?
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
25. breaks static code analysis
makes testing harder
makes refactoring harder
makes code harder to understand
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
26. It violates the interface contract
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
27. What to do instead?
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
28. Make the implicit explicit
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
29. Instead of assuming an implementation,
depend on the implementation
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
30. (c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
31. 4.
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
35. // ClanMember inherits Customer
class ClanMember extends Customer
{
public function getFullName()
{
return __(
'%1 of the %2',
$this->getName(), // inherited method
$this->getClanName()
);
}
public function getClanName() {...}
}
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
36. Every call to a parent method
is like a call to a different object
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
37. // ClanMember is composed with Customer
class ClanMember
{
/** @var Customer */
private $customer;
public function __construct(Customer $customer)
{
$this->customer = $customer;
}
public function getName()
{
return $this->customer->getName()
}
public function getFullName()
{
return __('%1 of the %2', $this->getName(), this->getClanName());
}
public function getClanName() { ... }
}
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
38. What about extending a class
for customization?
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
40. DECORATOR
▸ Wrap original instance instead of extending it
▸ No inheritance
▸ Implement same interface
▸ Implement changed methods
▸ Unchanged methods just call delegate
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
41. Example of inheritance based customization:
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
42. // inherit to customize render() via overwrite
class OrdinalPlaceholderRenderer extends Placeholder
{
private static $ordinal = ['first', 'second', 'third', 'fourth'];
public function render(array $source, array $arguments)
{
$source[] = reduce(keys(self::$ordinal), [$this, 'replaceOrdinalWithInt'], pop($source));
return parent::render($source, $arguments);
}
private function replaceOrdinalWithInt($source, $ordinalIdx)
{
$pattern = '/%' . self::$ordinal[$ordinalIdx] . 'b/';
$replacement = '%' . ($ordinalIdx + 1);
return preg_replace($pattern, $replacement, $source);
}
}
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
46. - More complex
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
47. + Better code reuse
+ Easier to change
+ Easier to test
+ More upgradeable
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
48. 5.
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
49. ATTITUDE
!(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
50. IMAGINE A LEGENDARY
DEVELOPER WILL REVIEW
IN 2 HOURS...!(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
57. What would _ _ _ _ do?
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
58. I am responsible for my attitude
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
59. 6.
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
60. BUILD STRATEGIES
!(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
61. Strategy 1: From one to many
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
62. Get one working
private function replaceOrdinalWithInt($source, $ordinalIdx)
{
$pattern = '/%' . self::$ordinal[$ordinalIdx] . 'b/';
$replacement = '%' . ($ordinalIdx + 1);
return preg_replace($pattern, $replacement, $source);
}
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
63. Then apply to many
$source[] = reduce(
keys(self::$ordinal),
[$this, 'replaceOrdinalWithInt'],
pop($source)
);
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
65. Simpler to test
Simpler to reason about
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
66. Strategy 2: Favor immutability
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
67. After a variable is initialized,
never overwrite it's value
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
68. Simpler to refactor
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
69. Strategy 3: Favor pure functions
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
70. Same input, same output
No side effects
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
71. Simpler to test
Simpler to change
Simpler to compose
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
72. Strategy 4: Follow a design recipe
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
73. name, input, output, examples
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
74. A) When writing a function, start with a name
(but no arguments yet)
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
75. B) Add a docblock
document the inputs and output
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
76. C) Add one example of inputs and expected output
per execution branch
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
77. D) Write the method
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
78. E) Finally check the behavior matches the examples
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24
79.
80. Thank you for your attention!
!
Questions? !
(c) Vinai Kopp - http://vinaikopp.com - twitter://@VinaiKopp - Meet Magento IT on 2018-05-24