Pillole di...

Frameworkless

Mi presento

Christian Nastasi

Lavoro in Facile.it

Ricopro il ruolo di Delivery Manager

Sviluppo cose dal 2000

Suono cose, ne ascolto altre, mi piace la cultura orientale ed il buon vino.

Disclaimer

Questo talk è basato su studi ed esperienze personali raccolte negli anni.

Per questioni di tempo, alcune delle argomentazioni potrebbero essere poco approfondite

Potrebbe contenere tracce di meme

Da qui in poi, sarà scritto in inglese (almost)

Introduction

Introduction

Nowadays, frameworks becomes a necessary "evil".

There's who loves them and who tollerate them.

They speeds up our developing process.

They offers a lot of ready to use functionalities

There often a big and supporting community around them.

They are open-source, so I can personalize them as I like

They give us a lot of power

Yes, that's true, But

They brings also

Architectural choices guided by the framework itself

A lot of pain whenever we want to upgrade the version

The cost of maintaining the entire framework, in case we personalize it

Documentation rarely go deep, it show you the easiest way to use it, not the best way

Programmers hate going out of their confort zone, so they tend to use the screwdriver as a fork

Symfony releases

Laravel RELEASES

Question time

How old is your current framework version?

 

How old is your project?

 

How often do you upgraded the framework?

 

How much it cost to upgrade?

Most of you

The truth is

Never enough time for refactoring 

Remove tightly coupled dependencies cost a lot

Upgrading a framework often cost too much

But every day we think about...

Often we choose to keep the current version

No new and shiny features

Security issue

Licenses compliancy issues

To use or not to use (a framework)

That is the question

You can use it but...

Just invert your dependencies

Holliwood Principle

Don't call us, we'll call you

Cool, but how?

Design by contracts

Design by contracts

Created by Bertrand Meyer in the 1980s

Is an aproach to software design that focuses on specifying contracts that define the interactions among components

Design by contracts

Client

Server

Precondition

Pre-condition: This is what the server expects from the client

Post condition

Post-condition: This is what the server promise to do for the client + what happens after 

Invariant: Those conditions should be always true inside the server, no matter who the client is

Invariant

Real life Example

Pre-condition:
- You should have enough money

- You should have choosed which pizza take

Post-condition:
- You'll have your pizza

- Some ingredients are consumed

Invariant:

- The pizza will be served hot

- The pizza will be prepared "just in time"

Client: You

Server: Your favourite "pizza dealer"*

* Everybody knows, pizza is a drug

Code EXAMPLE

interface Library {
    /**
     * Pre-conditions: 
     * - The book should be in the index
     * - There is at least a copy in the library
     * - The member exists and its membership is not expired
     *
     * Post-conditions:
     * - The count of the copy decrease by 1
     * - The count of the borrowed copy increase by 1
     *
     * Invariant:
     * - The borrowed books + the books in the library = const
     *
     * @throws BookNotInTheIndex
     * @throws MemberNotRegistered
     * @throws MembershipExpired
     * @throws NoMoreCopyLeft
     */
    public function borrowABook(Book $book, Member $member): BorrowedBook;
}

Design by contracts

How to enforce the contracts in PHP?

Libriaries

Unit testing

Language (es. Using class type hinting + value objects)

Comments + annotations

Dependency Inversion Principle

Dependency Inversion Principle

High-level modules should not depend on low-level modules.

Both should depend on abstractions.



Abstractions should not depend on details.

Details should depend on abstractions.

 

Robert C. Martin

Dependency Inversion Principle

Your code

File Logger

Tightly coupled

Dependency Inversion Principle

Your code

Logger

File Logger

Remote Logger

Null Logger

Tightly coupled

Concrete class

Interface

PSR

PSR

The PHP Framework Interoperability Group, since the 2009, is trying to create standards contracts in order to maximize the reusability of several components.

PSR

Layered Architecture

Different name, same concepts

Hexagonal


 

Clean (by Uncle Bob)



Onion


 

...

Different name, same concepts

Main GOALS

Independent of Frameworks
The architecture does not depend on libraries.

Independent of any external agency
In fact your business rules simply don’t know anything at all about the outside world.

Independent of Database
You can swap out MySQL or PostgreSQL, for Mongo, Elastic search, or something else. Your business rules are not bound to the database.

Independent of UI
The UI can change easily, without changing the rest of the system.

Testable
The business rules can be tested without the UI, Database, Web Server, or any other external element.

Dependency Rule

Source code dependencies can only point inwards.
Nothing in an inner circle can know anything at all about something in an outer circle

Domain Driven Design

Domain Driven Design

Is the concept that the structure and language of software code (class names, class methods, class variables) should match the business domain

The technical experts communicate trough a shared language, called
ubiquitous language.

BoundeD Context

Building blocks

Value Object

Self validating

Immutable

Describes values / concepts of your domain

Protect you from the past' yourself

Comparable

Money

Email Address

Entities

Composite by value objects

Identified by an id

With a life cycle

Quote

Customer

Can be mutable

Aggregates

Describes high level concepts of your domain

Composite by one or more entities

Formed by tightly coupled domain concepts

Manage pre/post/invariant conditions internally

Post

Reactions

Content

Comments

Author

Repositories

Treat persistence like a collection of entities / aggregates

It's a persistence abstraction layer

Isolate the source of the persistence from the domain

Use Case / services

Use cases are bounded to a domain context

Where the business logic resides

Services are more generic and could be used in different domain contexts

Follows the single responsability principle

PublishPost

FileUploader

Use Case

Service

Factories

Helps to apply the Inversion of Control principle

Centralize the creation of entities / aggregates

Domain EVENTS

Represent something important that occured in the domain

Immutables

Should named with verbs in the past

Semi pratical example

Normally we have this

But also this

First optimization:

Pull out the business logic

But what if...?

Second optimization:

Pull out the query

Another duplication:

Entity instatiation

Third optimization

Factory

Dependency inversion 

#1

Dependency inversion

#2

But what is A?

A is part of our domain

Can be described with Domain Objects like:

Value Objects, Entities, Aggregates, Enums

Why not primitives?

Let's think

What's an age?  a number

What's a phone number?  a string

NO

NO

Integer

> 18

< 99

Only italian numbers

Prefix + 8 o 9 digits

Start with +

Data safety

JSON
(string)

Primitives
(int, float, bool, string)

Domain Objects
(entities, value objects, aggregates)

Application + Domain
(Safe)

Framework
(Not safe)

Infrastracture
(Unknown)

Decoding  | Serialization

Wrapping up

Http Request

Controller

CLI Command

Command Bus

Command

Handler

Infrastructure

Framework

Application

DB

Repository
Implementation

Adapter
Implementation

Use Case

Repository
Interface

Adapter
Interface

Domain

CoNCLUSIONS

Cons

Frameworkless it's not easy to master

Require a lot of discipline

It doesn't fit for every scenario (p.e. Prototypes)

High initial cost

Pros

Keep your technical dept low

Speedup your development process in the mid term

Your domain data are solid and coherent

Focused on business

Easy to maintain, easy to evolve

Frameworkless Movement

https://www.frameworklessmovement.org/

Frameworkless Movement

https://www.frameworklessmovement.org/

Q & A

We Are Hiring

MAIL: 
christian.nastasi@gmail.com

LINKEDIN: https://www.linkedin.com/in/cnastasi/

https://github.com/cnastasi/ddd

Let me know if interested

SLACK:

@cnastasi

https://github.com/cnastasi/serializer

https://github.com/cnastasi/ddd

https://github.com/cnastasi/json-api

Rate my repos

Frameworkless

By Nastasi Christian

Frameworkless

  • 162