SlideShare ist ein Scribd-Unternehmen logo
1 von 46
Downloaden Sie, um offline zu lesen
Balša Šarenac, Stéphane Ducasse and Nicolas Anquetil
A New Architecture
Reconciling Refactorings and Transformations
Evref
fervE
Definitions
• Transformation
• Refactoring
• Precondition
• Atomic refactoring
• Composite refactoring
2
Imagine a world with only refactorings
• Then you have to do your transformations by hand
• Override an existing method
3
Imagine a world with only transformations
• Then you can break your systems with just adding a method (as in VSCode :))
4
We need both refactorings
and transformations
5
Example
6
Code example
RBInlineMethodRefactoring >> preconditions
. . . .
self isOverridden ifTrue: [
self refactoringWarning:
('<1p>>><2s> is overridden. Do you want to inline it
anyway?’
expandMacrosWith: self classOfTheMethodToInline
with: self inlineSelector) ] ].
. . . . .
7
Transformations AND Refactorings
• G. De Souza Santos de
fi
ned Transformations and CompositeTransformations
• But a lot of code duplication
• Di
ffi
cult to understand when using what
• What about preconditions?
8
Goals of our engineering effort
• Modernise our engine
• Reduce code duplication
• Cleaner code
• More tests
• Assess refactorings (clear/correct preconditions / semantics)
• Usability issues
9
Goals of our scientific work
• Reuse of transformations and refactorings to form new ones
• Understand composition issues (ongoing)
• Our ultimate goal is
• Support you to write your own transformation
• Domain speci
fi
c refactoring de
fi
nitions
10
A solid basis
• A refactoring reasons on a program model
• Check preconditions on such a program model
• Produces
fi
rst class changes that can be previewed
• Then and only then actual modi
fi
cations are done
Refactorings
RBMethod
RBNamespace
RBEntity
RBAbstractClass
RBPackage
RBMetaclass
RBClass
Changes
AST
ParseTreeRewriter
Condition
Program Model
11
A kind atomic approach
• A refactoring reasons on a program model
• Check preconditions on such a program model
• Produces
fi
rst class changes that can be previewed
• Then if something fails you can not apply the modi
fi
cations
12
About
Preconditions
13
Do you think that transformations
needs preconditions?
14
“Transformation-based Refactorings” [IWST22]
shows that there are different kinds of preconditions
15
Different kind of Preconditions
See IWST 22
• Applicability
• Breaking change
• Skipping
• Others
16
applicabilityPreconditions
RBAddMethodTransformation >> applicabilityPreconditions
. . . class should exist . . .
. . . method should be parsable . . .
17
breakingChangesPrecondition
RBAddMethodRefactoring >> applicabilityPreconditions
. . . method shouldn’t be overridden . . .
18
About Reuse
19
Clear separation
• Refactorings have breaking changes preconditions
• Transformations have applicability preconditions
20
Example
Add method
RBAddMethodTransformation
preconditions()
applicabilityPreconditions()
privateTransform()
RBAddMethodRefactoring
preconditions()
breakingChangePreconditions()
privateTransform()
21
Example
Add method
RBAddMethodRefactoring >> privateTransform
transformation privateTransform
RBAddMethodTransformation >> privateTransform
self definingClass
compile: sourceCode
classified: protocol
RBAddMethodRefactoring >> preconditions
transformation checkPreconditions.
^ self breakingChangePreconditions
22
Refactorings are decorators for transformations
• Refactoring uses Transformation to check applicability conditions
• Refactoring checks breaking change conditions
• Refactoring uses Transformation to make changes
• [Refactoring does cleanups and
fi
xes if needed]
RBAddMethodRefactoring —> RBAddMethodTransformation
23
State of situation
• We are in the process of converting all the implementation to this design
24
About
engineering
25
Realigning transformations and refactorings
• Better API
• Partial instantiation of refactorings to support better interaction
• Moving more responsibilities to refactorings
26
Revisit preconditions
• Some preconditions were obscure / wrong
• Clearly identify breaking and applicability preconditions
• Adding a lot of comments
• Fixing, enhancing tests
27
About the (T)
• You are warn when
you use a
Transformation
28
Cmd to Cm2.0
RBRefactoring
execute()
CmdCommand
prepareFullExecutionInContext()
createRefactoring()
execute()
RBRefactoring
execute()
CmCommand
prepareFullExecutionInContext()
isApplicable()
executeRefactoring()
29
About UI
RBRefactoring
execute()
CmdCommand
prepareFullExecutionInContext()
createRefactoring()
execute()
UI
UI
UI
UI
UI
UI
UI
30
Preconditions should not raise UI!
‣ Preconditions had a lot of UI like:
• Gather user input
• Raise warnings
• Show con
fi
rmation dialogs
31
New Tooling
RBRefactoring
generateChanges()
performChanges()
RBDriver
configureRefactoring()
runRefactoring()
openPreviewWithChagnes(changes)
SycCmCommand
prepareFullExecutionInContext()
isApplicable()
executeRefactoring()
UI
32
New Architecture
33
Refactorings
RBMethod
RBNamespace
RBEntity
RBAbstractClass
RBPackage
RBMetaclass
RBClass
Changes
AST
ParseTreeRewriter
Condition
Program Model
Drivers
UI
Driver
‣ UI is Driver’s responsibility now
• Con
fi
gures refactorings
• Gathers user input
• Displays errors and warnings
• Displays any other relevant information (noti
fi
cations, browsers, etc.)
34
Open questions
• Do we keep warning and exceptions
• Why not having failing reports that can be nicely displayed
35
About
Composition
(Started recently)
36
Existing Refactorings are monolithic
• G. De Souza Santos started to de
fi
ne more modular transformations
(RBCompositeTransformation)
• We introduced
• RBCompositeRefactoring
• Starting to play with composition semantics :)
37
Composite
RBRefactoring
execute()
preconditions()
privateTransform()
CmdCommand
prepareFullExecutionInContext()
createRefactoring()
execute()
RBCompositeRefactoring
preconditions()
privateTransform()
38
Let us study RemoveInstanceVariables
39
refactoring := RBCompositeRefactoring new
model: model;
refactorings: (variables collect: [:each |
RBRemoveInstanceVariableRefactoring
model: model
remove: each
from: class]);
yourself
RBCompositeRefactoring
• Execute in sequence refactorings
• P1, T1; P2, T2; … Pn Tn
40
RBCompositeRefactoring >> privateTransform
refactorings do: [ :each | each generateChanges ]
Different execution semantics
• Stop on failure (as RBCompositeRefactoring)
• Skip failed and proceed (as RBCompositeContinuingRefactoring)
RBCompositeContinuingRefactoring >> privateTransform
refactorings do:
[ :each |
[ each generateChanges] on: RBRefactoringError do: [ :ex | ]
]
41
Custom composite example
Can we remove both fooUnik and barUnikUnik?
X >> fooUnik
^ 12
X >> barUnikUnik
^ self fooUnik + 1
42
Custom composite need
removeMethods (fooUnik, barUnikUnik)
is not equals to
removeMethod (fooUnik);
removeMethod (barUnikUnik)
43
Custom composite
RBCompositeRefactoring
preconditions()
privateTransform()
RBCompositeRemoveMethodRefactoring
preconditions()
privateTransform()
RBRemoveMethodTransformation
preconditions()
privateTransform()
44
Require case by case analysis
- Specify
- Validate
- Composite preconditions
- Component preconditions
Future work: a large effort
• Continue eliminating code duplication between refactorings and
transformation
• Leverage composition of refactorings where possible
• Migrate to Commander2.0
• Migrate all UI to Driver
• A lot more to…
45
New architecture for the future :)
• Many many hidden improvements
• Driver for interactive application
• Clear roles for Transformations and Refactoring:
• A refactoring is a decorator of a transformation
• Better separation of concerns
Still some work but the path is clear
46
Refactorings
RBMethod
RBNamespace
RBEntity
RBAbstractClass
RBPackage
RBMetaclass
RBClass
Changes
AST
ParseTreeRewriter
Condition
Program Model
Drivers
UI

Weitere ähnliche Inhalte

Ähnlich wie A New Architecture Reconciling Refactorings and Transformations

LINQ Inside
LINQ InsideLINQ Inside
LINQ Inside
jeffz
 
Fundamentals of java --- version 2
Fundamentals of java --- version 2Fundamentals of java --- version 2
Fundamentals of java --- version 2
Uday Sharma
 
Lecture from javaday.bg by Nayden Gochev/ Ivan Ivanov and Mitia Alexandrov
Lecture from javaday.bg by Nayden Gochev/ Ivan Ivanov and Mitia Alexandrov Lecture from javaday.bg by Nayden Gochev/ Ivan Ivanov and Mitia Alexandrov
Lecture from javaday.bg by Nayden Gochev/ Ivan Ivanov and Mitia Alexandrov
Nayden Gochev
 

Ähnlich wie A New Architecture Reconciling Refactorings and Transformations (20)

The Power Of Refactoring (PHPCon Italia)
The Power Of Refactoring (PHPCon Italia)The Power Of Refactoring (PHPCon Italia)
The Power Of Refactoring (PHPCon Italia)
 
Refactoring: Improve the design of existing code
Refactoring: Improve the design of existing codeRefactoring: Improve the design of existing code
Refactoring: Improve the design of existing code
 
Nested subqueries and subquery chaining in openCypher
Nested subqueries and subquery chaining in openCypherNested subqueries and subquery chaining in openCypher
Nested subqueries and subquery chaining in openCypher
 
31 days Refactoring
31 days Refactoring31 days Refactoring
31 days Refactoring
 
Code refactoring
Code refactoringCode refactoring
Code refactoring
 
JDK8 Functional API
JDK8 Functional APIJDK8 Functional API
JDK8 Functional API
 
LINQ Inside
LINQ InsideLINQ Inside
LINQ Inside
 
Fundamentals of java --- version 2
Fundamentals of java --- version 2Fundamentals of java --- version 2
Fundamentals of java --- version 2
 
EKON 23 Code_review_checklist
EKON 23 Code_review_checklistEKON 23 Code_review_checklist
EKON 23 Code_review_checklist
 
Java Micro-Benchmarking
Java Micro-BenchmarkingJava Micro-Benchmarking
Java Micro-Benchmarking
 
Design p atterns
Design p atternsDesign p atterns
Design p atterns
 
Modern Java Concurrency
Modern Java ConcurrencyModern Java Concurrency
Modern Java Concurrency
 
principles of object oriented class design
principles of object oriented class designprinciples of object oriented class design
principles of object oriented class design
 
Improving The Quality of Existing Software
Improving The Quality of Existing SoftwareImproving The Quality of Existing Software
Improving The Quality of Existing Software
 
CICD Pipeline configuration as a code
CICD Pipeline configuration as a codeCICD Pipeline configuration as a code
CICD Pipeline configuration as a code
 
Commonly used design patterns
Commonly used design patternsCommonly used design patterns
Commonly used design patterns
 
Object-oriented design principles
Object-oriented design principlesObject-oriented design principles
Object-oriented design principles
 
Upgrading to MongoDB 4.0 from older versions
Upgrading to MongoDB 4.0 from older versionsUpgrading to MongoDB 4.0 from older versions
Upgrading to MongoDB 4.0 from older versions
 
Lecture from javaday.bg by Nayden Gochev/ Ivan Ivanov and Mitia Alexandrov
Lecture from javaday.bg by Nayden Gochev/ Ivan Ivanov and Mitia Alexandrov Lecture from javaday.bg by Nayden Gochev/ Ivan Ivanov and Mitia Alexandrov
Lecture from javaday.bg by Nayden Gochev/ Ivan Ivanov and Mitia Alexandrov
 
Matheus Albuquerque "The best is yet to come: the Future of React"
Matheus Albuquerque "The best is yet to come: the Future of React"Matheus Albuquerque "The best is yet to come: the Future of React"
Matheus Albuquerque "The best is yet to come: the Future of React"
 

Mehr von ESUG

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programming
ESUG
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and Roadmap
ESUG
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...
ESUG
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early results
ESUG
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
ESUG
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test Generation
ESUG
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic Programming
ESUG
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
ESUG
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience Report
ESUG
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIs
ESUG
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
ESUG
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and Future
ESUG
 

Mehr von ESUG (20)

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programming
 
Technical documentation support in Pharo
Technical documentation support in PharoTechnical documentation support in Pharo
Technical documentation support in Pharo
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and Roadmap
 
Sequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoSequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in Pharo
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early results
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test Generation
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic Programming
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience Report
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIs
 
Garbage Collector Tuning
Garbage Collector TuningGarbage Collector Tuning
Garbage Collector Tuning
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and Future
 
thisContext in the Debugger
thisContext in the DebuggerthisContext in the Debugger
thisContext in the Debugger
 
Websockets for Fencing Score
Websockets for Fencing ScoreWebsockets for Fencing Score
Websockets for Fencing Score
 
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
 
Advanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocAdvanced Object- Oriented Design Mooc
Advanced Object- Oriented Design Mooc
 
BioSmalltalk
BioSmalltalkBioSmalltalk
BioSmalltalk
 

Kürzlich hochgeladen

Kürzlich hochgeladen (20)

What is a Recruitment Management Software?
What is a Recruitment Management Software?What is a Recruitment Management Software?
What is a Recruitment Management Software?
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In witbank
^Clinic ^%[+27788225528*Abortion Pills For Sale In witbank^Clinic ^%[+27788225528*Abortion Pills For Sale In witbank
^Clinic ^%[+27788225528*Abortion Pills For Sale In witbank
 
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-CloudAlluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
Alluxio Monthly Webinar | Simplify Data Access for AI in Multi-Cloud
 
Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...
Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...
Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AI
 
Secure Software Ecosystem Teqnation 2024
Secure Software Ecosystem Teqnation 2024Secure Software Ecosystem Teqnation 2024
Secure Software Ecosystem Teqnation 2024
 
How to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabberHow to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabber
 
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
 
OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024
 
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
 
Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...
Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...
Abortion Clinic In Johannesburg ](+27832195400*)[ 🏥 Safe Abortion Pills in Jo...
 
Abortion Clinic In Polokwane ](+27832195400*)[ 🏥 Safe Abortion Pills in Polok...
Abortion Clinic In Polokwane ](+27832195400*)[ 🏥 Safe Abortion Pills in Polok...Abortion Clinic In Polokwane ](+27832195400*)[ 🏥 Safe Abortion Pills in Polok...
Abortion Clinic In Polokwane ](+27832195400*)[ 🏥 Safe Abortion Pills in Polok...
 
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
 
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
 
Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14
 
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCAOpenChain Webinar: AboutCode and Beyond - End-to-End SCA
OpenChain Webinar: AboutCode and Beyond - End-to-End SCA
 
Automate your OpenSIPS config tests - OpenSIPS Summit 2024
Automate your OpenSIPS config tests - OpenSIPS Summit 2024Automate your OpenSIPS config tests - OpenSIPS Summit 2024
Automate your OpenSIPS config tests - OpenSIPS Summit 2024
 
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdfStrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
 
Abortion Clinic In Springs ](+27832195400*)[ 🏥 Safe Abortion Pills in Springs...
Abortion Clinic In Springs ](+27832195400*)[ 🏥 Safe Abortion Pills in Springs...Abortion Clinic In Springs ](+27832195400*)[ 🏥 Safe Abortion Pills in Springs...
Abortion Clinic In Springs ](+27832195400*)[ 🏥 Safe Abortion Pills in Springs...
 

A New Architecture Reconciling Refactorings and Transformations