I start with the basics of the strangler pattern approach and then go to some harder parts of it, like the Anti-Corruption Layer. I also briefly discuss two projects I worked on using this pattern.
3. T H I S TA L K S I S A B O U T
• Where legacy comes from?
• Why it is worth to get rid of legacy…
• … and how to make it properly?
• How not to hurt yourself
• Examples
4. T H I S TA L K I S N O T A B O U T
• How to test
• How to refactor classes/methods
• Silver bullet step-by-step approach
11. Q U A L I T Y D E C R E A S E S I N T I M E
- L A C K O F T H E „ B O Y S C O U T ” R U L E
0
17,5
35
52,5
70
2010 2011 2012 2013
12. R E S U LT S ? I S S U E S :
• Complicated code
• Harder to write tests
• Difficult deployment
• Reluctance of developers
• Hard to develop
13. H O W T O C O N V I N C E B U S I N E S S
• Slower development
• competitors might be faster
• increased costs
• HR issues: harder recruitment, more people leaving
• Lots of bugs, angry customers
• It might explode at any time ;)
14. 2 0 1 2 , K N I G H T C A P I TA L G R O U P
$460 mln loss in 45 minutes
30. G AT E WAY - B U I L D I T L E A N
server {
listen 80;
server_name domain.com;
location /profile {
proxy_pass http://10.0.3.10:80;
}
location /news {
proxy_pass http://10.0.3.10:80;
}
proxy_pass http://10.0.3.20:80;
}
31. G AT E WAY - P O S S I B L E S O L U T I O N S
• API - Open Source
• Kong
• API - Paid
• AWS API Gateway
• WWW
• HaProxy
• Nginx/Apache/…
52. L O N G T I M E A G O …
• Market leader
• Project started in 2010, we took over in 2016
• Customers: banks, political parties - no downtime
allowed ;)
68. P R O S
• Small risk, less stress, quick releases
• Instant effects
• Both business and developers happy
69. S E C O N D A P P R O A C H - A C L *
* M O D I F I E D A B I T
70. M O D E R N A C L L E G A C Y
https://github.com/VaughnVernon/IDDD_Samples/tree/master/iddd_collaboration/src/main/java/com/saasovation/
collaboration/port/adapter/service
73. interface CurrencyRepository
{
public function findAll();
public function getDefault();
public function find(string $isoCode);
public function save(Currency $currency);
}
M O D E R N - C U R R E N C Y R E P O S I T O RY
74. class Internal_CurrencyController extends Internal_Controller_InternalController
{
public function listcurrenciesAction()
{
$this->checkIp();
$this->getResponse()->setHeader('Content-type', 'application/json');
$mCurrency = new Default_Model_Currency();
/** @var Zend_Db_Table_Rowset $currencies */
$currencies = $mCurrency->fetchAll('status = "active"');
$this->getResponse()
->setBody(json_encode($currencies->toArray()))
->setHttpResponseCode(200);
}
}
L E G A C Y - C U R R E N C Y FA C A D E
76. class LegacyCurrencyAdapter implements CurrencyAdapter
{
public function findAll(): array
{
$response = $this->client->request('GET', 'listCurrencies');
$currencies = json_decode((string) $response->getBody(), true);
return array_map(function ($row) {
$currency = $this->currencyTranslator->createFromArray($row);
if ($exCurrency = $this->currRepo->find($currency->isoCode())) {
$currency->setRatio($exCurrency->getRatio());
$currency->setDefault($exCurrency->getDefault());
}
return $currency;
}, $currencies);
}
}
A C L - C U R R E N C Y A P I
77. class LegacyCurrencyTranslator implements CurrencyTranslator
{
public function createFromArray(array $data)
{
$default = filter_var($data['default'], FILTER_VALIDATE_BOOLEAN);
$ratio = filter_var($data['value'], FILTER_VALIDATE_FLOAT);
return new Currency($data['code'], $ratio, $default);
}
}
A C L - C U R R E N C Y T R A N S L AT O R