SlideShare a Scribd company logo
1 of 58
REFACTORING CODE
DOMAIN DRIVEN DESIGN WAY
Supported By:
Supported By:
I’M ANDI PANGERAN
@andi_pangeran
cybercoding.wordpress.com
Supported By:
AGENDA
 PRACTICE HOW TO REFACTORING CODE BASED ON DOMAIN
DRIVEN DESIGN MINDSET
 PRACTICE HOW TO WRITE UNIT TESTING
Supported By:
JOKO
Individual who has significant expertise in the
domain of the system being developed.
DOMAIN EXPERT
MEET OUR ACTOR
Supported By:
BENTO
Individual who has spend all of his life for coding.
PROGRAMMER
MEET OUR ACTOR
Supported By:
PRACTICE
Supported By:
Protect your invariants
REFACTORING
Supported By:
JOKO
PRACTICE
“A customer must
always have an
email address.”
Supported By:
PRACTICE
BENTO
public class Customer {
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Supported By:
PRACTICE
BENTO
public class CostumerTest {
@Test
public void should_always_have_an_email() {
Customer customer = new Customer();
assertEquals(customer.getEmail(), "andi.pangeran@jtravl.com");
}
}
TEST FAIL
Supported By:
PRACTICE
BENTO
public class CostumerTest {
@Test
public void should_always_have_an_email() {
Customer customer = new Customer();
customer.setEmail("andi.pangeran@jtravl.com");
assertEquals(customer.getEmail(), "andi.pangeran@jtravl.com");
}
}
TEST PASSED
Supported By:
PRACTICE
BENTO
public class Customer {
private String email;
public Customer(String email) {
this.email = email;
}
}
Supported By:
PRACTICE
BENTO
public class CostumerTest {
@Test
public void should_always_have_an_email() {
Customer customer = new Customer("andi.pangeran@jtravl.com");
assertEquals(customer.getEmail(), "andi.pangeran@jtravl.com");
}
}
TEST PASSED
Supported By:
Use object as concistency boundaries
REFACTORING
Supported By:
JOKO
PRACTICE
“later prospective customer can be
upgraded to paying customer“
“Paying customer must have phone
number”
“we have two type of customer,
prospective and paying customer.”
Supported By:
PRACTICE
BENTO
public class ProspectiveCustomer extends Customer {
/* other attribute */
}
public class PayingCustomer extends Customer {
/* other attribute */
private String phone;
public PayingCustomer(String email, String phone) {
super(email);
this.phone = phone;
}
}
Supported By:
PRACTICE
BENTO
@Test
public void upgraded_prospective_paying() {
ProspectiveCustomer pcustomer = new
ProspectiveCustomer("andi.pangeran@jtravl.com");
assertEquals(pcustomer.getEmail(), "andi.pangeran@jtravl.com");
PayingCustomer payCustomer =
new PayingCustomer(pcustomer.getName(), “0852xxx”);
assertEquals(payCustomer.getEmail(), "andi.pangeran@jtravl.com");
assertEquals(payCustomer.getPhone(), " 0852xxx");
}
TEST FAIL
Supported By:
PRACTICE
BENTO
@Test
public void upgraded_prospective_paying() {
ProspectiveCustomer pcustomer = new
ProspectiveCustomer("andi.pangeran@jtravl.com");
assertEquals(pcustomer.getEmail(), "andi.pangeran@jtravl.com");
PayingCustomer payCustomer =
new PayingCustomer(pcustomer.getEmail(), “0852xxx”);
assertEquals(payCustomer.getEmail(), "andi.pangeran@jtravl.com");
assertEquals(payCustomer.getPhone(), " 0852xxx");
}
TEST PASSED
Supported By:
PRACTICE
BENTO
public class ProspectiveCustomer extends Customer {
/* other attribute */
public PayingCustomer upgradeToPayingCustomer(String phone) {
return new PayingCustomer(this.email, phone);
}
}
public class PayingCustomer extends Customer {
/* other attribute */
private String phone;
public PayingCustomer(String email, String phone) {
super(email);
this.phone = phone;
}
}
Supported By:
PRACTICE
BENTO
@Test
public void upgraded_prospective_paying() {
ProspectiveCustomer pcustomer = new
ProspectiveCustomer("andi.pangeran@jtravl.com");
assertEquals(pcustomer.getEmail(), "andi.pangeran@jtravl.com");
PayingCustomer payCustomer = pcostumer.upgradeToPaying(“0852xxx”);
assertEquals(payCustomer.getEmail(), "andi.pangeran@jtravl.com");
assertEquals(payCustomer.getPhone(), " 0852xxx");
}
TEST PASSED
Supported By:
JOKO
PRACTICE
“Paying customer must always have a
valid phone number”
Supported By:
PRACTICE
BENTO
@Test
public void upgraded_prospective_paying() {
PayingCustomer payCustomer =
new PayingCustomer(“test@mail.com", “badphonenumber”);
exception.expect(IllegalArgumentException.class);
}
TEST FAIL
Supported By:
PRACTICE
BENTO
public class PayingCustomer extends Customer {
/* other attribute */
private String phone;
public PayingCustomer(String email, String phone) {
super(email);
if (/* validation stuff of phone*/ ) {
throw new IllegalArgumentException();
}
this.phone = phone;
}
}
TEST PASSED
Supported By:
PRACTICE
BENTO
public class PayingCustomer extends Customer {
/* other attribute */
private String phone;
public PayingCustomer(String email, String phone) {
super(email);
if (/* validation stuff of phone*/ ) {
throw new IllegalArgumentException();
}
this.phone = phone;
}
}
TEST PASSED
Supported By:
Encapulate state and behavior with
value object
REFACTORING
Supported By:
PRACTICE
 Intro to value object
 Intro to immutable object
Supported By:
PRACTICE
BENTO
public class PhoneNumber {
private final String phone;
public PhoneNumber(String phone) {
if (/* validation stuff of phone*/ ) {
throw new IllegalArgumentException();
}
this.phone = phone;
}
public String getPhone() {
{
return this.phone;
}
}
Supported By:
PRACTICE
BENTO
public class PayingCustomer extends Customer {
/* other attribute */
private PhoneNumber phone;
public PayingCustomer(String email, PhoneNumber phone) {
super(email);
this.phone = phone;
}
}
TEST PASSED
Supported By:
PRACTICE
BENTO
@Test
public void upgraded_prospective_paying() {
PayingCustomer payCustomer =
new PayingCustomer(“test@mail.com", new
PhoneNumber(“badphonenumber”));
exception.expect(IllegalArgumentException.class);
}
TEST PASSED
Supported By:
Encapulate Operations
REFACTORING
Supported By:
JOKO
PRACTICE
“a Customer orders product and pays for
them”
Supported By:
Service.create
BENTO
Order order = new Order();
order.setCustomer(customer);
order.setProducts(products);
order.setStatus(PAYMENTSTATUS.UNPAID);
order.setPaidAmount(500);
order.setPaidCurrency(CURRENCY.IDR);
order.setStatus(PAYMENTSTATUS.PAID);
PRACTICE
Service.pay
Supported By:
Service.create
BENTO
Order order = new Order();
order.setCustomer(customer);
order.setProducts(products);
order.setStatus(new PaymentStatus(PAYMENTSTATUS.UNPAID));
order.setPaidAmount(500);
order.setPaidCurrency(CURRENCY.IDR);
order.setStatus(new PaymentStatus(PAYMENTSTATUS.PAID));
PRACTICE
Service.pay
Supported By:
Service.create
BENTO
Order order = new Order();
order.setCustomer(customer);
order.setProducts(products);
order.setStatus(new PaymentStatus(PAYMENTSTATUS.UNPAID));
order.setPaidMonetary(new Money(500, CURRENCY.IDR));
order.setStatus(new PaymentStatus(PAYMENTSTATUS.PAID));
PRACTICE
Service.pay
Supported By:
Service.create
BENTO
Order order = new Order(customer, products);
//set payment status in order constructor
order.setPaidMonetary(new Money(500, CURRENCY.IDR));
order.setStatus(new PaymentStatus(PAYMENTSTATUS.PAID));
PRACTICE
Service.pay
Supported By:
Service.create
BENTO
Order order = new Order(customer, products);
//set payment status in order constructor
order.pay (new Money(500, CURRENCY.IDR));
//set payment status in pay procedure
PRACTICE
Service.pay
Supported By:
Use Spefication
REFACTORING
Supported By:
JOKO
PRACTICE
“premium customers get special offers”
Supported By:
Service.premium
BENTO
If (customer.isPremium()) {
//send offer
}
PRACTICE
Supported By:
JOKO
PRACTICE
“order 3 times to become premium
customer”
Supported By:
Specification Interface
BENTO
public interface Specification<T> {
boolean isSatisfiedBy(T t);
Class<T> getType();
}
PRACTICE
Specification Abstract
abstract public class AbstractSpecification<T> implements
Specification<T> {
@Override
public boolean isSatisfiedBy(T t) {
throw new NotImplementedException();
}
/othercode
}
Supported By:
BENTO
public class CustomerIsPremium extends
AbstractSpecification<Customer> {
private OrderRepository orderRepository
public CustomerIsPremium(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@Override
public boolean isSatisfiedBy(Customer customer) {
int count =
this.orderRepository.countByCustomer(customer.getId);
return (count > 3);
}
}
PRACTICE
Supported By:
PRACTICE
BENTO
@Test
public void specification_customer_premium() {
CustomerIsPremium<Customer> spec= new CustomerIsPremium();
customer2order = …
customer3order = …
assertFalse(spec.isSatisfiedBy(customer2order));
assertTrue(spec.isSatisfiedBy(customer3order));
}
TEST PASSED
Supported By:
JOKO
PRACTICE
“different rules apply for different
tenants.”
Supported By:
BENTO
public class CustomerWith3OrdersIsPremium implement
CustomerIsPremium {}
public class CustomerWith500kPremium implement
CustomerIsPremium {}
public class CustomerWithSpecialRequiredmentPremium
implement CustomerIsPremium {}
PRACTICE
Specification Interface
public interface CustomerIsPremium extends
Specification<Customer> {
boolean isSatisfiedBy(Customer cust);
}
Supported By:
BENTO
PRACTICE
public class SpecialOfferSender {
private CustomerIsPremium premiumSpec
public SpecialOfferSende(CustomerIsPremium premiumSpec) {
this.orderRepository = orderRepository;
}
public void sendOffersTo(Customer customer) {
if (this.premiumSpec.isSatisfiedBy(customer)) {
//send offers
}
}
}
Supported By:
Use Spefication for Object Selection
REFACTORING
Supported By:
JOKO
PRACTICE
“get a list of all premium customers”
Supported By:
PRACTICE
 Intro to predicate pattern
 Collection predicate
 JPA predicate
Supported By:
BENTO
PRACTICE
Specification Interface
public interface Specification<T> {
boolean isSatisfiedBy(T t);
Predicate toCollectionPredicate();
}
@Override
public Predicate toCollectionPredicate(Customer customer) {
Predicate<Customer> predicate =
new predicate<Customer>() {
@Override
public boolean apply(Customer input) {
return this.isSatisfiedBy(input);
}
};
return predicate;
}
Supported By:
BENTO
PRACTICE
CustomerIsPremium<Customer> spec= new CustomerIsPremium();
List<Customer> allCustomer = …
Collection<Customer> result =
Collections2.filter(
allCustomer,
spec.toCollectionPredicate()
);
assertArrayEquals(result, … testarray);
TEST PASSED
Supported By:
BENTO
PRACTICE
Specification Interface
public interface Specification<T> {
boolean isSatisfiedBy(T t);
Predicate toCollectionPredicate();
Predicate toPredicate(Root<T> root, CriteriaBuilder cb);
}
@Override
public Predicate toPredicate
(Root<Customer> root, CriteriaBuilder cb) {
return
cb.and (cb.greaterThan(root.get(Customer_.order),3)
);
}
Supported By:
BENTO
PRACTICE
public class DBRepository {
private EntityManager entityManager = ...
public <T> List<T> findAllBySpecification(Specification<T> specification) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
// use specification.getType() to create a Root<T> instance
CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(specification.getType());
Root<T> root = criteriaQuery.from(specification.getType());
// get predicate from specification
Predicate predicate = specification.toPredicate(root, criteriaBuilder);
// set predicate and execute query
criteriaQuery.where(predicate);
return entityManager.createQuery(criteriaQuery).getResultList();
}
}
Supported By:
BENTO
PRACTICE
CustomerIsPremium<Customer> spec= new CustomerIsPremium();
List<Customer> Customer = DBRepository.
findAllBySpecification(spec);
assertArrayEquals(result, … testarray);
TEST PASSED
Supported By:
SUMMARY
 Protect your invariants
 Use object as consistency boundaries
 Encapulate state and behavior with value object
 Encapulate Operations
 Use specification pattern
 Use predicate pattern
Supported By:
Questions ?
Supported By:
Identity CTM for Refactoring,
each monday
REFACTORING
Supported By:
Thanks

More Related Content

Viewers also liked

Our way to microservices
Our way to microservicesOur way to microservices
Our way to microservicesAndi Pangeran
 
Liquidating database frustrations with liquibase
Liquidating database frustrations with liquibaseLiquidating database frustrations with liquibase
Liquidating database frustrations with liquibasePaul Churchward
 
Unbreakable Domain Models - DPC13
Unbreakable Domain Models - DPC13Unbreakable Domain Models - DPC13
Unbreakable Domain Models - DPC13Mathias Verraes
 
Modularity and Domain Driven Design; a killer combination?
Modularity and Domain Driven Design; a killer combination?Modularity and Domain Driven Design; a killer combination?
Modularity and Domain Driven Design; a killer combination?ACA IT-Solutions
 
DDD Basics - Context mapping
DDD Basics - Context mappingDDD Basics - Context mapping
DDD Basics - Context mappingStijn Volders
 
Towards Modelling Processes
Towards Modelling ProcessesTowards Modelling Processes
Towards Modelling ProcessesMathias Verraes
 
Liquibase – a time machine for your data
Liquibase – a time machine for your dataLiquibase – a time machine for your data
Liquibase – a time machine for your dataNeev Technologies
 
Liquibase migration for data bases
Liquibase migration for data basesLiquibase migration for data bases
Liquibase migration for data basesRoman Uholnikov
 
How Symfony Changed My Life
How Symfony Changed My LifeHow Symfony Changed My Life
How Symfony Changed My LifeMatthias Noback
 
Integrating Bounded Contexts - Mini-workshop
Integrating Bounded Contexts - Mini-workshopIntegrating Bounded Contexts - Mini-workshop
Integrating Bounded Contexts - Mini-workshopMatthias Noback
 
Programming with Cmdr. Chris Hadfield
Programming with Cmdr. Chris HadfieldProgramming with Cmdr. Chris Hadfield
Programming with Cmdr. Chris HadfieldMatthias Noback
 
Tactical DDD (just better OOP?) - PHPBenelux 2017
Tactical DDD (just better OOP?) - PHPBenelux 2017Tactical DDD (just better OOP?) - PHPBenelux 2017
Tactical DDD (just better OOP?) - PHPBenelux 2017Matthias Noback
 

Viewers also liked (18)

Our way to microservices
Our way to microservicesOur way to microservices
Our way to microservices
 
Liquidating database frustrations with liquibase
Liquidating database frustrations with liquibaseLiquidating database frustrations with liquibase
Liquidating database frustrations with liquibase
 
Unbreakable Domain Models - DPC13
Unbreakable Domain Models - DPC13Unbreakable Domain Models - DPC13
Unbreakable Domain Models - DPC13
 
Modularity and Domain Driven Design; a killer combination?
Modularity and Domain Driven Design; a killer combination?Modularity and Domain Driven Design; a killer combination?
Modularity and Domain Driven Design; a killer combination?
 
DDD Basics - Context mapping
DDD Basics - Context mappingDDD Basics - Context mapping
DDD Basics - Context mapping
 
Towards Modelling Processes
Towards Modelling ProcessesTowards Modelling Processes
Towards Modelling Processes
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Liquibase – a time machine for your data
Liquibase – a time machine for your dataLiquibase – a time machine for your data
Liquibase – a time machine for your data
 
Liquibase migration for data bases
Liquibase migration for data basesLiquibase migration for data bases
Liquibase migration for data bases
 
How Symfony Changed My Life
How Symfony Changed My LifeHow Symfony Changed My Life
How Symfony Changed My Life
 
Integrating Bounded Contexts - Mini-workshop
Integrating Bounded Contexts - Mini-workshopIntegrating Bounded Contexts - Mini-workshop
Integrating Bounded Contexts - Mini-workshop
 
Context Mapping In Action
Context Mapping In ActionContext Mapping In Action
Context Mapping In Action
 
Liquibase
LiquibaseLiquibase
Liquibase
 
Programming with Cmdr. Chris Hadfield
Programming with Cmdr. Chris HadfieldProgramming with Cmdr. Chris Hadfield
Programming with Cmdr. Chris Hadfield
 
Tactical DDD (just better OOP?) - PHPBenelux 2017
Tactical DDD (just better OOP?) - PHPBenelux 2017Tactical DDD (just better OOP?) - PHPBenelux 2017
Tactical DDD (just better OOP?) - PHPBenelux 2017
 
LiquiBase
LiquiBaseLiquiBase
LiquiBase
 
reveal.js 3.0.0
reveal.js 3.0.0reveal.js 3.0.0
reveal.js 3.0.0
 
Build Features, Not Apps
Build Features, Not AppsBuild Features, Not Apps
Build Features, Not Apps
 

Similar to Refactoring domain driven design way

ASP.NET MVC 3.0 Validation
ASP.NET MVC 3.0 ValidationASP.NET MVC 3.0 Validation
ASP.NET MVC 3.0 ValidationEyal Vardi
 
Restaurant Server.pdf
Restaurant Server.pdfRestaurant Server.pdf
Restaurant Server.pdfShaiAlmog1
 
ngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency InjectionngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency InjectionDzmitry Ivashutsin
 
Creating an Uber Clone - Part XIII - Transcript.pdf
Creating an Uber Clone - Part XIII - Transcript.pdfCreating an Uber Clone - Part XIII - Transcript.pdf
Creating an Uber Clone - Part XIII - Transcript.pdfShaiAlmog1
 
Jakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyJakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyPaweł Tekliński
 
Vaadin DevDay 2017 - Data Binding in Vaadin 8
Vaadin DevDay 2017 - Data Binding in Vaadin 8Vaadin DevDay 2017 - Data Binding in Vaadin 8
Vaadin DevDay 2017 - Data Binding in Vaadin 8Peter Lehto
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014Guillaume POTIER
 
"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita Galkin"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita GalkinFwdays
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesCiaranMcNulty
 
Creating a Whatsapp Clone - Part XIV - Transcript.pdf
Creating a Whatsapp Clone - Part XIV - Transcript.pdfCreating a Whatsapp Clone - Part XIV - Transcript.pdf
Creating a Whatsapp Clone - Part XIV - Transcript.pdfShaiAlmog1
 
Automatically Repairing Test Cases for Evolving Method Declarations
Automatically Repairing Test Cases for Evolving Method DeclarationsAutomatically Repairing Test Cases for Evolving Method Declarations
Automatically Repairing Test Cases for Evolving Method DeclarationsICSM 2010
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015Fernando Daciuk
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using CodeceptionJeroen van Dijk
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
Udi Dahan Intentions And Interfaces
Udi Dahan Intentions And InterfacesUdi Dahan Intentions And Interfaces
Udi Dahan Intentions And Interfacesdeimos
 
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
 
Pruebas unitarias con django
Pruebas unitarias con djangoPruebas unitarias con django
Pruebas unitarias con djangoTomás Henríquez
 

Similar to Refactoring domain driven design way (20)

ASP.NET MVC 3.0 Validation
ASP.NET MVC 3.0 ValidationASP.NET MVC 3.0 Validation
ASP.NET MVC 3.0 Validation
 
Restaurant Server.pdf
Restaurant Server.pdfRestaurant Server.pdf
Restaurant Server.pdf
 
ngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency InjectionngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency Injection
 
Creating an Uber Clone - Part XIII - Transcript.pdf
Creating an Uber Clone - Part XIII - Transcript.pdfCreating an Uber Clone - Part XIII - Transcript.pdf
Creating an Uber Clone - Part XIII - Transcript.pdf
 
Jakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testyJakość dostarczanego oprogramowania oparta o testy
Jakość dostarczanego oprogramowania oparta o testy
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Vaadin DevDay 2017 - Data Binding in Vaadin 8
Vaadin DevDay 2017 - Data Binding in Vaadin 8Vaadin DevDay 2017 - Data Binding in Vaadin 8
Vaadin DevDay 2017 - Data Binding in Vaadin 8
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014
 
"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita Galkin"Auth for React.js APP", Nikita Galkin
"Auth for React.js APP", Nikita Galkin
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
Creating a Whatsapp Clone - Part XIV - Transcript.pdf
Creating a Whatsapp Clone - Part XIV - Transcript.pdfCreating a Whatsapp Clone - Part XIV - Transcript.pdf
Creating a Whatsapp Clone - Part XIV - Transcript.pdf
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Automatically Repairing Test Cases for Evolving Method Declarations
Automatically Repairing Test Cases for Evolving Method DeclarationsAutomatically Repairing Test Cases for Evolving Method Declarations
Automatically Repairing Test Cases for Evolving Method Declarations
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Udi Dahan Intentions And Interfaces
Udi Dahan Intentions And InterfacesUdi Dahan Intentions And Interfaces
Udi Dahan Intentions And Interfaces
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Pruebas unitarias con django
Pruebas unitarias con djangoPruebas unitarias con django
Pruebas unitarias con django
 

Recently uploaded

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 

Recently uploaded (20)

Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 

Refactoring domain driven design way

  • 1. REFACTORING CODE DOMAIN DRIVEN DESIGN WAY Supported By:
  • 2. Supported By: I’M ANDI PANGERAN @andi_pangeran cybercoding.wordpress.com
  • 3. Supported By: AGENDA  PRACTICE HOW TO REFACTORING CODE BASED ON DOMAIN DRIVEN DESIGN MINDSET  PRACTICE HOW TO WRITE UNIT TESTING
  • 4. Supported By: JOKO Individual who has significant expertise in the domain of the system being developed. DOMAIN EXPERT MEET OUR ACTOR
  • 5. Supported By: BENTO Individual who has spend all of his life for coding. PROGRAMMER MEET OUR ACTOR
  • 7. Supported By: Protect your invariants REFACTORING
  • 8. Supported By: JOKO PRACTICE “A customer must always have an email address.”
  • 9. Supported By: PRACTICE BENTO public class Customer { private String email; public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
  • 10. Supported By: PRACTICE BENTO public class CostumerTest { @Test public void should_always_have_an_email() { Customer customer = new Customer(); assertEquals(customer.getEmail(), "andi.pangeran@jtravl.com"); } } TEST FAIL
  • 11. Supported By: PRACTICE BENTO public class CostumerTest { @Test public void should_always_have_an_email() { Customer customer = new Customer(); customer.setEmail("andi.pangeran@jtravl.com"); assertEquals(customer.getEmail(), "andi.pangeran@jtravl.com"); } } TEST PASSED
  • 12. Supported By: PRACTICE BENTO public class Customer { private String email; public Customer(String email) { this.email = email; } }
  • 13. Supported By: PRACTICE BENTO public class CostumerTest { @Test public void should_always_have_an_email() { Customer customer = new Customer("andi.pangeran@jtravl.com"); assertEquals(customer.getEmail(), "andi.pangeran@jtravl.com"); } } TEST PASSED
  • 14. Supported By: Use object as concistency boundaries REFACTORING
  • 15. Supported By: JOKO PRACTICE “later prospective customer can be upgraded to paying customer“ “Paying customer must have phone number” “we have two type of customer, prospective and paying customer.”
  • 16. Supported By: PRACTICE BENTO public class ProspectiveCustomer extends Customer { /* other attribute */ } public class PayingCustomer extends Customer { /* other attribute */ private String phone; public PayingCustomer(String email, String phone) { super(email); this.phone = phone; } }
  • 17. Supported By: PRACTICE BENTO @Test public void upgraded_prospective_paying() { ProspectiveCustomer pcustomer = new ProspectiveCustomer("andi.pangeran@jtravl.com"); assertEquals(pcustomer.getEmail(), "andi.pangeran@jtravl.com"); PayingCustomer payCustomer = new PayingCustomer(pcustomer.getName(), “0852xxx”); assertEquals(payCustomer.getEmail(), "andi.pangeran@jtravl.com"); assertEquals(payCustomer.getPhone(), " 0852xxx"); } TEST FAIL
  • 18. Supported By: PRACTICE BENTO @Test public void upgraded_prospective_paying() { ProspectiveCustomer pcustomer = new ProspectiveCustomer("andi.pangeran@jtravl.com"); assertEquals(pcustomer.getEmail(), "andi.pangeran@jtravl.com"); PayingCustomer payCustomer = new PayingCustomer(pcustomer.getEmail(), “0852xxx”); assertEquals(payCustomer.getEmail(), "andi.pangeran@jtravl.com"); assertEquals(payCustomer.getPhone(), " 0852xxx"); } TEST PASSED
  • 19. Supported By: PRACTICE BENTO public class ProspectiveCustomer extends Customer { /* other attribute */ public PayingCustomer upgradeToPayingCustomer(String phone) { return new PayingCustomer(this.email, phone); } } public class PayingCustomer extends Customer { /* other attribute */ private String phone; public PayingCustomer(String email, String phone) { super(email); this.phone = phone; } }
  • 20. Supported By: PRACTICE BENTO @Test public void upgraded_prospective_paying() { ProspectiveCustomer pcustomer = new ProspectiveCustomer("andi.pangeran@jtravl.com"); assertEquals(pcustomer.getEmail(), "andi.pangeran@jtravl.com"); PayingCustomer payCustomer = pcostumer.upgradeToPaying(“0852xxx”); assertEquals(payCustomer.getEmail(), "andi.pangeran@jtravl.com"); assertEquals(payCustomer.getPhone(), " 0852xxx"); } TEST PASSED
  • 21. Supported By: JOKO PRACTICE “Paying customer must always have a valid phone number”
  • 22. Supported By: PRACTICE BENTO @Test public void upgraded_prospective_paying() { PayingCustomer payCustomer = new PayingCustomer(“test@mail.com", “badphonenumber”); exception.expect(IllegalArgumentException.class); } TEST FAIL
  • 23. Supported By: PRACTICE BENTO public class PayingCustomer extends Customer { /* other attribute */ private String phone; public PayingCustomer(String email, String phone) { super(email); if (/* validation stuff of phone*/ ) { throw new IllegalArgumentException(); } this.phone = phone; } } TEST PASSED
  • 24. Supported By: PRACTICE BENTO public class PayingCustomer extends Customer { /* other attribute */ private String phone; public PayingCustomer(String email, String phone) { super(email); if (/* validation stuff of phone*/ ) { throw new IllegalArgumentException(); } this.phone = phone; } } TEST PASSED
  • 25. Supported By: Encapulate state and behavior with value object REFACTORING
  • 26. Supported By: PRACTICE  Intro to value object  Intro to immutable object
  • 27. Supported By: PRACTICE BENTO public class PhoneNumber { private final String phone; public PhoneNumber(String phone) { if (/* validation stuff of phone*/ ) { throw new IllegalArgumentException(); } this.phone = phone; } public String getPhone() { { return this.phone; } }
  • 28. Supported By: PRACTICE BENTO public class PayingCustomer extends Customer { /* other attribute */ private PhoneNumber phone; public PayingCustomer(String email, PhoneNumber phone) { super(email); this.phone = phone; } } TEST PASSED
  • 29. Supported By: PRACTICE BENTO @Test public void upgraded_prospective_paying() { PayingCustomer payCustomer = new PayingCustomer(“test@mail.com", new PhoneNumber(“badphonenumber”)); exception.expect(IllegalArgumentException.class); } TEST PASSED
  • 31. Supported By: JOKO PRACTICE “a Customer orders product and pays for them”
  • 32. Supported By: Service.create BENTO Order order = new Order(); order.setCustomer(customer); order.setProducts(products); order.setStatus(PAYMENTSTATUS.UNPAID); order.setPaidAmount(500); order.setPaidCurrency(CURRENCY.IDR); order.setStatus(PAYMENTSTATUS.PAID); PRACTICE Service.pay
  • 33. Supported By: Service.create BENTO Order order = new Order(); order.setCustomer(customer); order.setProducts(products); order.setStatus(new PaymentStatus(PAYMENTSTATUS.UNPAID)); order.setPaidAmount(500); order.setPaidCurrency(CURRENCY.IDR); order.setStatus(new PaymentStatus(PAYMENTSTATUS.PAID)); PRACTICE Service.pay
  • 34. Supported By: Service.create BENTO Order order = new Order(); order.setCustomer(customer); order.setProducts(products); order.setStatus(new PaymentStatus(PAYMENTSTATUS.UNPAID)); order.setPaidMonetary(new Money(500, CURRENCY.IDR)); order.setStatus(new PaymentStatus(PAYMENTSTATUS.PAID)); PRACTICE Service.pay
  • 35. Supported By: Service.create BENTO Order order = new Order(customer, products); //set payment status in order constructor order.setPaidMonetary(new Money(500, CURRENCY.IDR)); order.setStatus(new PaymentStatus(PAYMENTSTATUS.PAID)); PRACTICE Service.pay
  • 36. Supported By: Service.create BENTO Order order = new Order(customer, products); //set payment status in order constructor order.pay (new Money(500, CURRENCY.IDR)); //set payment status in pay procedure PRACTICE Service.pay
  • 40. Supported By: JOKO PRACTICE “order 3 times to become premium customer”
  • 41. Supported By: Specification Interface BENTO public interface Specification<T> { boolean isSatisfiedBy(T t); Class<T> getType(); } PRACTICE Specification Abstract abstract public class AbstractSpecification<T> implements Specification<T> { @Override public boolean isSatisfiedBy(T t) { throw new NotImplementedException(); } /othercode }
  • 42. Supported By: BENTO public class CustomerIsPremium extends AbstractSpecification<Customer> { private OrderRepository orderRepository public CustomerIsPremium(OrderRepository orderRepository) { this.orderRepository = orderRepository; } @Override public boolean isSatisfiedBy(Customer customer) { int count = this.orderRepository.countByCustomer(customer.getId); return (count > 3); } } PRACTICE
  • 43. Supported By: PRACTICE BENTO @Test public void specification_customer_premium() { CustomerIsPremium<Customer> spec= new CustomerIsPremium(); customer2order = … customer3order = … assertFalse(spec.isSatisfiedBy(customer2order)); assertTrue(spec.isSatisfiedBy(customer3order)); } TEST PASSED
  • 44. Supported By: JOKO PRACTICE “different rules apply for different tenants.”
  • 45. Supported By: BENTO public class CustomerWith3OrdersIsPremium implement CustomerIsPremium {} public class CustomerWith500kPremium implement CustomerIsPremium {} public class CustomerWithSpecialRequiredmentPremium implement CustomerIsPremium {} PRACTICE Specification Interface public interface CustomerIsPremium extends Specification<Customer> { boolean isSatisfiedBy(Customer cust); }
  • 46. Supported By: BENTO PRACTICE public class SpecialOfferSender { private CustomerIsPremium premiumSpec public SpecialOfferSende(CustomerIsPremium premiumSpec) { this.orderRepository = orderRepository; } public void sendOffersTo(Customer customer) { if (this.premiumSpec.isSatisfiedBy(customer)) { //send offers } } }
  • 47. Supported By: Use Spefication for Object Selection REFACTORING
  • 48. Supported By: JOKO PRACTICE “get a list of all premium customers”
  • 49. Supported By: PRACTICE  Intro to predicate pattern  Collection predicate  JPA predicate
  • 50. Supported By: BENTO PRACTICE Specification Interface public interface Specification<T> { boolean isSatisfiedBy(T t); Predicate toCollectionPredicate(); } @Override public Predicate toCollectionPredicate(Customer customer) { Predicate<Customer> predicate = new predicate<Customer>() { @Override public boolean apply(Customer input) { return this.isSatisfiedBy(input); } }; return predicate; }
  • 51. Supported By: BENTO PRACTICE CustomerIsPremium<Customer> spec= new CustomerIsPremium(); List<Customer> allCustomer = … Collection<Customer> result = Collections2.filter( allCustomer, spec.toCollectionPredicate() ); assertArrayEquals(result, … testarray); TEST PASSED
  • 52. Supported By: BENTO PRACTICE Specification Interface public interface Specification<T> { boolean isSatisfiedBy(T t); Predicate toCollectionPredicate(); Predicate toPredicate(Root<T> root, CriteriaBuilder cb); } @Override public Predicate toPredicate (Root<Customer> root, CriteriaBuilder cb) { return cb.and (cb.greaterThan(root.get(Customer_.order),3) ); }
  • 53. Supported By: BENTO PRACTICE public class DBRepository { private EntityManager entityManager = ... public <T> List<T> findAllBySpecification(Specification<T> specification) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); // use specification.getType() to create a Root<T> instance CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(specification.getType()); Root<T> root = criteriaQuery.from(specification.getType()); // get predicate from specification Predicate predicate = specification.toPredicate(root, criteriaBuilder); // set predicate and execute query criteriaQuery.where(predicate); return entityManager.createQuery(criteriaQuery).getResultList(); } }
  • 54. Supported By: BENTO PRACTICE CustomerIsPremium<Customer> spec= new CustomerIsPremium(); List<Customer> Customer = DBRepository. findAllBySpecification(spec); assertArrayEquals(result, … testarray); TEST PASSED
  • 55. Supported By: SUMMARY  Protect your invariants  Use object as consistency boundaries  Encapulate state and behavior with value object  Encapulate Operations  Use specification pattern  Use predicate pattern
  • 57. Supported By: Identity CTM for Refactoring, each monday REFACTORING