SlideShare uma empresa Scribd logo
1 de 68
Baixar para ler offline
JakubPilimon
Refactor And Do It
Safely
Jakub Pilimon
JakubPilimon
SZCZEBRZESZYN
CHRZĄSZCZYRZEWOSZYCE
JakubPilimon
JakubPilimon
Jakub Pilimon
Principal Technologist @Pivotal
•Domain-Driven Design
•Test-Driven Development
•Architecture
•Spring
pillopl.github.io
#dddbyexamples
https://github.com/ddd-by-examples
JakubPilimon
JakubPilimon
WHAT THIS TALK IS
NOT ABOUT
JakubPilimon
JakubPilimon
JakubPilimon
BIG BALL OF MUD
JakubPilimon
NO STRUCTURE
SLOPPY
DUCT-TYPE STYLE
JakubPilimon
COUPLING
JakubPilimon
HARD TO
UNDERSTAND
MAINTAIN
DELIVER VALUE
JakubPilimon
TIME TO
REFACTOR?
JakubPilimon
IS THERE ANY
BUSINESS VALUE
LOST?
JakubPilimon
OUR JOB AS ENGINEERS
IS BRINGING VALUE,
NOT JUST SATISFYING
OUR AESTHETICS
NEEDS
JakubPilimon
WHAT IS
REFACTORING
ANYWAYS?
JakubPilimon
–Michael C. Feathers
“Code refactoring is the process of
restructuring existing computer code
—changing the factoring—
without changing its observable
behavior. (!!!)”
JakubPilimon
NOBODY IS GOING
TO PAY FOR THAT
JakubPilimon
DON’T SAY
“REFACTORING”
JakubPilimon
CREATE COMMON
UNDERSTANDING
“Introducing Event
Storming” by Alberto
Brandolini
JakubPilimon
USE MEASURABLE DATA
“Introducing Event Storming” by Alberto
Brandolini
JakubPilimon
USE MAGIC*
*MAGIC = ENGINEERING
JakubPilimonJakubPilimon
JakubPilimon
TREAT REFACTORING
AS A FEATURE
THAT ENABLES YOU TO
DELIVER FEATURES
QUICKER
JakubPilimonJakubPilimon
•Desirable observable
behavior of 🦄 is the
same as 💩 - it is
refactoring
• 🦄 is clean and ready
for new requirements
How it works
JakubPilimon
HOW TO REFACTOR?
JakubPilimon
HOW TO REFACTOR
WITHOUT TESTS?
“…without changing its observable behavior…”
JakubPilimon
OBSERVABLE BEHAVIORS
CAN BE EXPRESSED AS
AUTOMATED TEST SCENARIOS
*ALMOST ALWAYS
JakubPilimon
UNIT
INTEGRATION
E2E
JakubPilimon
JakubPilimon
JakubPilimon
JakubPilimon
IF IT WAS EASY TO ADD
UNIT TESTS IT WOULD
NOT BE A BIG BALL OF
MUD
JakubPilimon
UNIT
INTEGRATION
E2EE2E
INTEGRATION
UNIT
JakubPilimon
HOW TO FIND
SCENARIOS TO
TEST?
JakubPilimon
LOOK AT THE WALL
Place CollectOnly if
books on
Placed Book
Hold
Hold
Collected
Books
Placed on
Hold
JakubPilimonJakubPilimon
Place Book
On Hold
Only if
books on
hold < 5
HoldExpir
ed
4. Rule
2. Command
Placed On
Hold 1. Domain Event
Collected
Books View
View
3. Query
JakubPilimonJakubPilimon
Black-box testing of observable behaviors
Collect
Book
Collected
Books View
Command
API call
queue listener
db script
executed…
Query
API call
Excel sheet
DB query
Place
Book On
Hold
Collected
Books View
Collect
Book
Placed on
Hold Books
View
JakubPilimonJakubPilimon
Black-box testing of observable behaviors
@Test
public void patronCanHoldABook() {
//given
BookEntity book = fixtures.aCirculatingBookAvailableForLending();
//and
BookHolderEntity patron = fixtures.aRegularPatron();
//when
patronWantsToHoldBook(patron, book);
//then
assertThat(placedOnHoldsBooksBy(patron)).containsExactlyInAnyOrder(book);
}
Hold
Book
Books on
Hold View
Observable Behaviors!!!
JakubPilimonJakubPilimon
Exploratory testing against present data sets
Place
Book On
Hold
Collected
Books View
Collect
Book
Placed on
Hold Books
View
Production copy/Staging
Amy John
JakubPilimonJakubPilimon
Reverse engineering from tests to business rules
@Test
public void patronCanHoldABook() {
//given
BookEntity book = bookFromDb(“Domain-Driven Design”);
//and
BookHolderEntity john = fromDb(“John”);
//and
BookHolderEntity amy = fromDb(“Amy”);
//when
assertThatExceptionIsThrown(()-> patronWantsToHoldBook(john, book)); //exception
patronWantsToHoldBook(amy, book); //success
//then
assertThat(placedOnHoldsBooksBy(amy)).containsExactlyInAnyOrder(book);
}
Heuristics about rules
5 holds
rule?
Researcher
can book
Restricted
books?
John has
overdue
books?
DDD
Book is
special?
Why
exception?
Why
success?
JakubPilimon
How to make the transition?
JakubPilimon
Option #1: Climbing step by step (💩 slowly becomes 🦄)
Option #2: Blue/Green refactoring (🦄 side by side with 💩)
JakubPilimonJakubPilimon
• 💩 slowly becomes 🦄
•Observable effects of 💩
kept
•Cannot easily rollback to
💩 from 🦄
•Need to dig in 💩
•Need to maintain one
model
Step by Step Refactoring
JakubPilimon
JakubPilimonJakubPilimon
• 💩 remains untouched
•Observable behavior of 💩
kept
•Easy to rollback to 💩 from
🦄
• 🦄 feels a bit like a green
field in 💩
•Need to maintain both 💩 🦄
•Need to somehow plugin 🦄
to the observable behaviors
Blue/Green Refactoring
JakubPilimon
JakubPilimon
Place
Book On
Hold
Collected
Books View
How it works
Collect
Book
Placed on
Hold Books
View
JakubPilimon
How to plug in new model to
observable behaviors?
JakubPilimon
–Michael C. Feathers
“A seam is a place where you can alter behaviour
in your program without editing in that place”
JakubPilimon
HOW TO LOOK FOR
SEEMS?
Collected
Books View
Place
Book On
Hold
JakubPilimon
public List<BookDto> booksPlacedOnHoldBy(UUID patronId, List<BookDto> oldModel) {
if (NewModelToggles.USE_NEW_MODEL.isActive()) {
List<BookDto> newModel = newLendingModel.booksOnHoldBy(patronId));
reconciliation.compare(oldModel, newModel);
return newModel;
}
return oldModel;
}
Anti-Corruption Layer
@GetMapping("/holds/{holderId}")
public ResponseEntity<List<BookDto>> getPlacedOnHoldBooks(UUID holderId) {
List<BookDto> oldModel = bookHolderService.getBooks(holderId);
return ResponseEntity.ok(lendingACL.booksPlacedOnHoldBy(holderId, oldModel));
}
Collected
Books View
JakubPilimon
Switch between models while querying
Collected
Books View
OR
Uses Feature Toggles for Querying
Query
JakubPilimon
Anti-Corruption Layer
@PostMapping("/books/collections")
public ResponseEntity collect(BookRequest bookRequest) {
oldModel.createCollectedBook(bookRequest.getBookId(),
bookRequest.getDays());
lendingACL.collect(bookRequest);
return ResponseEntity.ok().build();
}
Place
Book On
Hold
JakubPilimon
Parallel Operations For Commands
Collect
AND
Command
JakubPilimon
New model command failure cannot affect old
model result!
try/catch/log - might be your friend
JakubPilimon
JakubPilimon
Dependencies between packages
Old Lending Model New Lending Model
JakubPilimon
public List<BookDto> booksPlacedOnHoldBy(UUID patronId, List<BookDto> oldModel) {
if (NewModelToggles.RECONCILE_NEW_MODEL.isActive()) {
List<BookDto> newModel = newLendingModel.booksOnHoldBy(patronId));
reconciliation.compare(oldModel, newModel);
return oldModel;
}
if (NewModelToggles.RECONCILE_AND_USE_NEW_MODEL.isActive()) {
List<BookDto> newModel = newLendingModel.booksOnHoldBy(patronId));
reconciliation.compare(oldModel, newModel);
return newModel;
}
return oldModel;
}
Reconciliation in the ACL
JakubPilimon
Reconciliation
class Reconciliation<T> {
private final Reaction reaction;
public Diff<T> compare(Set<T> oldOne, Set<T> newOne) {
Diff<T> difference = new Diff<>(oldOne, newOne);
if (difference.exists()) {
reaction.reactTo(difference);
}
return difference;
}
}
interface Reaction {
void reactTo(Diff diff);
static Reaction logAndThanDisableToggle() {
return new CompositeReaction(justLog(), diff -> disableToggle());
}
static Reaction justLog() {
return System.out::println;
}
}
JakubPilimon
Add new model
to a next seam
Go to prod
Switch toggle to old model
Reconcile
Gather feedback
Switch toggle to new model
JakubPilimon
Place
Book On
Hold
Collected
Books View
Collect
Book
Placed on
Hold Books
View
Place
Book On
Hold
Collected
Books View
Collect
Book
Placed on
Hold Books
View
Black-box testing of observable behaviors should
pass against two models!
JakubPilimon
Black-box testing of observable behaviors should
pass against two models!
@Test
public void patronCanHoldABook() {
//given
BookEntity book = fixtures.aCirculatingBookAvailableForLending();
//and
BookHolderEntity patron = fixtures.aRegularPatron();
//when
patronWantsToHoldBookInNewModel(patron, book);
//then
assertThat(newModelPlacedOnHoldsBooksBy(patron)).containsExactlyInAnyOrder(book);
}
@Rule
public TogglzRule togglzRule = TogglzRule.allDisabled(NewModelToggles.class);
List<UUID> newModelPlacedOnHoldsBooksBy(BookHolderEntity aRegularPatron) {
togglzRule.enable(NewModelToggles.RECONCILE_AND_USE_NEW_MODEL);
//..
}
JakubPilimon
Place
Book On
Hold
Collected
Books View
Collect
Book
Placed on
Hold Books
View
Automated verification of two models
@Test
public void researcherCanPlaceOpenEndedHolds() {
//given
BookHolderEntity aResearcherPatron = fixtures.aResearcherPatron();
//when
patronWantsToHoldBookForOpenEndedHold(aResearcherPatron, aCirculatingBook);
//and
List<UUID> oldModel = oldModelPlacedOnHoldsBooksBy(aResearcherPatron);
List<UUID> newModel = newModelPlacedOnHoldsBooksBy(aResearcherPatron);
//then
assertThat(oldModel).containsExactlyInAnyOrderElementsOf(newModel);
}
JakubPilimon
Place
Book On
Hold
Collected
Books View
Collect
Book
Placed on
Hold Books
View
Production copy/Staging
Amy John
JakubPilimon
Exploratory testing against present data set after data
migration from 💩 to 🦄
Place
Book On
Hold
Collected
Books View
Collect
Book
Placed on
Hold Books
View
Production copy/Staging
Amy John
JakubPilimon
UNIT
INTEGRATION
E2EE2E
INTEGRATION
UNIT
JakubPilimon
When we are sure…
Collected
Books View
3
JakubPilimon
Dependencies between packages
Old Lending Model New Lending Model
BBOM
JakubPilimon
JakubPilimon
Modular monolith
Is the system modular?
Isthesystemdistributed?
Big Ball Of Mud
Distributed
Big Ball Of Mud
Modular Monolith
Microservices
JakubPilimon
• Always, ALWAYS! Test if ACL works correctly (returning
correct models depending on the toggle settings)
• Always test if ACL does reconciliation correctly!
• Add test that checks that your feature toggle is disabled/
enabled by default
• Go to production and reconcile very quickly (after 1st
seam)
• Make sure new model failures do not affect old model
• With B/G Refactoring you are limited to programming
language and database of BBOM
JakubPilimon
Lessons Learned
JakubPilimon
https://github.com/pilloPl/bigballofmud
THANK YOU!

Mais conteúdo relacionado

Mais de VMware Tanzu

Mais de VMware Tanzu (20)

Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdfSpring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
 
tanzu_developer_connect.pptx
tanzu_developer_connect.pptxtanzu_developer_connect.pptx
tanzu_developer_connect.pptx
 
Tanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - FrenchTanzu Virtual Developer Connect Workshop - French
Tanzu Virtual Developer Connect Workshop - French
 
Tanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - EnglishTanzu Developer Connect Workshop - English
Tanzu Developer Connect Workshop - English
 
Virtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - EnglishVirtual Developer Connect Workshop - English
Virtual Developer Connect Workshop - English
 
Tanzu Developer Connect - French
Tanzu Developer Connect - FrenchTanzu Developer Connect - French
Tanzu Developer Connect - French
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring BootSpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
 
SpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software EngineerSpringOne Tour: The Influential Software Engineer
SpringOne Tour: The Influential Software Engineer
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs PracticeSpringOne Tour: Domain-Driven Design: Theory vs Practice
SpringOne Tour: Domain-Driven Design: Theory vs Practice
 
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense SolutionsSpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
SpringOne Tour: Spring Recipes: A Collection of Common-Sense Solutions
 
SpringOne Tour: Doing Progressive Delivery with your Team
SpringOne Tour: Doing Progressive Delivery with your TeamSpringOne Tour: Doing Progressive Delivery with your Team
SpringOne Tour: Doing Progressive Delivery with your Team
 
SpringOne Tour: Make the Right Thing the Obvious Thing: The Journey to Intern...
SpringOne Tour: Make the Right Thing the Obvious Thing: The Journey to Intern...SpringOne Tour: Make the Right Thing the Obvious Thing: The Journey to Intern...
SpringOne Tour: Make the Right Thing the Obvious Thing: The Journey to Intern...
 
SpringOne Tour: An Introduction to Azure Spring Apps Enterprise
SpringOne Tour: An Introduction to Azure Spring Apps EnterpriseSpringOne Tour: An Introduction to Azure Spring Apps Enterprise
SpringOne Tour: An Introduction to Azure Spring Apps Enterprise
 
SpringOne Tour: 10 Practical Tips for Building Native and Serverless Spring A...
SpringOne Tour: 10 Practical Tips for Building Native and Serverless Spring A...SpringOne Tour: 10 Practical Tips for Building Native and Serverless Spring A...
SpringOne Tour: 10 Practical Tips for Building Native and Serverless Spring A...
 
SpringOne Tour: Spring Boot 3 and Beyond
SpringOne Tour: Spring Boot 3 and BeyondSpringOne Tour: Spring Boot 3 and Beyond
SpringOne Tour: Spring Boot 3 and Beyond
 
SpringOne Tour 2023: Let's Get Streaming! A Guide to Orchestrating Spring Clo...
SpringOne Tour 2023: Let's Get Streaming! A Guide to Orchestrating Spring Clo...SpringOne Tour 2023: Let's Get Streaming! A Guide to Orchestrating Spring Clo...
SpringOne Tour 2023: Let's Get Streaming! A Guide to Orchestrating Spring Clo...
 
Tanzu Developer Connect | Public Sector | March 29, 2023.pdf
Tanzu Developer Connect | Public Sector | March 29, 2023.pdfTanzu Developer Connect | Public Sector | March 29, 2023.pdf
Tanzu Developer Connect | Public Sector | March 29, 2023.pdf
 

Último

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
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
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
+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
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 

Último (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
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
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
 
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 🔝✔️✔️
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
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
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
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
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
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
 
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 🔝✔️✔️
 
+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...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
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 ...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 

Refactor And Do It Safely - Jakub Pilimon