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 en assemblant 5-10+ librairies et frameworks
Le bagage à trainer est lourd et coûteux
Un des frameworks se met en travers de votre chemin
Vous vous sentez prisonnier de ce framework
Un framework vous surprend par sa « magie »
3. Faisons simple !
• Une option sans doute ignorée par biais de :
1. temps
2. sophistication
3. analyse
4.
5. Le point de départ
• Application à vocation académique, développée avec :
• Spring et Spring MVC
• Hibernate, JPA
• Maven
• Velocity et SiteMesh
• 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.
12. Buildr
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
13. new
AttachmentStorage attachments = new FileSystemPhotoStore("/photos");
Cart cart = new SessionScope(request.session()).cart();
Connection connection = new ConnectionReference(request).get();
Transactor transactor = new JDBCTransactor(connection);
ProductCatalog catalog = new ProductsDatabase(connection);
ItemInventory inventory = new ItemsDatabase(connection);
OrderBook orders = new OrdersDatabase(connection);
ProcurementRequestHandler procurement = new PurchasingAgent(catalog, inventory,
transactor);
OrderNumberSequence orderNumbers = new OrderNumberDatabaseSequence(connection);
Cashier cashier = new Cashier(orderNumbers, orders, inventory, cart, transactor);
15. 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());
}
}
16. Data Mapping
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);
}
17. Transactions
public class Cashier implements SalesAssistant {
[...]
public OrderNumber placeOrder(PaymentMethod paymentMethod) throws Exception {
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);
}
18. Toutefois
• Pas très « entreprise »
• Pas à la portée de toutes les équipes
• Pas à toutes les sauces
• Pas sans risque
19. 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
20. 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
• Web :
https://github.com/testinfected/molecule