AGENCE DE DÉVELOPPEMENT WEB À PARIS

Lançons votre application web en un temps record à Paris.

Situé en plein coeur de Paris, dans le 9e arrondissement, Yield Studio vous accompagne afin de développer des applications web dont vos utilisateurs se souviendront.

Garantie

Améliorons votre expérience client ou collaborateur

Notre objectif chez Yield Studio Paris n’est pas simplement de développer un site web ou une application en ligne. Nous visons avant tout à créer des expériences digitales qui favorisent l’adoption des utilisateurs et atteignent vos objectifs business (augmentation de la productivité, amélioration de la satisfaction client, augmentation des ventes, etc.).

Installée au cœur de Paris, notre agence privilégie une approche centrée sur l’utilisateur pour concevoir des plateformes web qui apportent une valeur réelle à vos utilisateurs parisiens.

Contrairement à d’autres agences qui se focalisent uniquement sur la technique, nous intégrons une compréhension fine du marché parisien pour vous proposer des solutions web sur-mesure, parfaitement adaptées à vos besoins.Discutons de votre projet web à Paris dès maintenant

Discutons de votre projet à Paris dès maintenant

Yield Studio : votre agence de développement web à Paris 09

24 rue de Mogador, 75009 Paris
Voir l’itinéraire

Yield Studio, votre agence spécialisée dans le développement web, est implantée au cœur de Paris depuis 2019.

Après avoir débuté dans le 16ᵉ arrondissement, puis à Neuilly, nous avons récemment déménagé dans le quartier dynamique de Trinité, offrant ainsi à nos clients un cadre idéal pour travailler ensemble.

Nous accompagnons les entreprises parisiennes et franciliennes dans la création de sites web innovants, adaptés à leurs besoins spécifiques. Que vous soyez basé à Paris, Neuilly, Boulogne ou ailleurs en Île-de-France, nous sommes à vos côtés pour concrétiser vos projets numériques. Faites confiance à Yield Studio, votre agence de développement web dédiée à la réussite de vos projets digitaux.

Confiance

Bénéficiez de notre recul pour vous challenger sur Paris

Construire une application web performante est un levier stratégique essentiel pour accélérer votre transformation digitale à Paris. Notre objectif ? Vous permettre de gagner en productivité, d'améliorer l'expérience utilisateur, ou encore de moderniser vos processus métiers pour booster votre croissance dans un environnement compétitif comme celui de la capitale.

Avec plus de 6 ans d’expérience et 110 projets web développés, Yield Studio Paris a acquis une solide expérience pour anticiper les défis techniques, concevoir des architectures évolutives et garantir la scalabilité de vos projets sur le marché parisien.

Plus de 110 projets

web développés ou refondus par nos équipes pour des clients de toutes tailles à Paris.

Déjà 6 ans

que Yield Studio est un partenaire parisien reconnu dans le développement d'applications web sur mesure.

Plus d'1 million

d'utilisateurs touchés chaque mois par les applications web que nous avons développées pour nos clients d'ile de france.

Dizaines de millions

de requêtes API sont faites chaque jour sur les applications de nos clients que nous maintenons

Pourquoi Yield Studio ?

Code de qualité

Nous écrivons un code de qualité dès le départ pour aller plus vite ensuite

Focus utilisateur

Nous identifions les fonctionnalités différenciantes pour les utilisateurs finaux

Time To Market

Nous mettons très rapidement en production les fonctionnalités grâce à notre Lean Lab’ ®

Compétence n°1

Création d'application web à Paris

Lancer une application web performante va bien au-delà du simple développement d’interface. Chez Yield Studio Paris, nous vous accompagnons dès la conception pour créer des applications web sur-mesure, qu’il s’agisse d’applications métiers pour automatiser vos processus internes et améliorer votre productivité, d’applications SaaS évolutives pensées pour répondre aux besoins spécifiques de vos utilisateurs parisiens, ou encore de sites web complexes offrant une expérience utilisateur optimisée grâce à une architecture robuste et une conception sur mesure.

Implantés au cœur de Paris, nous comprenons les enjeux particuliers des entreprises locales et proposons des solutions adaptées à votre réalité.

Découvrir
Compétence n°2

Refonte d’applications web

Une application vieillissante ou un site web obsolète peut freiner votre croissance. Nous vous aidons à moderniser vos applications en repensant leur architecture technique, en améliorant leurs performances, leur design et leur scalabilité. Notre approche se concentre sur la mise à jour de vos outils pour offrir une expérience utilisateur optimale tout en garantissant une maintenance simplifiée et une capacité d’évolution sur le long terme.

Découvrir
Compétence n°3

Tierce Maintenance Applicative (TMA)

Un code mal structuré entraîne des bugs, des lenteurs et des dettes techniques qui peuvent nuire à l’efficacité de votre application. Nos experts réalisent des audits complets pour évaluer l’état de votre application, identifier les goulots d’étranglement, et proposer des améliorations concrètes.

Notre objectif : Vous garantir un code fiable, maintenable et prêt à évoluer sans friction. Grâce à une maintenance rigoureuse et proactive, nous veillons à ce que votre application reste performante et sécurisée au fil du temps.

Découvrir
Cas Clients

Découvrez nos réalisations clients

BTP Consultants

DSI externalisée en charge de la création d’un socle applicatif et d'une application métier pour un grand groupe immobilier
Voir le cas client
Fonctionnalités

Focus sur quelques fonctionnalités phares développées pour nos clients

Nous créons des fonctionnalités sur-mesure qui répondent aux besoins spécifiques de chaque projet web, qu’il s’agisse de plateformes SaaS, de logiciels métiers ou de sites complexes.

Portails client personnalisés : espaces sécurisés offrant des dashboards interactifs, accès aux données en temps réel, et outils de collaboration dédiés.
Systèmes de reporting avancés : génération de rapports dynamiques, visualisations de données complexes et exports personnalisés.
Automatisation de processus métiers : développement de workflows sur-mesure pour simplifier et optimiser vos processus internes.
Intégrations d’API & webhooks : connexion fluide avec vos ERP, CRM, solutions de paiement ou services tiers pour une interopérabilité totale.
Sécurité & Performance : systèmes de gestion des permissions, cryptage des données, monitoring des performances et maintenance proactive.
Franck JOUSSE
Directeur des Systèmes d'Information
Ce qui nous a intéressé chez Yield Studo c'est la vision qu'ils ont des transformations de l'entreprise et le mix entre la rigueur et la souplesse. Historiquement chez BTP Consultants la gestion de projet en mode agile a été compliquée, ils ont eu cette faculté et nous ont prouvé qu'eux y parvenaient avec leur approche. La collaboration au quotidien se passe super bien, les développeurs voient nos utilisateurs finaux. On a beaucoup d'intéractions au quotidien, on est dans une relation super saine et de confiance ! Les collaborateurs sont bienveillants et purement smarts dans leurs solutions, discussions, ... Et c'est rare sur le marché. Je recommande Yield Studio pour cette capacité à imaginer les produits, à être très concentré sur l'utilisateur final, à chercher le gain business ! Ils nous font vraiment progresser au quotidien.
Fonctionnement

Une approche en 5 phases

ETAPE 1

Compréhension utilisateur

Identification des problématiques de vos utilisateurs, de vos enjeux clés à travers l'écoute active et l'analyse de marché pour cadrer le projet.

1 à 3 semaines
ETAPE 2

Conception & Prototypage

Création de maquettes et prototypes interactifs, testés et améliorés grâce aux retours des utilisateurs pour garantir une solution répondant à leurs attentes.

2 à 4 semaines
ETAPE 3

Développement agile

Codage de votre application web en sprints d’une semaine, permettant des ajustements flexibles basés sur des tests en conditions réelles. A la fin de chaque sprint une revue est organisée ensemble.

6 à 12 semaines
ETAPE 4

Tests & améliorations

Assurer la qualité et la performance de l'application par des tests rigoureux en conditions réelles, en prenant en compte des retours pour des ajustements.

1 à 3 semaines
ETAPE 5

Itérations

Mettre votre produit en ligne et effectuer des itérations basées sur les retours, les datas et les évolutions du marché. Retour à l’étape 1 pour focus une autre problématique !

Nos experts en développement web situés à Paris

Alexandre
Développeur sénior
Timothée
Développeur sénior
Alexandre
Développeur sénior
Arthur
Développeur sénior
Adrien
Développeur sénior
Alexis
Développeur sénior
Jonathan
Lead Développeur
Louis
Développeur sénior
Thibaut
Lead Développeur
Sergio
Développeur sénior
Mathieu
Développeur sénior
Gabriel
Développeur sénior
James
Chief Technical Officer & Co-founder
Cyrille
Chief Product Officer & Co-Founder
David
Développeur sénior
Vidéo

Découvrez le mot de notre co-fondateur

Yield Studio aide les entreprises à devenir plus productives et identifier des leviers de croissance. Agacés de travailler sur des projets sans impact réel, c’est en 2019 que James et Cyrille créent Yield Studio.  Notre objectif est d’utiliser la tech pour créer des innovations qui apportent de la valeur à la fois à l’utilisateur final et à la fois au business

+150

Produits digitaux construits pour des besoins B2B, B2C et internes

9,8/10

de NPS client depuis 2019. Nous construisons un partenariat sur la durée.

Expertises

Développement web & mobile

Product Management

Data & IA

Yield Studio logo blanc

Découvrez Cyrille ADAM
Co-fondateur & CPO

Blog

Découvrez nos articles sur la thématique développement web

Comment envoyer des e-mails et SMS transactionnels avec Brevo sur Laravel ?
Si vous développez une application, il est fort probable que vous aillez besoin d’envoyer des e-mails ou des SMS transactionnels à vos utilisateurs. Découvrez notre guide étape par étape pour envoyer des Notifications avec Brevo sur Laravel.
Arthur
3/9/2024

Si vous développez une application SaaS, un réseau social, une marketplace ou encore une application métier, il est fort probable que vous aillez besoin d’envoyer des e-mails ou des SMS transactionnels à vos utilisateurs.

Si vous vous demandez ce qu’est un message transactionnel, c’est un message automatisé qui fournit aux utilisateurs des informations utiles qui visent à l’aider et améliorer son expérience. Parmi les exemples les plus courants, on retrouve les confirmations de commande, les rappels de rendez-vous et l'authentification à deux facteurs.

Exemple d’un e-mail et d’un SMS transactionnel

L’envoi d’e-mails et de SMS transactionnels avec Laravel est un jeu d’enfant, cette simplicité nous la devons au composant Notifications.

Laravel embarque le support de certains canaux : SMTP, Vonage et Slack. Les développeurs peuvent ensuite intégrer leurs propres canaux et les partager à la communauté sous forme de librairies.

C’est ce que nous avons fait chez Yield Studio en développant des packages pour Brevo, Mailjet et Expo !

Dans ce tutoriel, nous allons vous expliquer étape par étape comment envoyer des e-mails et des SMS transactionnels avec yieldstudio/laravel-brevo-notifier !

Étape 1 : Créer un compte Brevo

Pour commencer, vous devez vous créer un compte sur Brevo et vérifier votre adresse e-mail. Après ça vous pourrez vous rendre sur le tableau de bord.

Le plan Gratuit de Brevo vous permet d’envoyer jusqu’à 300 e-mails par jour, quant au SMS vous devrez charger votre compte avec des crédits SMS, à titre d’exemple le pack de 100 crédits SMS à destination de la France est facturé 4,5€.

Étape 2 : Installer Laravel Brevo Notifier

Après avoir créé votre compte Brevo, nous pouvons continuer l’installation.


composer require yieldstudio/laravel-brevo-notifier

Une fois l'installation terminée, nous pouvons éditer le fichier .env et ajouter les variables suivantes avec vos propres valeurs.


BREVO_KEY=your-brevo-key
BREVO_SMS_SENDER=Yield

# Laravel variables
MAIL_FROM_ADDRESS=hello@yieldstudio.fr
MAIL_FROM_NAME=Yield Studio

La valeur de BREVO_KEY peut être obtenue sur votre tableau de bord dans SMTP et API.

Créer une clé API sur Brevo

Quant à la valeur de BREVO_SMS_SENDER, elle est limitée à 11 caractères alphanumériques ou 15 caractères numériques. Il s’agit de l’expéditeur que verra votre utilisateur lors de l’envoi SMS (Yield, Amazon, IKEA)

Étape 3 : Authentifier vos expéditeurs

Avec Brevo comme avec de nombreux fournisseurs, les adresses e-mail qui servent à envoyer des e-mails doivent être une adresse authentifiée. Vous pouvez authentifier une adresse e-mail en particulier ou bien directement un nom de domaine.

Vous devez vous rendre dans Expéditeurs, domaines et IP dédiées et ajouter les adresses e-mails ou les domaines qui vous serviront à envoyer des e-mails.

Liste des expéditeurs autorisés sur Brevo

Étape 4 : Générer la Notification

Vous devez ensuite créer une classe pour votre notification, vous pouvez utiliser la commande Artisan ci-dessous, par exemple nous créons une notification OrderShipped


php artisan make:notification OrderShipped

Cette commande génère la classe dans le dossier App\Notifications. Si ce dossier n’existe pas encore, Laravel le créera pour nous.

Étape 5 : Envoyer un e-mail et un SMS

Assurez ensuite vous de changer le retour de la méthode via pour y ajouter notre BrevoSmsChannel  et/ou BrevoEmailChannel


<?php

namespace App\Notifications;

use Illuminate\Notifications\Notification;
use YieldStudio\LaravelBrevoNotifier\BrevoSmsChannel;
use YieldStudio\LaravelBrevoNotifier\BrevoEmailChannel;

class OrderShipped extends Notification
{
    public function via(): array
    {
        return [BrevoSmsChannel::class, BrevoEmailChannel::class];
    } 
}

Vous pouvez ensuite préparer votre notification en ajoutant la méthode toBrevoSms et/ou toBrevoEmail :


<?php

namespace App\Notifications;

use Illuminate\Notifications\Notification;
use YieldStudio\LaravelBrevoNotifier\BrevoSmsMessage;
use YieldStudio\LaravelBrevoNotifier\BrevoEmailMessage;

class OrderShipped extends Notification
{
    public function __construct(private Order $order) {
    }

    // ...
    
    public function toBrevoSms($notifiable): BrevoSmsMessage
    {
        return (new BrevoSmsMessage())
            ->to($notifiable->phone)
            ->content('La commande n°' . $this->order->number . ' a été expédiée.');
    }

    public function toBrevoEmail($notifiable): BrevoEmailMessage
    {
        return (new BrevoEmailMessage())
            ->templateId(1)
            ->to($notifiable->firstname, $notifiable->email)
            ->params(['order_number' => $this->order->number]);
    }
}

Pour envoyer un e-mail transactionnel avec Brevo, vous devez créer des Templates.

Vous pouvez maintenant envoyer votre notification depuis votre controller, un listener ou l’endroit le plus approprié dans votre cas :


<?php

namespace App\Http\Controllers;

use App\Notifications\SendSMSMessageNotification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

final class MarkOrderAsShipped extends Controller
{
    public function __invoke(Request $request, Order $order)
    {
        // ...
        $request->user->notify(new OrderShipped($order));
        // ...
    }
}

Et voilà vous avez envoyé votre première notification avec Brevo ⚡

Conclusion

Et voila, envoyer un e-mail ou un SMS transactionnel avec Brevo à partir d'une application Laravel c’est relativement simple. Créez d'abord un compte Brevo, installez la librairie yieldstudio/laravel-brevo-notifier, configurez et envoyez votre superbe notification.

Vous pouvez aller encore plus loin en ajoutant des destinataires en copie, des pièces jointes (une facture par exemple) et bien plus.

Sentez-vous libre de tester ce package et d’y contribuer sur Github.

Design Pattern : Compound Components
Nos composants traditionnels montrent parfois leurs limites. Ils ne sont pas tous adaptés pour faire face de manière flexible et robuste à l'évolution constante.
Julien
25/6/2024

Introduction

En tant que développeurs, nous savons que les projets évoluent constamment : les besoins changent, les designs se métamorphosent et les spécifications initiales peuvent rapidement devenir obsolètes.

Face à cet environnement mouvant, nos composants traditionnels montrent parfois leurs limites. Ils ne sont pas tous adaptés pour faire face de manière flexible et robuste à cette évolution constante.

Qui n'a jamais été frustré par un composant trop rigide pour s'accommoder d'un changement de maquette ou d'une mise à jour des exigences du projet ?

Examinons ensemble, deux exemples, pour illustrer le Design Pattern : Compound Components.

Exemple d’un composant d’UI simple ✏️

Supposons que nous devons créer un composant Card tout ce qu’il y a de plus classique. On a besoin d’affiche un title, une description et un thumbnail.

Voilà une implementation simple de ce que pourrait être ce composant :

// card.tsx

type CardProps = {
	title: string;
	description: string;
	thumbnail: string;
}

function Card({ title, description, thumbnail }: CardProps) {
	return (
		<View>
			<Image source={{ uri: thumbnail }} />
			<Text>{title}</Text>
			<Text>{description}</Text>
		</View>
	)
}

Ainsi que son usage :

// home.tsx

function HomeScreen() {
	return (
		<View>
			<Card
				title="Lorem ipsum"
				description="Quis enim aliqua ad et consectetur laboris reprehenderit ea anim occaecat adipisicing duis exercitation magna cupidatat."
				thumbnail="https://picsum.photos/200/300"
			/>
		</View>
	)
}

Jusque là, tout va bien, notre composant est simple à développer, simple à utiliser et facile à relire.

Maintenant, comme dans tous les projets, le besoin évolue et le design de nos composants avec. Admettons, que notre besoin a évolué de façon à ce qu’on ai besoin d’ajouter un bouton sur notre composant Card. Mais, ce bouton ne doit pas apparaître à tous les endroits de mon application.

Ce que l’on va retrouver dans la plupart des projets professionnels aujourd’hui, c’est une surcharge de propriétés sur le composant. Le plus souvent, notre composant serait comme suit :

// card.tsx

type CardProps = {
	title: string;
	description: string;
	thumbnail: string;
	buttonLabel?: string;
	showButton?: boolean;
	onPressButton?: () => void;
}

function Card({ 
	title, 
	description, 
	thumbnail,
	buttonLabel,
	showButton = false,
	onPressButton
}: CardProps) {
	return (
		<View>
			<Image source={{ uri: thumbnail }} />
			<Text>{title}</Text>
			<Text>{description}</Text>
			{showButton && <Button label={buttonLabel} onPress={onPressButton} />}
		</View>
	)
}


NB : c’est volontairement exagéré pour mettre en avant le problème. Même sans Compound Components que l’on verra après, on pourra avoir un composant bien plus propre !

Et l’usage du composant serait comme suit :

// home.tsx

function HomeScreen() {
	return (
		<View>
			<Card
				title="Lorem ipsum"
				description="Quis enim aliqua ad et consectetur laboris reprehenderit ea anim occaecat adipisicing duis exercitation magna cupidatat."
				thumbnail="https://picsum.photos/200/300"
			/>
			<Card
				title="Lorem ipsum"
				description="Quis enim aliqua ad et consectetur laboris reprehenderit ea anim occaecat adipisicing duis exercitation magna cupidatat."
				thumbnail="https://picsum.photos/200/300"
				buttonLabel="Lorem"
				onPressButton={() => { /* ... */}}
				showButton
			/>
		</View>
	)
}


Observations

Que peux-tu observer sur cet exemple de composant “traditionnel” qui ne représente que de l’UI ?

  1. Structure rigide
    Le composant Card a une structure définie, il contient toujours une image, un titre, une description et un bouton. Il n’y a flexibilité pour changer la structure d’un composant en fonction des besoins.
  2. Passage de props
    Toutes les données dont le composant Card a besoin sont passées via les props. Cela peut devenir encombrant et difficile à maintenir à mesure que nous ajoutons plus de props au composant.
  3. Moins de réutilisabilité
    Les sous-composants ne peuvent pas être réutilisés indépendamment. Par exemple, si nous voulons utiliser seulement le bouton ou l'image de la carte dans un autre composant, cela ne serait pas possible.
  4. Peu extensible
    Ajouter de nouvelles fonctionnalités à la carte nécessite une modification de l'implémentation de la carte elle-même, augmentant potentiellement le risque de créer des bugs non liés.
  5. Simplicité
    Cependant, dans certains cas, cette approche peut être préférable pour sa simplicité. Si votre composant est très simple et n'a pas besoin des avantages offerts par le pattern de Compound Components, le surcoût en complexité peut ne pas en valoir la peine.

Exemple d’un composant plus complexe ✏️

Supposons maintenant que nous devons créer un composant plus complexe, des composants mêmes, qui ont besoin de travailler ensuite pour mettre en oeuvre une fonctionnalité de Todo-list.

Pour cela, nous allons avoir les composants TodoList (pour afficher une liste d’item de todo), TodoItem (qui représente un item de todo), TodoForm (qui représente le formulaire d’un item de todo) et TodoStats (qui affiche des statistiques pour une liste de todo donnée).

Voilà une implementation de ce que pourrait être ces composants :

// todo-list.tsx

type TodoListProps = {
	todos: Array<{ id: string; content: string }>;
	onPressDelete: (id: string) => void;
}

function TodoList({ todos, onPressDelete }: TodoListProps) {
	return (
		<View>
			{todos.map((todo) => (
				<TodoItem 
					key={todo.id} 
					id={todo.id} 
					content={todo.content}
					onPressDelete={onPressDelete}
				/>
			)}
		</View>
	)
}

// todo-item.tsx

type TodoItemProps = {
	id: string;
	content: string;
	onPressDelete: (id: string) => void;
}

function TodoItem({ id, content onPressDelete }: TodoListItemProps) {
	return (
		<View>
			<Text>{content}</Text>
			<Button label="Delete" onPress={() => onPressDelete(id)} />
		</View>
	)
}

// todo-form.tsx

type TodoFormProps = {
	onPressSubmit: (content: string) => void;
}

function TodoForm({ onPressSubmit }: TodoFormProps) {
	const [value, setValue] = useState<string>('')
	
	return (
		<View>
			<TextInput value={value} onChangeText={setValue} />
			<Button label="Add" onPress={() => onPressSubmit(value)} />
		</View>
	)
}

// todo-stats.tsx

type TodoStatsProps = {
	todos: Array<{ id: string; content: string }>;
}

function TodoStats({ todos }: TodoStatsProps) {
	return (
		<View>
			<Text>Sum of todos: {todos.length}</Text>
			{/* average number of characters */}
			{/* ... */}
		</View>
	)
}


Ainsi que l’usage de ces composants :

// home.tsx

function HomeScreen() {
	const [todos, setTodos] = useState([])
	
	return (
		<View>
			<TodoList 
				todos={todos} 
				onPressDelete={(id) => 
					setTodos((state) => state.filter(todo) => todo.id !== id
				}
			/>
			<TodoStats todo={todos} />
			<TodoForm 
				onPressSubmit={(content) =>
					setTodos((state) => [...state.todos, { id: uuid(), content }])
				} 
			/>
		</View>
	)
}


Observations

Que peux-tu observer sur cet exemple de composant “traditionnel” qui ne représente cette fois une fonctionnalité plus complexe ?

  1. Rigidité
    Dans l'état actuel, la structure est assez rigide. Par exemple, si vous voulez une autre variante de TodoItem qui a un bouton pour marquer une tâche comme terminée, ou peut-être une variante de TodoForm qui a des champs supplémentaires, l'adaptation de ces composants à ces scénarios serait plus complexe.
  2. Passage de props
    Les fonctions de suppression et d'ajout sont transmises en tant que props aux composants enfants TodoItem et TodoForm depuis le composant parent HomeScreen. Cela peut devenir compliqué à gérer à mesure que l'application s'agrandit, car chaque fois que vous voulez utiliser ces fonctions, vous devez les transmettre à travers tous les composants intermédiaires.
  3. Manque d’encapsulation
    Les composants TodoItem et TodoForm exposent trop de détails d'implémentation. Par exemple, TodoItem a besoin de connaître non seulement le contenu de la tâche, mais aussi son id et comment traiter une action de suppression. De même, TodoForm doit gérer son propre état et savoir comment gérer une action de soumission. Cela pourrait être évité avec une version composée qui masquerait ces détails.
  4. Peu extensible et peu lisible
    Ce point est suffisamment explicite je pense !

Le Design Pattern : Compound Components 👀

Le Design Pattern : Compound Components s’applique à n’importe quel langage fonctionnant avec des composants et de la gestion d’états. Il s’agit d’une approche qui offre :

  1. Structure
    Le terme "Compound Components" décrit une relation "a un" entre les composants. Un composant comporte plusieurs sous-composants qui travaillent ensemble pour former une unité cohérente. Le composant parent sert de composant de mise en page tandis que les sous-composants déterminent le contenu.
  2. Flexibilité
    Les Compound Components offrent une grande flexibilité dans l'arrangement des sous-composants. Les utilisateurs de cette API de composant peuvent contrôler l'organisation, la structure et la présentation d'un composant.
  3. Abstraction
    Ils permettent une bonne séparation des préoccupations car chaque sous-composant traite une fonctionnalité particulière. Cela permet une meilleure réutilisation des composants et simplifie le test et la maintenance.
  4. Pas de passage de props
    Un avantage majeur du modèle de Compound Components est l'évitement du prop-drilling, qui est un problème où des props doivent être passés à travers de nombreux niveaux de composants. Les Compound Components résolvent ce problème en utilisant le contexte React pour partager la valeur entre les composants.
  5. Encapsulation
    Avec les Compound Components, nous pouvons exposer ce qui est nécessaire et masquer les détails d'implémentation spécifiques. Cela aide à produire un code plus clair et plus facile à maintenir.

Mise en pratique

Maintenant, voyons ensemble un refactor de nos composants précédents en version Compound Components.

Le composant d’UI simple en Compound Components

Reprenons notre composant d’UI simple et convertissons les props title, description, etc. en sous-composants pour en faire une composition comme suit :

// card.tsx

type CardProps = PropsWithChildren

function Card({ children }: CardProps) {
	return <View>{children}</View>
}

Card.Title = CardTitle
Card.Description = CardDescription
Card.Thumbnail = CardThumbnail
Card.Button = CardButton

// card-title.tsx

type CardTitleProps = {	title: string }

function CardTitle({ title }: CardTitleProps) {
	return <Text>{title}</Text>
}

// card-description.tsx

type CardDescriptionProps = {	description: string }

function CardDescription({ description }: CardDescriptionProps) {
	return <Text>{description}</Text>
}

// card-thumbnail.tsx

type CardThumbnailProps = {	source: string }

function Card({ source }: CardThumbnailProps) {
	return <Image source={{ uri: thumbnail }} />
}

// card-button.tsx

type CardButtonProps = {
	label: string;
	onPress: () => void;
}

function CardButton({ label, onPress }: CardButtonProps) {
	return <Button label={label} onPress={onPress} />
}


Et maintenant l’usage :

// home.tsx

function HomeScreen() {
	return (
		<View>
			<Card>
				<Card.Thumbnail source="https://picsum.photos/200/300" />
				<Card.Title title="Lorem ipsum" />
				<Card.Description 
					description="Quis enim aliqua ad et consectetur laboris reprehenderit ea anim occaecat adipisicing duis exercitation magna cupidatat."
				/>
			</Card>
			<Card>
				<Card.Thumbnail source="https://picsum.photos/200/300" />
				<Card.Title title="Lorem ipsum" />
				<Card.Description 
					description="Quis enim aliqua ad et consectetur laboris reprehenderit ea anim occaecat adipisicing duis exercitation magna cupidatat."
				/>
				<Card.Button label="Lorem" onPress={() => { /* ... */}} />
			</Card>
		</View>
	)
}


Observations

Quelles observations peux-tu faire cette fois ci ?

  1. Flexibilité
    Le Compound Components donne un plus grand contrôle sur l'organisation des éléments dans le rendu. Dans le deuxième exemple d'utilisation, nous avons de l'information supplémentaire et une absence de bouton, ce qui ne serait pas possible avec une version non composée du composant qui limiterait strictement la structure.
  2. Réutilisabilité
    Les sous-composants, comme CardTitle, CardImage, et CardContent peuvent être réutilisés et réarrangés librement. Cette approche réduit la duplication du code et accroît la maintenabilité.
  3. Lisibilité
    Le code est plus facile à comprendre. Alors qu'un composant non composé pourrait avoir un grand nombre de props, ce qui pourrait rendre le code plus difficile à suivre, chaque sous-composant sait clairement quel est son rôle dans le composant de carte.
  4. Isolation
    Les sous-composants (comme CardButton ou CardImage) peuvent être mis à jour indépendamment des autres sous-composants, évitant ainsi les effets de bord inattendus.
  5. Scalabilité
    Les nouveaux sous-composants peuvent être ajoutés facilement en suivant cette approche, permettant au composant de s'adapter et de se développer avec le temps. Par exemple, un sous-composant CardFooter pourrait être ajouté si besoin.

Le composant complexe en Compound Components

Enfin, passons au plus intéressant, le groupe de composant qui représente la fonctionnalité de Todo-list, voilà la version Compound Components :

// home.tsx

function HomeScreen() {
	return (
		<View>
			<Card>
				<Card.Thumbnail source="https://picsum.photos/200/300" />
				<Card.Title title="Lorem ipsum" />
				<Card.Description 
					description="Quis enim aliqua ad et consectetur laboris reprehenderit ea anim occaecat adipisicing duis exercitation magna cupidatat."
				/>
			</Card>
			<Card>
				<Card.Thumbnail source="https://picsum.photos/200/300" />
				<Card.Title title="Lorem ipsum" />
				<Card.Description 
					description="Quis enim aliqua ad et consectetur laboris reprehenderit ea anim occaecat adipisicing duis exercitation magna cupidatat."
				/>
				<Card.Button label="Lorem" onPress={() => { /* ... */}} />
			</Card>
		</View>
	)
}

Ainsi que son usage, drastiquement simplifiée :

// home.tsx

function HomeScreen() {
	return (
		<View>
			<Todos todos={[]}>
				<Todos.List />
				<Todos.Stats />
				<Todos.Form />
			</Todos>
		</View>
	)
}


Observations

Que peux t-on observer sur cette dernière partie ?

  1. Flexibilité d’affichage
    Avec l'approche de Compound Components, la disposition des composants est beaucoup plus flexible. Vous pouvez choisir de rendre Todos.List, Todos.Form, et Todos.Stats dans n'importe quel ordre ou même de ne pas les afficher en fonction des spécificités des spécifications ou des besoins de votre application.
  2. Utilisation du Contexte
    Grâce à l'utilisation de React Context (TodosContext), vous pouvez facilement partager des données (todos) et des fonctions (add, remove) entre tous les composants enfants. Cela permet d'éviter le problème de prop-drilling propre à l'approche non compound components.
  3. Hook personnalisé
    Ils utilisent un hook personnalisé useTodosContext pour obtenir les valeurs du contexte. Ce hook rend le code plus lisible et plus facile à utiliser.
  4. Réutilisabilité accrue
    Les composants sont désormais plus indépendants et peuvent être facilement réutilisés ailleurs dans l'application. Par exemple, Todos.List pourra être utilisé dans un autre écran ou dans une sidebar sans avoir besoin de passer d'informations supplémentaires via les props.
  5. Extensibilité
    Avec cette approche, vous pouvez également étendre facilement le composant Todos en ajoutant des sous-composants supplémentaires sans bouleverser l'architecture existante. Par exemple, si vous voulez ajouter une fonctionnalité pour marquer les tâches comme faites, vous pourriez créer un nouveau sous-composant Todos.Checkbox.

Le mot de la fin 👋

De manière générale, le composant “traditionnel” est plus simple, mais il offre moins de flexibilité et de potentiel de réutilisation que le Compound Components. Le choix entre les deux approches dépend des besoins spécifiques du projet. Mais de mon experience, partir direct sur du Compound Components est rarement une mauvaise idée !

Les inconvénients potentiels de cette approche sont qu'elle est plus complexe et qu'elle nécessite une compréhension plus approfondie des concepts de React (pour le cas de React), tels que le Contexte et les Compound Components eux-mêmes. De plus, il est important de noter que bien que le Context puisse sembler être une solution à tous les problèmes, il doit être utilisé avec parcimonie pour éviter un couplage excessif entre les composants de votre application.

L'adoption du pattern Compound Components dans la conception d'interfaces utilisateur peut sembler déroutante au début, mais les avantages qu'elle offre en termes de modularité, de flexibilité et de réutilisabilité sont indéniables. Ainsi, en décomposant intelligemment les composants en des sous-éléments logiques, nous pouvons produire des systèmes d'UI flexibles, réutilisables et gérables.

Vous pouvez retrouvez cet article au format vidéo sur YouTube en suivant ce lien.

L'Architecture hexagonale : Introduction
Découvrez l'architecture hexagonale : principes, exemples, intégration avec Spring Boot. Optimisez votre code pour des applications mobiles robustes.
Julien
26/2/2024

Découvrons aujourd’hui l'univers captivant de l'architecture hexagonale. Cette approche du développement d'applications mobiles repose sur des principes fondamentaux, offrant une structure robuste et évolutive. Dans cet article, explorez les bases de l'architecture hexagonale, découvrez des exemples concrets sur GitHub et apprenez à l'intégrer avec Spring Boot. Optimisez votre code, maîtrisez l'inversion des dépendances et transformez votre façon de concevoir des applications mobiles.

Bienvenue dans le futur du développement logiciel !

Qu'est-ce que l'architecture hexagonale ?

L'architecture hexagonale redéfinit la conception des applications mobiles. À la base de cette approche novatrice se trouvent des principes clés, sculptant une structure en forme d'hexagone. Cette méthode se distingue par son agilité, son adaptabilité et son aptitude à créer des applications robustes. Découvrons les fondements de l'architecture hexagonale pour comprendre comment elle redéfinit le développement logiciel.

L'architecture hexagonale transcende les schémas conventionnels de développement logiciel. Imaginons-la comme une vue aérienne de votre application, où un hexagone représente le cœur, le noyau de votre système. Plongeons dans les détails de cette approche novatrice.

Au centre de cette structure, nous trouvons l'hexagone central. C'est le cœur, le noyau où réside la logique métier de votre application. Cet espace défini par l'hexagone représente l'essence même de ce que votre application offre à ses utilisateurs.

Les côtés de l'hexagone représentent les couches périphériques. Chacune de ces couches a un rôle spécifique dans l'interaction de l’application avec le monde extérieur. De la gestion des entrées/sorties à la persistance des données, ces couches entourent le noyau central, mais sans créer de dépendances directes avec lui.

Les interactions entre le cœur et les couches périphériques se font à travers des ports et adaptateurs. Les ports définissent des interfaces au sein du noyau, tandis que les adaptateurs fournissent des implémentations concrètes pour ces interfaces. Cette modularité offre une flexibilité essentielle, permettant à l'application de s'adapter sans altérer sa logique métier.

Enfin, l'inversion des dépendances est le principe qui gouverne l'architecture hexagonale. Plutôt que d'avoir des dépendances directes, le cœur de l'application dépend d'abstractions définies par les ports. Cette inversion crée un environnement flexible permettant des modifications sans impacter la stabilité du système.

Pour comprendre pleinement l'architecture hexagonale, explorons des exemples concrets. 

L'architecture hexagonale ne se contente pas de suivre les sentiers battus du développement logiciel. Imaginez-la comme une vue aérienne de votre application, où un hexagone représente le cœur, le noyau vibrant de votre système. Plongeons dans les détails pour rendre cette approche plus tangible.

Au cœur, l'hexagone central incarne la logique métier de votre application. C'est là que réside l'essence de ce que votre application offre à ses utilisateurs. Autour de ce noyau, les côtés de l'hexagone représentent les couches périphériques. De la gestion des entrées/sorties à la persistance des données, chaque couche a un rôle précis dans l'interaction de l'application avec le monde extérieur.

Exemples concrets

Imaginons une application de gestion de tâches où le cœur de l'hexagone représente la logique de gestion des tâches, des deadlines, etc. Les côtés de l'hexagone pourraient inclure une couche d'interface utilisateur, une couche de persistance des données, et une couche de services externes.

Les interactions entre le cœur et les couches périphériques s'effectuent à travers des ports et adaptateurs. Les ports définissent des interfaces au sein du noyau, tandis que les adaptateurs fournissent des implémentations concrètes pour ces interfaces. Cette modularité offre une flexibilité essentielle, permettant à l'application de s'adapter sans compromettre sa logique métier.

Supposons que le port "GestionTâchesPort" définisse les opérations nécessaires à la gestion des tâches. L'adaptateur "GestionTâchesAdapter" fournirait l'implémentation concrète de ces opérations, interagissant avec la base de données et les services externes.

Enfin, l'inversion des dépendances règne en maître dans l'architecture hexagonale. Plutôt que des dépendances directes, le cœur dépend d'abstractions définies par les ports. Cette inversion crée un environnement souple, permettant des modifications sans secouer la stabilité du système.

Plutôt que d'avoir des dépendances directes vers la base de données, le cœur dépendrait d'interfaces définies dans le port "PersistancePort", laissant les détails d'implémentation à l'adaptateur "PersistanceAdapter".

En résumé, l'architecture hexagonale offre une vision stratégique du développement logiciel. Elle place la logique métier au centre, entourée de couches flexibles facilitant l'interaction avec le monde extérieur. Cette approche, avec son hexagone central et ses principes fondamentaux, ouvre la voie à des applications mobiles robustes, adaptables et pérennes.

Les principes de l'architecture hexagonale

L'architecture hexagonale repose sur des fondements solides, formant une structure en forme d'hexagone pour créer des applications mobiles robustes. Décortiquons les principes clés qui définissent cette approche innovante :

  • L'architecture hexagonale est structurée en couches fondamentales. De la couche d'infrastructure à celle de persistance, chaque strate joue un rôle crucial. Cela offre une organisation claire, favorisant la stabilité et la modularité.
  • Le point d'entrée représente l'accès initial à l'application, tandis que la logique métier dicte son fonctionnement interne. Cette dualité assure une expérience utilisateur fluide, équilibrant l'interaction extérieure avec la logique interne.
  • Fondamentale à l'architecture hexagonale, l'inversion des dépendances renverse les schémas traditionnels. Cette approche permet à l'application de s'adapter aux changements sans compromettre sa stabilité. Elle crée un environnement où la logique métier guide les détails d'implémentation.

Mise en pratique de l'architecture hexagonale

Découvrons comment concrètement mettre en œuvre l'architecture hexagonale dans le développement d'applications mobiles. Plongeons dans des exemples tangibles pour comprendre son impact réel.

Explorez un exemple concret sur GitHub où le code source d'une application est dévoilé. Chaque composant, de la couche d'infrastructure à la couche de persistance, est clairement défini. Visualisez comment ces éléments s'entremêlent pour former une structure cohérente. Cette transparence simplifie le processus de développement, permettant une compréhension facile et une évolution efficace de l'application.

L'intégration pratique de l'architecture hexagonale est facilitée avec Spring Boot. Cette union offre une approche concrète pour développer des applications mobiles robustes. Elle simplifie la gestion des dépendances et maintient la flexibilité, permettant aux développeurs de se concentrer sur la création plutôt que sur des considérations techniques. 

L'architecture hexagonale dans le contexte du Domain-Driven Design

Plongeons dans la synergie puissante entre l'architecture hexagonale et les principes du Domain-Driven Design (DDD), développant ainsi des applications mobiles de plus grande qualité.

L'architecture hexagonale et le Domain-Driven Design (DDD) fusionnent harmonieusement pour définir des modèles de domaine robustes offrant ainsi une approche complète du développement logiciel.

Lorsque nous plongeons l'architecture hexagonale dans le contexte du Domain-Driven Design (DDD), une collaboration symbiotique émerge. Ces deux approches, axées sur la compréhension profonde du domaine métier, se renforcent mutuellement.

1. Collaboration Harmonieuse

Imaginons une application de commerce électronique. Dans l'architecture hexagonale, le cœur de l'hexagone représente la gestion des commandes, des transactions, et des stocks, constituant la logique métier centrale. Dans le contexte du DDD, ces entités deviennent les agrégats du domaine, chacun avec son propre cycle de vie et ses règles métier spécifiques. Ainsi, l'hexagone central et les agrégats du DDD collaborent harmonieusement pour façonner le modèle de domaine.

2. Réflexion sur le Contexte Limité

Poursuivons avec la réflexion sur le contexte limité du DDD. Supposons que notre application de commerce électronique ait également un module de gestion des utilisateurs. Dans l'architecture hexagonale, cela devient une autre zone centrale, avec ses propres ports et adaptateurs. Dans le contexte limité du DDD, ce module représente son propre sous-domaine avec ses règles métier distinctes. Cette approche permet une séparation claire des préoccupations et une meilleure compréhension du modèle de domaine, alignant ainsi l'architecture hexagonale avec les principes du DDD.

3. Alistair Cockburn et les Fondements

Alistair Cockburn, un pionnier du Domain-Driven Design, souligne l'importance de définir des interactions précises entre les entités du domaine. Dans l'architecture hexagonale, cela se traduit par la définition précise des ports et adaptateurs, offrant une interface bien définie pour chaque interaction. Cette synchronicité entre les principes de Cockburn et l'architecture hexagonale garantit une compréhension approfondie du domaine et une mise en œuvre logicielle qui reflète fidèlement la réalité métier.

L'architecture hexagonale et le Domain-Driven Design forment une alliance puissante. En utilisant des exemples concrets, nous avons vu comment ces approches complémentaires collaborent pour créer des modèles de domaine clairs, des contextes limités bien définis, et des applications mobiles riches en fonctionnalités métier.

Nos conseils pratiques et astuces

Explorez des conseils concrets et des astuces judicieuses pour optimiser l'utilisation de l'architecture hexagonale dans le développement d'applications mobiles.

Dans la mise en œuvre de l'architecture hexagonale, privilégiez la clarté. Des noms de classes explicites aux commentaires informatifs, assurez-vous que chaque composant de votre application est compréhensible. La transparence facilite la collaboration et la maintenance à long terme.

Investissez dans des tests unitaires approfondis. L'architecture hexagonale favorise la testabilité, alors profitez-en. Des tests solides garantissent la stabilité de votre application et facilitent l'identification rapide des problèmes potentiels.

Accompagnez votre code d'une documentation complète. Décrivez les choix architecturaux, les interactions clés, et les modèles de domaine. Une documentation détaillée facilite l'intégration de nouveaux membres dans l'équipe et assure une compréhension globale du projet.

Soyez sélectif quant aux dépendances. Limitez-vous aux dépendances nécessaires pour éviter la complexité inutile. Une architecture hexagonale bien conçue privilégie la simplicité, ce qui facilite la maintenance et l'évolutivité.

Adoptez une approche itérative. L'itération continue associée au réajustement est essentielle. Recueillez les retours, identifiez les améliorations possibles, et évoluez constamment. Cette approche flexible s'aligne parfaitement avec les principes de l'architecture hexagonale.

L'architecture hexagonale se révèle comme une approche incontournable pour le développement d'applications mobiles. Avec ses principes solides, sa mise en pratique transparente, et sa synergie avec le Domain-Driven Design, elle offre une solution robuste et flexible.

Priorisez la clarté, investissez dans des tests unitaires approfondis, documentez judicieusement, évitez les dépendances superflues, et adoptez une approche itérative pour un succès continu.

En embrassant l'architecture hexagonale, vous développez des applications mobiles plus résilientes et créez une base pour l'innovation future. Restez agile, apprenez constamment, et évoluez avec votre application.

L'architecture hexagone est le socle sur lequel repose l'avenir du développement logiciel mobile.

FAQ

La réponse à vos questions

Pourquoi faire appel à une agence de développement web à Paris ?
Travailler avec Yield Studio Paris, une agence située au cœur de Paris, vous permet de bénéficier d’un accompagnement local sur-mesure. Nous comprenons les spécificités du marché parisien et développons des applications web robustes et évolutives qui répondent aux besoins des entreprises de la capitale et de la région Île-de-France.
Pourquoi votre application web doit-elle avoir un impact business à Paris ?
À Paris, un marché où l’innovation est essentielle, une application web performante doit produire des résultats concrets : productivité accrue, meilleure expérience utilisateur, augmentation des ventes… Chez Yield Studio Paris, nous concevons des applications web qui créent de la valeur pour vos utilisateurs parisiens et qui soutiennent efficacement vos objectifs business.
Combien de temps faut-il pour créer une application web à Paris ?
Le développement d’une application web sur-mesure par Yield Studio Paris suit une méthodologie agile. Nous visons à livrer un prototype fonctionnel en 3 à 5 semaines, et une version complète prête à être lancée entre 10 et 22 semaines, selon la complexité du projet. Notre présence à Paris permet une réactivité optimale à chaque étape.
Combien coûte le développement d’une application web à Paris ?
Le coût de développement d’une application web par Yield Studio Paris dépend de la complexité de votre projet, de ses spécificités techniques et de vos objectifs. En moyenne, nos projets démarrent à partir de 30k€. Nous analysons vos besoins pour proposer une solution parfaitement adaptée, garantissant un retour sur investissement optimal.

Échangeons sur votre projet !

Application web
Application mobile
Logiciel métier
Nous contacter

Simulateur

Bienvenue dans le
simulateur d’estimation

Sélectionnez
vos besoins

Sélectionnez un ou plusieurs choix

Définissez les
fonctionnalités

Sélectionnez un ou plusieurs choix

Dernière
étape !

Renseignez votre adresse mail pour recevoir l’estimation !
Obtenez l’estimation
Précédent
Suivant

Bravo ! Vous avez terminé
l’estimation de votre future app !

Vous recevrez dans votre boite mail l’estimation personnalisé. Une estimation vous offre la possibilité de vous projeter dans un budget, vous permettant ainsi de planifier en toute confiance. Néanmoins, chez Yield, nous adoptons une approche agile, prêts à remettre en question et ajuster nos évaluations en fonction de l'évolution de vos besoins et des spécificités de votre projet.
Retour au site
Oops! Something went wrong while submitting the form.