SlideShare a Scribd company logo
1 of 22
Download to read offline
Retour à la simplicité
Vincent Tencé
@testinfected
http://vtence.com
http://github.com/testinfected
Un sentiment de déja-vu ?
Vous démarrez un projet avec une dizaine de librairies et frameworks
Le bagage à trainer est lourd et vous coute cher
Un des frameworks se met en travers de votre chemin
Vous vous sentez prisonnier d’un des frameworks
Un framework vous surprend par sa « magie »
Le point de départ
• Spring et Spring MVC
• Velocity et SiteMesh
• Hibernate, JPA
• Hibernate Validator
• Maven
• 53 jars externes !
Le défi
• Uniquement des outils simples
• DIYS (Do It Yourself Simply)
• Assemblage, déploiement et configuration faciles
• XML
• Annotations
• Framework (Web, ORM, DI)
Build	
define 'petstore', [..] do
define 'domain' do
compile.with
test.with HAMCREST
package :jar
end
define 'persistence' do
compile.with project(:domain)
test.with HAMCREST, :flyway, :mysql, NO_LOG, [...]
package :jar
end
define 'webapp' domain
compile.with :simpleframework, :jmustache, [...]
test.with HAMCREST, :antlr_runtime, :cssselectors, :hamcrest_dom, [...]
test.with transitive(artifacts(:nekohtml, :htmlunit, :jmock_legacy))
package :jar
end
Injection de dépendances

AttachmentStorage attachments = new FileSystemPhotoStore("/photos");
Connection connection = new ConnectionReference(request).get();
Transactor transactor = new JDBCTransactor(connection);
ProductCatalog products = new ProductsDatabase(connection);
ItemInventory items = new ItemsDatabase(connection);
OrderBook orders = new OrdersDatabase(connection);
ProcurementRequestHandler procurement =
new PurchasingAgent(products, items, transactor)
OrderNumberSequence orderNumbers = new OrderNumberDatabaseSequence(connection);
Cashier cashier = new Cashier(orderNumbers, orders, transactor);
Messages messages =
new BundledMessages(ResourceBundle.getBundle("ValidationMessages"))
Routing

Router router = Router.draw(new DynamicRoutes() {{
get("/products").to(new ListProducts(products, attachments, pages.products()));
post("/products").to(new CreateProduct(procurement));
get("/products/:product/items").to(new ListItems(items, pages.items()));
post("/products/:product/items").to(new CreateItem(procurement));
get("/cart").to(new ShowCart(cashier, pages.cart()));
post("/cart").to(new CreateCartItem(cashier));
get("/orders/new").to(new Checkout(cashier, pages.checkout()));
get("/orders/:number").to(new ShowOrder(orders, pages.order()));
post("/orders").to(new PlaceOrder(cashier));
delete("/logout").to(new Logout());
map("/").to(new StaticPage(pages.home()));
}});
MVC

public class ShowOrder implements Application {
private final OrderBook orderBook;
private final Page orderPage;
public ShowOrder(OrderBook orderBook, Page orderPage) {
this.orderBook = orderBook;
this.orderPage = orderPage;
}
public void handle(Request request, Response response) throws Exception {
String number = request.parameter("number");
Order order = orderBook.find(new OrderNumber(number));
orderPage.render(response, context().with("order", order).asMap());
}
}
Accès aux données
public class OrdersDatabase implements OrderBook {
private final Connection connection;
[...]
public OrdersDatabase(Connection connection) {
this.connection = connection;
}
private List<LineItem> findLineItemsOf(Order order) {
return Select.from(lineItems).
where("order_id = ?", idOf(order).get()).
orderBy("order_line").
list(connection);
}
private Order findOrder(OrderNumber orderNumber) {
return Select.from(orders, "_order").
leftJoin(payments, "payment", "_order.payment_id = payment.id").
where("_order.number = ?", orderNumber).
first(connection);
}
Transactions
public class Cashier implements SalesAssistant {
[...]
public OrderNumber placeOrder(PaymentMethod paymentMethod) throws Exception {
Ensure.valid(paymentMethod);
QueryUnitOfWork<OrderNumber> order = new QueryUnitOfWork<OrderNumber>() {
public OrderNumber query() throws Exception {
OrderNumber nextNumber = orderNumberSequence.nextOrderNumber();
final Order order = new Order(nextNumber);
order.addItemsFrom(cart);
order.pay(paymentMethod);
orderBook.record(order);
cart.clear();
return nextNumber;
}
};
return transactor.performQuery(order);
}
Contraintes de validité
public class CreditCardDetails extends PaymentMethod implements Serializable {
private
private
private
private

final
final
final
final

CreditCardType cardType;
Constraint<String> cardNumber;
NotNull<String> cardExpiryDate;
Valid<Address> billingAddress;

public CreditCardDetails(CreditCardType type,
String number,
String expiryDate,
Address billingAddress) {
this.cardType = type;
this.cardNumber = Validates.both(Validates.notEmpty(number),
Validates.correctnessOf(type, number));
this.cardExpiryDate = Validates.notNull(expiryDate);
this.billingAddress = Validates.validityOf(billingAddress);
}
Validation

public class Validator {
public <T> Set<ConstraintViolation<?>> validate(T target) {
Valid<T> valid = Validates.validityOf(target);
valid.disableRootViolation();
ViolationsReport report = new ViolationsReport();
valid.check(Path.root(target), report);
return report.violations();
}
[...]
}
Formulaires
public class PaymentForm extends Form {
public static PaymentForm parse(Request request) {
return new PaymentForm(new CreditCardDetails(
valueOf(request.parameter("card-type")),
request.parameter("card-number"),
request.parameter("expiry-date"),
new Address(request.parameter("first-name"),
request.parameter("last-name"),
request.parameter("email"))));
}
private final Valid<CreditCardDetails> paymentDetails;
public PaymentForm(CreditCardDetails paymentDetails) {
this.paymentDetails = Validates.validityOf(paymentDetails);
}
public CreditCardType cardType() { return paymentDetails().getCardType(); }
public CreditCardDetails paymentDetails() { return paymentDetails.get(); }
}
Toutefois
• Pas très « entreprise »
• Pas à la portée de toutes les équipes ?
• Pas à toutes les sauces
• Pas sans risque ?
Leçons apprises
• Éviter la tentation des frameworks
• Utiliser des outils simples, légers et spécialisés
• Construire mes propres outils
• S’inspirer des meilleures idées; réécrire le code simplement
• Spécialiser plutôt que de généraliser
Références
• Nouvelle version :
https://github.com/testinfected/simple-petstore
• Ancienne version :
https://github.com/testinfected/petstore
• Data Mapping :
https://github.com/testinfected/tape

More Related Content

What's hot

Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Masahiro Nagano
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Fabien Potencier
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
The state of your own hypertext preprocessor
The state of your own hypertext preprocessorThe state of your own hypertext preprocessor
The state of your own hypertext preprocessorAlessandro Nadalin
 
Practical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich ClientsPractical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich ClientsRichard Bair
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
History of jQuery
History of jQueryHistory of jQuery
History of jQueryjeresig
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionAdam Trachtenberg
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Ismael Celis
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012Michael Peacock
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jqueryDanilo Sousa
 
The love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinThe love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinLorenz Cuno Klopfenstein
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 

What's hot (20)

Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)
 
Whats new in iOS5
Whats new in iOS5Whats new in iOS5
Whats new in iOS5
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
The state of your own hypertext preprocessor
The state of your own hypertext preprocessorThe state of your own hypertext preprocessor
The state of your own hypertext preprocessor
 
Practical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich ClientsPractical Experience Building JavaFX Rich Clients
Practical Experience Building JavaFX Rich Clients
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
History of jQuery
History of jQueryHistory of jQuery
History of jQuery
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010
 
PhoneGap: Local Storage
PhoneGap: Local StoragePhoneGap: Local Storage
PhoneGap: Local Storage
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jquery
 
The love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with XamarinThe love child of Android and .NET: App development with Xamarin
The love child of Android and .NET: App development with Xamarin
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
iOS5 NewStuff
iOS5 NewStuffiOS5 NewStuff
iOS5 NewStuff
 

Viewers also liked

이끌림을 넘어 이야기하기
이끌림을 넘어 이야기하기이끌림을 넘어 이야기하기
이끌림을 넘어 이야기하기DDAM
 
Slide Show Exploring The Numbers By Number Senses And Numeration
Slide Show Exploring The Numbers By Number Senses And NumerationSlide Show Exploring The Numbers By Number Senses And Numeration
Slide Show Exploring The Numbers By Number Senses And NumerationHoneylay P. Royo
 
Social Media For Business Development In Real Estate
Social Media For Business Development In Real EstateSocial Media For Business Development In Real Estate
Social Media For Business Development In Real Estatejohnesplana
 
Slide Show Exploring The Numbers By Number Senses And Numeration
Slide Show Exploring The Numbers By Number Senses And NumerationSlide Show Exploring The Numbers By Number Senses And Numeration
Slide Show Exploring The Numbers By Number Senses And NumerationHoneylay P. Royo
 
My Personal Consumption Plan
My Personal Consumption PlanMy Personal Consumption Plan
My Personal Consumption Planguestc57745f
 
Using semantic to enhance content
Using semantic to enhance contentUsing semantic to enhance content
Using semantic to enhance contentguestf0561e3
 
Effective Business Strategies in Corporate Travel Market
Effective Business Strategies in Corporate Travel MarketEffective Business Strategies in Corporate Travel Market
Effective Business Strategies in Corporate Travel Marketerya1
 

Viewers also liked (14)

이끌림을 넘어 이야기하기
이끌림을 넘어 이야기하기이끌림을 넘어 이야기하기
이끌림을 넘어 이야기하기
 
final draft In Workbook
final draft In Workbookfinal draft In Workbook
final draft In Workbook
 
Impresora Termica
Impresora TermicaImpresora Termica
Impresora Termica
 
Presentacion.Amor
Presentacion.AmorPresentacion.Amor
Presentacion.Amor
 
Slide Show Exploring The Numbers By Number Senses And Numeration
Slide Show Exploring The Numbers By Number Senses And NumerationSlide Show Exploring The Numbers By Number Senses And Numeration
Slide Show Exploring The Numbers By Number Senses And Numeration
 
Social Media For Business Development In Real Estate
Social Media For Business Development In Real EstateSocial Media For Business Development In Real Estate
Social Media For Business Development In Real Estate
 
Slide Show Exploring The Numbers By Number Senses And Numeration
Slide Show Exploring The Numbers By Number Senses And NumerationSlide Show Exploring The Numbers By Number Senses And Numeration
Slide Show Exploring The Numbers By Number Senses And Numeration
 
My Personal Consumption Plan
My Personal Consumption PlanMy Personal Consumption Plan
My Personal Consumption Plan
 
final draft In Workbook
final draft In Workbookfinal draft In Workbook
final draft In Workbook
 
Using semantic to enhance content
Using semantic to enhance contentUsing semantic to enhance content
Using semantic to enhance content
 
ConnectED
ConnectEDConnectED
ConnectED
 
Instantagent
InstantagentInstantagent
Instantagent
 
Resume Of Akhilesh Mritunjai
Resume Of Akhilesh MritunjaiResume Of Akhilesh Mritunjai
Resume Of Akhilesh Mritunjai
 
Effective Business Strategies in Corporate Travel Market
Effective Business Strategies in Corporate Travel MarketEffective Business Strategies in Corporate Travel Market
Effective Business Strategies in Corporate Travel Market
 

Similar to Retour à la simplicité

Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastJorge Lopez-Malla
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldChristian Melchior
 
Rich Internet Applications con JavaFX e NetBeans
Rich Internet Applications  con JavaFX e NetBeans Rich Internet Applications  con JavaFX e NetBeans
Rich Internet Applications con JavaFX e NetBeans Fabrizio Giudici
 
Local storage in Web apps
Local storage in Web appsLocal storage in Web apps
Local storage in Web appsIvano Malavolta
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?Trisha Gee
 
Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#Vagif Abilov
 
Kief Morris - Infrastructure is terrible
Kief Morris - Infrastructure is terribleKief Morris - Infrastructure is terrible
Kief Morris - Infrastructure is terribleThoughtworks
 
HashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin InfrastructureHashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin InfrastructureNicolas Corrarello
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web developmentJohannes Brodwall
 
10.Local Database & LINQ
10.Local Database & LINQ10.Local Database & LINQ
10.Local Database & LINQNguyen Tuan
 
Scaling php applications with redis
Scaling php applications with redisScaling php applications with redis
Scaling php applications with redisjimbojsb
 
Vert.x - Reactive & Distributed [Devoxx version]
Vert.x - Reactive & Distributed [Devoxx version]Vert.x - Reactive & Distributed [Devoxx version]
Vert.x - Reactive & Distributed [Devoxx version]Orkhan Gasimov
 
.NET Database Toolkit
.NET Database Toolkit.NET Database Toolkit
.NET Database Toolkitwlscaudill
 
Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology
Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology
Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology Ayes Chinmay
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionChristian Panadero
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Sven Efftinge
 
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...Fons Sonnemans
 

Similar to Retour à la simplicité (20)

Linq
LinqLinq
Linq
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected World
 
Rich Internet Applications con JavaFX e NetBeans
Rich Internet Applications  con JavaFX e NetBeans Rich Internet Applications  con JavaFX e NetBeans
Rich Internet Applications con JavaFX e NetBeans
 
Local storage in Web apps
Local storage in Web appsLocal storage in Web apps
Local storage in Web apps
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
 
Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#Typed? Dynamic? Both! Cross-platform DSLs in C#
Typed? Dynamic? Both! Cross-platform DSLs in C#
 
Kief Morris - Infrastructure is terrible
Kief Morris - Infrastructure is terribleKief Morris - Infrastructure is terrible
Kief Morris - Infrastructure is terrible
 
HashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin InfrastructureHashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin Infrastructure
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web development
 
10.Local Database & LINQ
10.Local Database & LINQ10.Local Database & LINQ
10.Local Database & LINQ
 
Scaling php applications with redis
Scaling php applications with redisScaling php applications with redis
Scaling php applications with redis
 
Vert.x - Reactive & Distributed [Devoxx version]
Vert.x - Reactive & Distributed [Devoxx version]Vert.x - Reactive & Distributed [Devoxx version]
Vert.x - Reactive & Distributed [Devoxx version]
 
.NET Database Toolkit
.NET Database Toolkit.NET Database Toolkit
.NET Database Toolkit
 
Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology
Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology
Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 
Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]Getting the most out of Java [Nordic Coding-2010]
Getting the most out of Java [Nordic Coding-2010]
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
 

Recently uploaded

GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 

Recently uploaded (20)

GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 

Retour à la simplicité

  • 1. Retour à la simplicité Vincent Tencé @testinfected http://vtence.com http://github.com/testinfected
  • 2. Un sentiment de déja-vu ? Vous démarrez un projet avec une dizaine de librairies et frameworks Le bagage à trainer est lourd et vous coute cher Un des frameworks se met en travers de votre chemin Vous vous sentez prisonnier d’un des frameworks Un framework vous surprend par sa « magie »
  • 3.
  • 4.
  • 5. Le point de départ • Spring et Spring MVC • Velocity et SiteMesh • Hibernate, JPA • Hibernate Validator • Maven • 53 jars externes !
  • 6.
  • 7. Le défi • Uniquement des outils simples • DIYS (Do It Yourself Simply) • Assemblage, déploiement et configuration faciles • XML • Annotations • Framework (Web, ORM, DI)
  • 8.
  • 9.
  • 10.
  • 11. Build define 'petstore', [..] do define 'domain' do compile.with test.with HAMCREST package :jar end define 'persistence' do compile.with project(:domain) test.with HAMCREST, :flyway, :mysql, NO_LOG, [...] package :jar end define 'webapp' domain compile.with :simpleframework, :jmustache, [...] test.with HAMCREST, :antlr_runtime, :cssselectors, :hamcrest_dom, [...] test.with transitive(artifacts(:nekohtml, :htmlunit, :jmock_legacy)) package :jar end
  • 12. Injection de dépendances AttachmentStorage attachments = new FileSystemPhotoStore("/photos"); Connection connection = new ConnectionReference(request).get(); Transactor transactor = new JDBCTransactor(connection); ProductCatalog products = new ProductsDatabase(connection); ItemInventory items = new ItemsDatabase(connection); OrderBook orders = new OrdersDatabase(connection); ProcurementRequestHandler procurement = new PurchasingAgent(products, items, transactor) OrderNumberSequence orderNumbers = new OrderNumberDatabaseSequence(connection); Cashier cashier = new Cashier(orderNumbers, orders, transactor); Messages messages = new BundledMessages(ResourceBundle.getBundle("ValidationMessages"))
  • 13. Routing Router router = Router.draw(new DynamicRoutes() {{ get("/products").to(new ListProducts(products, attachments, pages.products())); post("/products").to(new CreateProduct(procurement)); get("/products/:product/items").to(new ListItems(items, pages.items())); post("/products/:product/items").to(new CreateItem(procurement)); get("/cart").to(new ShowCart(cashier, pages.cart())); post("/cart").to(new CreateCartItem(cashier)); get("/orders/new").to(new Checkout(cashier, pages.checkout())); get("/orders/:number").to(new ShowOrder(orders, pages.order())); post("/orders").to(new PlaceOrder(cashier)); delete("/logout").to(new Logout()); map("/").to(new StaticPage(pages.home())); }});
  • 14. MVC public class ShowOrder implements Application { private final OrderBook orderBook; private final Page orderPage; public ShowOrder(OrderBook orderBook, Page orderPage) { this.orderBook = orderBook; this.orderPage = orderPage; } public void handle(Request request, Response response) throws Exception { String number = request.parameter("number"); Order order = orderBook.find(new OrderNumber(number)); orderPage.render(response, context().with("order", order).asMap()); } }
  • 15. Accès aux données public class OrdersDatabase implements OrderBook { private final Connection connection; [...] public OrdersDatabase(Connection connection) { this.connection = connection; } private List<LineItem> findLineItemsOf(Order order) { return Select.from(lineItems). where("order_id = ?", idOf(order).get()). orderBy("order_line"). list(connection); } private Order findOrder(OrderNumber orderNumber) { return Select.from(orders, "_order"). leftJoin(payments, "payment", "_order.payment_id = payment.id"). where("_order.number = ?", orderNumber). first(connection); }
  • 16. Transactions public class Cashier implements SalesAssistant { [...] public OrderNumber placeOrder(PaymentMethod paymentMethod) throws Exception { Ensure.valid(paymentMethod); QueryUnitOfWork<OrderNumber> order = new QueryUnitOfWork<OrderNumber>() { public OrderNumber query() throws Exception { OrderNumber nextNumber = orderNumberSequence.nextOrderNumber(); final Order order = new Order(nextNumber); order.addItemsFrom(cart); order.pay(paymentMethod); orderBook.record(order); cart.clear(); return nextNumber; } }; return transactor.performQuery(order); }
  • 17. Contraintes de validité public class CreditCardDetails extends PaymentMethod implements Serializable { private private private private final final final final CreditCardType cardType; Constraint<String> cardNumber; NotNull<String> cardExpiryDate; Valid<Address> billingAddress; public CreditCardDetails(CreditCardType type, String number, String expiryDate, Address billingAddress) { this.cardType = type; this.cardNumber = Validates.both(Validates.notEmpty(number), Validates.correctnessOf(type, number)); this.cardExpiryDate = Validates.notNull(expiryDate); this.billingAddress = Validates.validityOf(billingAddress); }
  • 18. Validation public class Validator { public <T> Set<ConstraintViolation<?>> validate(T target) { Valid<T> valid = Validates.validityOf(target); valid.disableRootViolation(); ViolationsReport report = new ViolationsReport(); valid.check(Path.root(target), report); return report.violations(); } [...] }
  • 19. Formulaires public class PaymentForm extends Form { public static PaymentForm parse(Request request) { return new PaymentForm(new CreditCardDetails( valueOf(request.parameter("card-type")), request.parameter("card-number"), request.parameter("expiry-date"), new Address(request.parameter("first-name"), request.parameter("last-name"), request.parameter("email")))); } private final Valid<CreditCardDetails> paymentDetails; public PaymentForm(CreditCardDetails paymentDetails) { this.paymentDetails = Validates.validityOf(paymentDetails); } public CreditCardType cardType() { return paymentDetails().getCardType(); } public CreditCardDetails paymentDetails() { return paymentDetails.get(); } }
  • 20. Toutefois • Pas très « entreprise » • Pas à la portée de toutes les équipes ? • Pas à toutes les sauces • Pas sans risque ?
  • 21. Leçons apprises • Éviter la tentation des frameworks • Utiliser des outils simples, légers et spécialisés • Construire mes propres outils • S’inspirer des meilleures idées; réécrire le code simplement • Spécialiser plutôt que de généraliser
  • 22. Références • Nouvelle version : https://github.com/testinfected/simple-petstore • Ancienne version : https://github.com/testinfected/petstore • Data Mapping : https://github.com/testinfected/tape