SlideShare a Scribd company logo
Dlaczego DDD pomaga
skutecznie zapobiegać
chorobie legacy
Szymon Janikowski
Marcin Markowski
https://github.com/itlibrium
Szymon: @szjanikowski
Marcin: @technites_pl
http://itlibrium.com @itlibriun
Szymon Janikowski
@szjanikowski
https://github.com/itlibrium
http://itlibrium.com
Marcin Markowski
@technites_pl
Legacy - zespół chorób,
na który chorują całe
organizacje
WSPÓŁPRACA DDD
KOMPLEKSOWA OCHRONA PRZECIW LEGACY!
AGENDA
• OBJAWY

• WYSTĘPOWANIE (DOMENA)

• ZAPOBIEGANIE

• WSPÓŁPRACA MIĘDZY BIZNESEM i IT

• DOMAIN DRIVEN DESIGN

• CASE STUDY
OBJAWY
- po stronie biznesu
CORAZ TRUDNIEJ
MYŚLEĆ O KLIENTACH
JĘZYK TECHNICZNY
W ROZMOWACH
TRUDNO WDROŻYĆ
ZMIANY
AWARIE NA
PRODUKCJI
ROTACJA I
ROSNĄCE KOSZTY
OBJAWY
- po stronie IT
CHAOS W KODZIE
STRACH PRZED
WDRAŻANIEM ZMIAN
NISKIE MORALE
AIR-CON-SYS
AIR-CON-SYS
AIR-CON-SYS
AIR-CON-SYS
GWARANCJE
AIR-CON-SYS
GW
AIR-CON-SYS
GW
AIR-CON-SYS
GW
AIR-CON-SYS
GW
UMOWY
SERWISOWE
AIR-CON-SYS
UMOWA

SERWIS.
AIR-CON-SYS
AIR-CON-SYS
AIR-CON-SYS
F-VAT ?
AIR-CON-SYS
TANIE-ZLECENIA.PL
$$CHEAP-DEVS.COM
Po próbnym sprincie
public class ServiceService {
[…]
public void finish(int serviceId, Collection<Integer> sparePartIds)
throws BusinessException {
Service service = serviceRepository.Get(serviceId);
if (service.getStatus() != ServiceStatus.Scheduled) {
throw new BusinessException("Nieprawidłowy status usługi");
}
List<SparePart> spareParts = new ArrayList<>();
for (int sparePartId : sparePartIds) {
spareParts.add(sparePartRepository.Get(sparePartId));
}
service.setSpareParts(spareParts);
BigDecimal sparePartsCost = BigDecimal.valueOf(0);
for (SparePart sparePart : service.getSpareParts()) {
sparePartsCost = sparePartsCost.add(sparePart.Price);
}
PricingCategory pricingCategory =
service.getClient().getEquipmentModel().getPricingCategory();
BigDecimal labourCost = pricingCategory.getPricePerHour()
.multiply(BigDecimal.valueOf(service.getDuration()));
service.setPrice(pricingCategory.getMinPrice().max(labourCost)
.add(sparePartsCost));
service.setStatus(ServiceStatus.Done);
serviceRepository.Save(service);
}
}
Kilka sprintów
później…
JAK TO NIE DA SIĘ 

WPROWADZIĆ PŁATNEJ 

NAPRAWY PODCZAS 

PRZEGLĄDU
GWARANCYJNEGO !!!
JAK TO NIE DA SIĘ 

WPROWADZIĆ PŁATNEJ 

NAPRAWY PODCZAS 

PRZEGLĄDU
GWARANCYJNEGO !!!
blic void finish(int serviceId, Collection<Integer> sparePartIds) throws BusinessException {
Service service = serviceRepository.Get(serviceId);
if (service.getStatus() != ServiceStatus.Scheduled)
throw new BusinessException("Nieprawidłowy status usługi");
List<SparePart> spareParts = new ArrayList<>();
for (int sparePartId : sparePartIds)
{
spareParts.add(sparePartRepository.Get(sparePartId));
}
service.setSpareParts(spareParts);
BigDecimal price = BigDecimal.ZERO;
if (service.isWarranty())
{
price = BigDecimal.valueOf(0);
}
else
{
EquipmentModel equipmentModel = service.getClient().getEquipmentModel();
PricingCategory pricingCategory = equipmentModel.getPricingCategory();
Contract contract = service.getClient().getContract();
BigDecimal sparePartsCost = BigDecimal.valueOf(0);
for (SparePart sparePart : service.getSpareParts())
{
sparePartsCost = sparePartsCost.add(sparePart.Price);
}
if (contract == null)
{
price = pricingCategory.getMinPrice().max(pricingCategory.getPricePerHour()
.multiply(BigDecimal.valueOf(service.getDuration()))).add(sparePartsCost);
}
else
{
blic void finish(int serviceId, Collection<Integer> sparePartIds) throws BusinessException {
Service service = serviceRepository.Get(serviceId);
if (service.getStatus() != ServiceStatus.Scheduled)
throw new BusinessException("Nieprawidłowy status usługi");
List<SparePart> spareParts = new ArrayList<>();
for (int sparePartId : sparePartIds)
{
spareParts.add(sparePartRepository.Get(sparePartId));
}
service.setSpareParts(spareParts);
BigDecimal price = BigDecimal.ZERO;
if (service.isWarranty())
{
price = BigDecimal.valueOf(0);
}
else
{
EquipmentModel equipmentModel = service.getClient().getEquipmentModel();
PricingCategory pricingCategory = equipmentModel.getPricingCategory();
Contract contract = service.getClient().getContract();
BigDecimal sparePartsCost = BigDecimal.valueOf(0);
for (SparePart sparePart : service.getSpareParts())
{
sparePartsCost = sparePartsCost.add(sparePart.Price);
}
if (contract == null)
{
price = pricingCategory.getMinPrice().max(pricingCategory.getPricePerHour()
.multiply(BigDecimal.valueOf(service.getDuration()))).add(sparePartsCost);
}
else
{
CHEAP-DEVS
BIZNES IT
WYMAGANIA
WIEDZA
WIZJA
SPÓJNOŚĆ
I
MOŻLIWOŚCI
TECHNICZNE
PRODUKT
REALIZACJAREVIEW
ŹLE
ESTYMATY
BIZNES IT
WIEDZA
WIZJA
MOŻLIWOŚCI
TECHNICZNE
PRODUKT
REALIZACJA
REVIEW
DOBRZE!
SPÓJNOŚĆ
OGRANICZENIA
ŚRODKI
SOFTWARE
CRAFTSMANSHIP
BRAK ZAUFANIA
BRAK ZAUFANIA
OBAWA PRZED KONFLIKTEM
BRAK ZAUFANIA
OBAWA PRZED KONFLIKTEM
BRAK ZAANGAŻOWANIA
BRAK ZAUFANIA
OBAWA PRZED KONFLIKTEM
BRAK ZAANGAŻOWANIA
UNIKANIE
ODPOWIEDZIALNOŚCI
BRAK ZAUFANIA
OBAWA PRZED KONFLIKTEM
BRAK ZAANGAŻOWANIA
UNIKANIE
ODPOWIEDZIALNOŚCI
BRAK
DBAŁOŚCI
O WYNIKI
Model
Biznes
Bounded Context
Ubiquitous
Language
Model
Biznes
Bounded Context
Ubiquitous
Language
BOUNDED CONTEXT
LOGIKA DOMENOWA
LOGIKA APLIKACYJNA
BUILDING BLOCKS
AGREGAT
STANREGUŁY
ZACHOWANIA
AGREGAT AGREGAT!=
TAKIE SAME != TE SAME
VALUE OBJECT
VALUE OBJECT VALUE OBJECT==
TAKIE SAME
TE SAME
PRICE POLICY
f(x)
POLITYKA
INPUT OUTPUT
PRICE
POLICYf(x)
FABRYKA POLITYK
KONTEKST
POLITYKA
PRZERWA :)
SPRINT 1
Big Picture
+
Tactical
UMAWIANIE
TERMINÓW
OPERACJE
ROZLICZENIA
IoT
CRM
WYCENA
Interwencję można
zakończyć jeśli wszystkie
czynności serwisowe są
wycenione.
Interwencję można
zakończyć jeśli wszystkie
czynności serwisowe są
wycenione.
AGREGAT
Czynności serwisowe to w
tej chwili
przegląd i
naprawa
Czynności serwisowe to w
tej chwili
przegląd i
naprawa
VALUE
OBJECT
Wycena czynności zależy od
robocizny i kosztu części
zamiennych
Wycena czynności zależy od
robocizny i kosztu części
zamiennych
PRICE
POLICYf(x)
Ogólnie eksperymentujemy z
różnymi sposobami wyceny.
Ogólnie eksperymentujemy z
różnymi sposobami wyceny.
AGREGAT
VALUE
OBJECT
PRICE
POLICYf(x)
INTERWENCJA
CZYNNOŚĆ
SERWISOWA
POLITYKA
WYCENY
FABRYKA
POLITYK WYCENY
INTERVENTION
SERVICE ACTION
PRICE POLICY
PRICE POLICY FACTORY
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
SPRINT 1 - REVIEW
–Alberto Brandolini
„Software development is a LEARNING
PROCESS
Working code is a SIDE EFFECT”
CZY ZAPOBIEGAMY LEGACY ?
CZY DZIAŁAMY JAK ZESPÓŁ ?
• WYMIANA WIEDZY 

• POZNANIE ORGANIZACJI

• USTALENIE JĘZYKA!!
SPRINT 2
TEST FIRST!
def "Labour cost calculated correctly"() {
given:
_minPrice = minPrice;
_pricePerHour = pph;
_sparePartsPrices = [ 158 : Money.fromDouble(30),
333 : Money.fromDouble(40)];
_duration = duration;
_usedParts = usedPartsIds;
_actionType = actionType;
when:
serviceIsFinished();
then:
getInterventionPrice() == Money.fromDouble(price);
where:
minPrice | pph | duration | usedPartsIds | actionType || price
200 | 100 | 4 | [] | Review || 400
200 | 100 | 1 | [158, 333] | Repair || 270
200 | 100 | 1 | [] | Review || 200
200 | 100 | 0 | [333] | Repair || 240
300 | 100 | 0 | [] | Review || 300
400 | 0 | 10 | [158] | Repair || 430
}
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
public class FinishInterventionHandler {
[…]
public void finish(FinishInterventionCommand command) throws BusinessException {
Intervention intervention = interventionRepository
.get(command.getInterventionId());
PricePolicy pricePolicy = this.pricePolicyFactory.createFor(intervention);
intervention.finish(command.getServiceActions(), pricePolicy);
interventionRepository.save(intervention);
}
}
DDD v1
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
PRICE
POLICY
PRICE
POLICY
FINISH
public class Intervention {
[…]
public void finish(Collection<ServiceAction> serviceActions, PricePolicy pricePolicy)
throws BusinessException {
if (this.serviceActions != null)
throw new BusinessException("Nie można zakończyć interwencji więcej niż raz");
this.serviceActions = new ArrayList<>(serviceActions);
price = this.serviceActions.stream()
.map(pricePolicy::apply)
.reduce(Money.ZERO, Money::sum);
}
}
DDD v1
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
PRICE
POLICY
PRICE
POLICY
FINISH
public class PricePolicies {
public static PricePolicy labour(Money pricePerHour, Money minPrice) {
return serviceAction ->
Money.max(
Money.multiply(pricePerHour, serviceAction.getDuration().getHours()),
minPrice);
}
public static PricePolicy sparePartsCost(Map<Integer, Money> sparePartPrices) {
return serviceAction ->
serviceAction.getSparePartIds().stream()
.map(sparePartPrices::get)
.reduce(Money.ZERO, Money::sum);
}
[…]
}
DDD v1
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
PRICE
POLICY
PRICE
POLICY
FINISH
public class PricePolicyFactory implements IPricePolicyFactory {
[…]
public PricePolicy createFor(Intervention intervention) {
[…]
return PricePolicies.sum(
PricePolicies.labour(
Money.fromDecimal(pricingCategory.getPricePerHour()),
Money.fromDecimal(pricingCategory.getMinPrice())),
PricePolicies.sparePartsCost(sparePartPrices));
}
}
DDD v1
SPRINT 2 - REVIEW
CZY ZAPOBIEGAMY LEGACY ?
CZY DZIAŁAMY JAK ZESPÓŁ ?
• POGŁĘBIENIE WIEDZY

• REALIZACJA WIZJI (ZAUFANIE)
SPRINT 3
GWARANCJE
AIR-CON-SYS
GW
AIR-CON-SYS
GW
AIR-CON-SYS
GW
AIR-CON-SYS
GW
Dodajemy 2 nowe
CZYNNOŚCI SERWISOWE:
PRZEGLĄD GWARANCYJNY
NAPRAWA GWARANCYJNA
TEST FIRST!
def "Labour cost calculated correctly"() {
given:
_minPrice = minPrice;
_pricePerHour = pph;
_sparePartsPrices = [ 158 : Money.fromDouble(30),
333 : Money.fromDouble(40)];
_duration = duration;
_usedParts = usedPartsIds;
_actionType = actionType;
when:
serviceIsFinished();
then:
getInterventionPrice() == Money.fromDouble(price);
where:
minPrice | pph | duration | usedPartsIds | actionType || price
200 | 100 | 4 | [] | Review || 400
200 | 100 | 1 | [158, 333] | Repair || 270
200 | 100 | 1 | [] | Review || 200
200 | 100 | 0 | [333] | Repair || 240
300 | 100 | 0 | [] | Review || 300
400 | 0 | 10 | [158] | Repair || 430
400 | 0 | 1 | [] | WarrantyReview || 0
200 | 100 | 2 | [158] | WarrantyRepair || 0
}
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
PRICE
POLICY
PARTS
POLICY
PRICE
POLICY
public class PricePolicies {
public static PricePolicy labour(Money pricePerHour, Money minPrice) {
return serviceAction ->
Money.max(
Money.multiply(pricePerHour, serviceAction.getDuration().getHours()),
minPrice);
}
public static PricePolicy sparePartsCost(Map<Integer, Money> sparePartPrices) {
return serviceAction ->
serviceAction.getSparePartIds().stream()
.map(sparePartPrices::get)
.reduce(Money.ZERO, Money::sum);
}
public static PricePolicy free() {
return serviceAction -> Money.ZERO;
}
}
DDD v2
public class PricePolicies {
public static PricePolicy labour(Money pricePerHour, Money minPrice) {
return serviceAction ->
Money.max(
Money.multiply(pricePerHour, serviceAction.getDuration().getHours()),
minPrice);
}
public static PricePolicy sparePartsCost(Map<Integer, Money> sparePartPrices) {
return serviceAction ->
serviceAction.getSparePartIds().stream()
.map(sparePartPrices::get)
.reduce(Money.ZERO, Money::sum);
}
public static PricePolicy free() {
return serviceAction -> Money.ZERO;
}
}
JEDNA NOWA
POLITYKA
DDD v2
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
PRICE
POLICY
PARTS
POLICY
PRICE
POLICY
DDD v2
public class PricePolicyFactory implements IPricePolicyFactory {
[…]
public PricePolicy CreateFor(Intervention intervention) {
[…]
return PricePolicies.sum(
PricePolicies.when(
PricePolicyFactory::isRegularAction,
PricePolicies.sum(
PricePolicies.labour(
pricingCategory.getPricePerHour(),
pricingCategory.getMinPrice(),
PricePolicies.sparePartsCost(sparePartPrices))),
PricePolicies.when(
PricePolicyFactory::isWarrantyAction,
PricePolicies.free()));
}
}
DDD v2
public class PricePolicyFactory implements IPricePolicyFactory {
[…]
public PricePolicy CreateFor(Intervention intervention) {
[…]
return PricePolicies.sum(
PricePolicies.when(
PricePolicyFactory::isRegularAction,
PricePolicies.sum(
PricePolicies.labour(
pricingCategory.getPricePerHour(),
pricingCategory.getMinPrice(),
PricePolicies.sparePartsCost(sparePartPrices))),
PricePolicies.when(
PricePolicyFactory::isWarrantyAction,
PricePolicies.free()));
}
}
SPRINT 3 - REVIEW
CZY ZAPOBIEGAMY LEGACY ?
CZY DZIAŁAMY JAK ZESPÓŁ ?
• BARDZO SZYBKIE DOSTARCZENIE

• WYKORZYSTANIE ELASTYCZNOŚCI 

MODELU

• WZROST ZAUFANIA
SPRINT 4
UMOWY SERWISOWE
AIR-CON-SYS
UMOWA

SERWIS.
AIR-CON-SYS
F-VAT ?
Umowa
serwisowa
Zakończenie
interwencji
może obniżyć cenę
wykorzystuje limity
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
PRICE
POLICY
PARTS
POLICY
PRICE
POLICY
?
public class PricePolicies {
public static PricePolicy labour(Money pricePerHour, Money minPrice) {
return serviceAction ->
Money.max(
Money.multiply(pricePerHour, serviceAction.getDuration().getHours()),
minPrice);
}
public static PricePolicy sparePartsCost(Map<Integer, Money> sparePartPrices) {
return serviceAction ->
serviceAction.getSparePartIds().stream()
.map(sparePartPrices::get)
.reduce(Money.ZERO, Money::sum);
}
public static PricePolicy free() {
return fixed(Money.ZERO);
}
public static PricePolicy fixed(BigDecimal value) {
return fixed(Money.fromDecimal(value));
}
public static PricePolicy fixed(Money value) {
return serviceAction -> value;
}
}
DDD v2
public class PricePolicies {
public static PricePolicy labour(Money pricePerHour, Money minPrice) {
return serviceAction ->
Money.max(
Money.multiply(pricePerHour, serviceAction.getDuration().getHours()),
minPrice);
}
public static PricePolicy sparePartsCost(Map<Integer, Money> sparePartPrices) {
return serviceAction ->
serviceAction.getSparePartIds().stream()
.map(sparePartPrices::get)
.reduce(Money.ZERO, Money::sum);
}
public static PricePolicy free() {
return fixed(Money.ZERO);
}
public static PricePolicy fixed(BigDecimal value) {
return fixed(Money.fromDecimal(value));
}
public static PricePolicy fixed(Money value) {
return serviceAction -> value;
}
}
POLITYKA
ZMIENIAJĄCA
UMOWĘ?
DDD v2
public class PricePolicies {
public static PricePolicy labour(Money pricePerHour, Money minPrice) {
return serviceAction ->
Money.max(
Money.multiply(pricePerHour, serviceAction.getDuration().getHours()),
minPrice);
}
public static PricePolicy sparePartsCost(Map<Integer, Money> sparePartPrices) {
return serviceAction ->
serviceAction.getSparePartIds().stream()
.map(sparePartPrices::get)
.reduce(Money.ZERO, Money::sum);
}
public static PricePolicy free() {
return fixed(Money.ZERO);
}
public static PricePolicy fixed(BigDecimal value) {
return fixed(Money.fromDecimal(value));
}
public static PricePolicy fixed(Money value) {
return serviceAction -> value;
}
}
DDD v2
?
WYCENA interwencji i
aktualizacja 

UMOWY SERWISOWEJ
są niezależne
PRZEŁOM!
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
USAGE
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
USAGE
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
USAGE
AGREGAT
VALUE
OBJECT
UMOWA SERWISOWA
LIMITY UMOWY
WYCENA
INTERWENCJI
SERWIS
WYCENIAJĄCY
CONTRACT
CONTRACT LIMITS
INTERVENTION
PRICING
PRICING
SERVICE
VALUE
OBJECT
SERWIS
DOMENOWY
SPRINT 4 - REVIEW
CZY ZAPOBIEGAMY LEGACY ?
CZY DZIAŁAMY JAK ZESPÓŁ ?
• PRZECHODZENIE PRZEZ KONFLIKT

• PRÓBA ZAUFANIA

• NIE DOPUSZCZAMY DO ROZWIĄZANIA 

„NA KRÓTKO”
SPRINT 5…
TEST FIRST!
def "Contracts allows certain number of free interventions"() {
given:
_interventionsLimit = i10nsLimit;
_interventionsUsed = i10nsUsedBefore;
_actionType = actionType;
when:
serviceIsFinished();
then:
getInterventionPrice() == Money.fromDouble(total);
getInterventionsLimitUsed() == i10sUsedAfter;
where:
i10nsLimit | i10nsUsedBefore | actionType || total | i10sUsedAfter
2 | 0 | Repair || 0 | 1
2 | 0 | WarrantyReview || 0 | 0
2 | 2 | Repair || 300 | 2
0 | 0 | Repair || 300 | 0
}
def "Contracts allows spare parts usage up to a limit"() {
given:
_sparePartsPrices = [ 5 : Money.fromDouble(50),
2 : Money.fromDouble(20)]
_sparePartsLimit = partsLimit
_sparePartsLimitUsed = limitBefore
labourIsFree()
_usedParts = usedParts;
_actionType = actionType;
when:
serviceIsFinished();
then:
getInterventionPrice() == Money.fromDouble(total);
getSparePartsLimitUsed() == Money.fromDouble(limitAfter);
where:
partsLimit | limitBefore | actionType | usedParts || total |limitAfter
100 | 0 | Repair | [5,5] || 0 | 100
100 | 0 | Repair | [5,5,2] || 20 | 100
100 | 20 | Repair | [2] || 0 | 40
100 | 50 | WarrantyRepair| [5] || 0 | 50
0 | 0 | Repair | [5,2] || 70 | 0
}
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
PRICING
USAGE
PRICING
PRICE
POLICY
PARTS
POLICY
PRICE
POLICY
DDD v3
public class Intervention {
[…]
public void Finish(Collection<ServiceAction> serviceActions,
InterventionPricing interventionPricing)
throws BusinessException {
if (this.serviceActions != null)
throw new BusinessException("Nie można zakończyć interwencji więcej niż raz");
this.serviceActions = new ArrayList<>(serviceActions);
price = interventionPricing.getTotalPrice();
}
}
DDD v3
public class Intervention {
[…]
public void Finish(Collection<ServiceAction> serviceActions,
InterventionPricing interventionPricing)
throws BusinessException {
if (this.serviceActions != null)
throw new BusinessException("Nie można zakończyć interwencji więcej niż raz");
this.serviceActions = new ArrayList<>(serviceActions);
price = interventionPricing.getTotalPrice();
}
}
ZMIANA PARAMETRU
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
PRICING
USAGE
PRICING
PRICE
POLICY
PARTS
POLICY
PRICE
POLICY
public class PricingService implements IPricingService {
private IPricePolicyFactory pricePolicyFactory;
public PricingService(IPricePolicyFactory pricePolicyFactory) {
this.pricePolicyFactory = pricePolicyFactory;
}
public InterventionPricing GetPricingFor(Intervention intervention,
Collection<ServiceAction> serviceActions,
ContractLimits contractLimits) {
PricePolicy pricePolicy = pricePolicyFactory.CreateFor(intervention);
Money totalPrice = Money.ZERO;
for (ServiceAction serviceAction : serviceActions) {
PricingContext context = new PricingContext(serviceAction, contractLimits);
Pricing pricing = pricePolicy.apply(context);
contractLimits = pricing.getContractLimits();
totalPrice = Money.sum(totalPrice, pricing.getValue());
}
return new InterventionPricing(totalPrice, contractLimits);
}
}
DDD v3
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
PRICING
USAGE
PRICING
PRICE
POLICY
PARTS
POLICY
PRICE
POLICY
public static PricePolicy labour(Money pricePerHour, Money minPrice,
InterventionDuration freeInterventionTimeLimit) {
return context ->
{
FreeInterventionsLimit freeInterventionsLimit =
context.getContractLimits().getFreeInterventionsLimit();
if (freeInterventionsLimit.usedInCurrentIntervention()) {
Money labourOverLimit =
labourOverLimit(context, pricePerHour, freeInterventionTimeLimit);
return new Pricing(context.getContractLimits(), labourOverLimit);
}
if (freeInterventionsLimit.canUse()) {
ContractLimits modifiedContractLimits =
context.getContractLimits().UseFreeIntervention();
Money labourOverLimit =
labourOverLimit(context, pricePerHour, freeInterventionTimeLimit);
return new Pricing(modifiedContractLimits, labourOverLimit);
}
Money labour = labour(context, pricePerHour, minPrice);
return new Pricing(context.getContractLimits(), labour);
};
}
DDD v3
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
PRICING
USAGE
PRICING
PRICE
POLICY
PARTS
POLICY
PRICE
POLICY
public class PricePolicyFactory implements IPricePolicyFactory {
[…]
public PricePolicy CreateFor(Intervention intervention) {
[…]
return PricePolicies.sum(
PricePolicies.when(
PricePolicyFactory::isRegularAction,
PricePolicies.sum(
PricePolicies.labour(
pricingCategory.getPricePerHour(),
pricingCategory.getMinPrice(),
freeInterventionTimeLimit,
PricePolicies.sparePartsCost(sparePartPrices))),
PricePolicies.when(
PricePolicyFactory::isWarrantyAction,
PricePolicies.free()));
}
}
DDD v3
public class PricePolicyFactory implements IPricePolicyFactory {
[…]
public PricePolicy CreateFor(Intervention intervention) {
[…]
return PricePolicies.sum(
PricePolicies.when(
PricePolicyFactory::isRegularAction,
PricePolicies.sum(
PricePolicies.labour(
pricingCategory.getPricePerHour(),
pricingCategory.getMinPrice(),
freeInterventionTimeLimit,
PricePolicies.sparePartsCost(sparePartPrices))),
PricePolicies.when(
PricePolicyFactory::isWarrantyAction,
PricePolicies.free()));
}
}
DDD v3
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
USAGE
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
USAGE
POLICY FACTORY
INTERVENTION
PARTS
POLICY
LABOUR
POLICY
FINISH
FREE
POLICY
CONTRACT
PRICING SERVICE
LIMITS
USAGE
public void finish(FinishInterventionCommand command) throws BusinessException {
Intervention intervention = interventionRepository.Get(command.getInterventionId());
IContract contract = contractRepository.GetForClient(intervention.getClientId());
ContractLimits contractLimits = contract.GetContractLimits();
InterventionPricing interventionPricing =
pricingService.GetPricingFor(intervention, command.getServiceActions(),
contractLimits);
intervention.Finish(command.getServiceActions(), interventionPricing);
interventionRepository.Save(intervention);
contract.AddUsage(interventionPricing.getContractLimits());
contractRepository.Save(contract);
}
DDD v3
public void finish(FinishInterventionCommand command) throws BusinessException {
Intervention intervention = interventionRepository.Get(command.getInterventionId());
IContract contract = contractRepository.GetForClient(intervention.getClientId());
ContractLimits contractLimits = contract.GetContractLimits();
InterventionPricing interventionPricing =
pricingService.GetPricingFor(intervention, command.getServiceActions(),
contractLimits);
intervention.Finish(command.getServiceActions(), interventionPricing);
interventionRepository.Save(intervention);
contract.AddUsage(interventionPricing.getContractLimits());
contractRepository.Save(contract);
}
DDD v3
2 AGREGATY
W TRANSAKCJI ?
SPRINT 5 - REVIEW
CZY ZAPOBIEGAMY LEGACY ?
CZY DZIAŁAMY JAK ZESPÓŁ ?
• SPRAWDZENIE SIĘ W 

TRUDNEJ SYTUACJI

• POTWIERDZENIE WSPÓLNYCH

CELÓW
WSPÓŁPRACA DDD
KOMPLEKSOWA OCHRONA PRZECIW LEGACY!
BIZNES IT
WIEDZA
WIZJA
MOŻLIWOŚCI
TECHNICZNE
PRODUKT
REALIZACJA
REVIEW
DOBRZE!
SPÓJNOŚĆ
OGRANICZENIA
BIZNES - PODSUMOWANIE
• BUDOWANIE ZAUFANIA I
PRZEJRZYSTOŚCI

• WSPÓLNY JĘZYK W KOMUNIKACJI

• WSPÓLNE CELE Z IT
IT - PODSUMOWANIE
• SKUPIENIE NA ABSTRAKCJACH
BIZNESOWYCH

• PORZĄDEK I STRUKTURA W KODZIE

• WSPÓLNE CELE Z BIZNESEM
https://github.com/itlibrium
Dzięki!
Szymon: @szjanikowski
Marcin: @technites_pl
https://github.com/itlibrium
Pytania?
Szymon: @szjanikowski
Marcin: @technites_pl
Szymon Janikowski
@szjanikowski
https://github.com/itlibrium
http://itlibrium.com
Marcin Markowski
@technites_pl
Postaci SouthPark - SP-STUDIO.DE

Flooded office:

http://cdn.abclocal.go.com/content/wtvd/images/cms/automation/vod/991300_1280x720.jpg

AIR CONDITIONING PHOTOS:

https://commons.wikimedia.org/wiki/File:Industrial_air_conditioning_unit_(DFdB).JPG#filelinks

https://commons.wikimedia.org/wiki/File:2008-08-23_Durham_Regional_Hospital_air_conditioner.jpg

https://commons.wikimedia.org/wiki/File:2008-07-11_Air_conditioners_at_UNC-CH.jpg

https://commons.wikimedia.org/wiki/File:Centralized_Air_conditioning.jpg

Icons made by:

• http://www.freepik.com

• https://www.flaticon.com/authors/nikita-golubev

• https://www.flaticon.com/authors/smashicons

More Related Content

Similar to Dlaczego DDD skutecznie zapobiega chorobie legacy ?

Spring AOP
Spring AOPSpring AOP
Spring AOP
AnushaNaidu
 
Implementing Clean Architecture
Implementing Clean ArchitectureImplementing Clean Architecture
Implementing Clean Architecture
Florin Coros
 
Bootiful Development with Spring Boot and React - Dublin JUG 2018
Bootiful Development with Spring Boot and React - Dublin JUG 2018Bootiful Development with Spring Boot and React - Dublin JUG 2018
Bootiful Development with Spring Boot and React - Dublin JUG 2018
Matt Raible
 
Good code
Good codeGood code
Good code
Jane Prusakova
 
Wcf data services
Wcf data servicesWcf data services
Wcf data services
Eyal Vardi
 
Is writing performant code too expensive?
Is writing performant code too expensive? Is writing performant code too expensive?
Is writing performant code too expensive?
Tomasz Kowalczewski
 
Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2
Max Pronko
 
Biz Talk Server Certification
Biz Talk Server CertificationBiz Talk Server Certification
Biz Talk Server Certification
Vskills
 
Maximal: Comparison of Optimization Modeling Software for Python - Oct 2012
Maximal: Comparison of Optimization Modeling Software for Python - Oct 2012Maximal: Comparison of Optimization Modeling Software for Python - Oct 2012
Maximal: Comparison of Optimization Modeling Software for Python - Oct 2012Bjarni Kristjánsson
 
Adopting F# at SBTech
Adopting F# at SBTechAdopting F# at SBTech
Adopting F# at SBTech
Antya Dev
 
Intalio|Cloud Presentation
Intalio|Cloud PresentationIntalio|Cloud Presentation
Intalio|Cloud Presentation
intalio_bpm
 
Bootiful Development with Spring Boot and React
Bootiful Development with Spring Boot and ReactBootiful Development with Spring Boot and React
Bootiful Development with Spring Boot and React
VMware Tanzu
 
Automated Design Validation The Solid Works Api
Automated Design Validation The Solid Works ApiAutomated Design Validation The Solid Works Api
Automated Design Validation The Solid Works Api
Razorleaf Corporation
 
Enforce Consistency through Application Infrastructure
Enforce Consistency through Application InfrastructureEnforce Consistency through Application Infrastructure
Enforce Consistency through Application Infrastructure
Florin Coros
 
Web components in Angular (Angular Elements) | Walkingtree Technologies
Web components in Angular (Angular Elements) | Walkingtree TechnologiesWeb components in Angular (Angular Elements) | Walkingtree Technologies
Web components in Angular (Angular Elements) | Walkingtree Technologies
Walking Tree Technologies
 
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv Startup Club
 
C# Tutorial MSM_Murach chapter-13-slides
C# Tutorial MSM_Murach chapter-13-slidesC# Tutorial MSM_Murach chapter-13-slides
C# Tutorial MSM_Murach chapter-13-slides
Sami Mut
 
Events on the outside, on the inside and at the core (jfokus jfokus2016)
Events on the outside, on the inside and at the core (jfokus jfokus2016)Events on the outside, on the inside and at the core (jfokus jfokus2016)
Events on the outside, on the inside and at the core (jfokus jfokus2016)
Chris Richardson
 
Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0
PhilWinstanley
 

Similar to Dlaczego DDD skutecznie zapobiega chorobie legacy ? (20)

Spring AOP
Spring AOPSpring AOP
Spring AOP
 
Implementing Clean Architecture
Implementing Clean ArchitectureImplementing Clean Architecture
Implementing Clean Architecture
 
Bootiful Development with Spring Boot and React - Dublin JUG 2018
Bootiful Development with Spring Boot and React - Dublin JUG 2018Bootiful Development with Spring Boot and React - Dublin JUG 2018
Bootiful Development with Spring Boot and React - Dublin JUG 2018
 
Good code
Good codeGood code
Good code
 
Wcf data services
Wcf data servicesWcf data services
Wcf data services
 
Is writing performant code too expensive?
Is writing performant code too expensive? Is writing performant code too expensive?
Is writing performant code too expensive?
 
Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2Service Oriented Architecture in Magento 2
Service Oriented Architecture in Magento 2
 
Biz Talk Server Certification
Biz Talk Server CertificationBiz Talk Server Certification
Biz Talk Server Certification
 
Einführung in mdx
Einführung in mdxEinführung in mdx
Einführung in mdx
 
Maximal: Comparison of Optimization Modeling Software for Python - Oct 2012
Maximal: Comparison of Optimization Modeling Software for Python - Oct 2012Maximal: Comparison of Optimization Modeling Software for Python - Oct 2012
Maximal: Comparison of Optimization Modeling Software for Python - Oct 2012
 
Adopting F# at SBTech
Adopting F# at SBTechAdopting F# at SBTech
Adopting F# at SBTech
 
Intalio|Cloud Presentation
Intalio|Cloud PresentationIntalio|Cloud Presentation
Intalio|Cloud Presentation
 
Bootiful Development with Spring Boot and React
Bootiful Development with Spring Boot and ReactBootiful Development with Spring Boot and React
Bootiful Development with Spring Boot and React
 
Automated Design Validation The Solid Works Api
Automated Design Validation The Solid Works ApiAutomated Design Validation The Solid Works Api
Automated Design Validation The Solid Works Api
 
Enforce Consistency through Application Infrastructure
Enforce Consistency through Application InfrastructureEnforce Consistency through Application Infrastructure
Enforce Consistency through Application Infrastructure
 
Web components in Angular (Angular Elements) | Walkingtree Technologies
Web components in Angular (Angular Elements) | Walkingtree TechnologiesWeb components in Angular (Angular Elements) | Walkingtree Technologies
Web components in Angular (Angular Elements) | Walkingtree Technologies
 
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
Lviv MDDay 2014. Ігор Коробка “забезпечення базової безпеки в андроїд аплікац...
 
C# Tutorial MSM_Murach chapter-13-slides
C# Tutorial MSM_Murach chapter-13-slidesC# Tutorial MSM_Murach chapter-13-slides
C# Tutorial MSM_Murach chapter-13-slides
 
Events on the outside, on the inside and at the core (jfokus jfokus2016)
Events on the outside, on the inside and at the core (jfokus jfokus2016)Events on the outside, on the inside and at the core (jfokus jfokus2016)
Events on the outside, on the inside and at the core (jfokus jfokus2016)
 
Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0
 

Recently uploaded

FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
ThomasParaiso2
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 

Recently uploaded (20)

FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...GridMate - End to end testing is a critical piece to ensure quality and avoid...
GridMate - End to end testing is a critical piece to ensure quality and avoid...
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 

Dlaczego DDD skutecznie zapobiega chorobie legacy ?