国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Maison Java javaDidacticiel JOOQ ne remplace pas Hibernate. Ils résolvent différents problèmes

JOOQ ne remplace pas Hibernate. Ils résolvent différents problèmes

Jan 11, 2025 pm 08:10 PM

J'ai initialement écrit cet article en russe. Donc, si vous êtes natif, vous pouvez le lire via ce lien.

Au cours de la dernière année, je suis tombé sur des articles et des discussions suggérant que JOOQ est une alternative moderne et supérieure à Hibernate. Les arguments incluent généralement?:

  1. JOOQ vous permet de tout vérifier au moment de la compilation, contrairement à Hibernate?!
  2. Hibernate génère des requêtes étranges et pas toujours optimales, alors qu'avec JOOQ, tout est transparent !
  3. Les entités Hibernate sont mutables, ce qui est mauvais. JOOQ permet à toutes les entités d'être immuables (bonjour la programmation fonctionnelle) !
  4. JOOQ n'implique aucune ? magie ? avec les annotations !

Permettez-moi de préciser d'emblée que je considère JOOQ comme une excellente bibliothèque (en particulier une bibliothèque, pas un framework comme Hibernate). Il excelle dans sa tache : travailler avec SQL de manière statique pour détecter la plupart des erreurs au moment de la compilation.

Cependant, quand j'entends l'argument selon lequel l'époque d'Hibernate est révolue et que nous devrions maintenant tout écrire en utilisant JOOQ, cela me semble dire que l'ère des bases de données relationnelles est révolue et que nous ne devrions utiliser que NoSQL maintenant. ?a a l'air dr?le ? Et pourtant, il n’y a pas si longtemps, de telles discussions étaient plut?t sérieuses.

Je pense que le problème réside dans une mauvaise compréhension des problèmes fondamentaux résolus par ces deux outils. Dans cet article, je vise à clarifier ces questions. Nous explorerons?:

  1. Qu'est-ce que le script de transaction??
  2. Qu'est-ce que le modèle de modèle de domaine??
  3. Quels problèmes spécifiques Hibernate et JOOQ résolvent-ils??
  4. Pourquoi l’un ne remplace-t-il pas l’autre, et comment peuvent-ils coexister??

JOOQ Is Not a Replacement for Hibernate. They Solve Different Problems

Script de transaction

La manière la plus simple et la plus intuitive de travailler avec une base de données est le modèle Transaction Script. En bref, vous organisez toute votre logique métier sous la forme d'un ensemble de commandes SQL combinées en une seule transaction. En règle générale, chaque méthode d'une classe représente une opération commerciale et se limite à une seule transaction.

Supposons que nous développions une application qui permet aux intervenants de soumettre leurs exposés à une conférence (pour plus de simplicité, nous n'enregistrerons que le titre de l'exposé). En suivant le modèle Transaction Script, la méthode de soumission d'une présentation pourrait ressembler à ceci (en utilisant JDBI pour SQL)?:

@Service
@RequiredArgsConstructor
public class TalkService {
    private final Jdbi jdbi;

    public TalkSubmittedResult submitTalk(Long speakerId, String title) {
        var talkId = jdbi.inTransaction(handle -> {
            // Count the number of accepted talks by the speaker
            var acceptedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'ACCEPTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // Check if the speaker is experienced
            var experienced = acceptedTalksCount >= 10;
            // Determine the maximum allowable number of submitted talks
            var maxSubmittedTalksCount = experienced ? 5 : 3;
            var submittedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'SUBMITTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // If the maximum number of submitted talks is exceeded, throw an exception
            if (submittedTalksCount >= maxSubmittedTalksCount) {
                throw new CannotSubmitTalkException("Submitted talks count is maximum: " + maxSubmittedTalksCount);
            }
            return handle.createUpdate(
                    "INSERT INTO talk (speaker_id, status, title) " +
                    "VALUES (:id, 'SUBMITTED', :title)"
                ).bind("id", speakerId)
                   .bind("title", title)
                   .executeAndReturnGeneratedKeys("id")
                   .mapTo(Long.class)
                   .one();
        });
        return new TalkSubmittedResult(talkId);
    }
}

Dans ce code?:

  1. Nous comptons le nombre d'exposés que l'orateur a déjà soumis.
  2. Nous vérifions si le nombre maximum autorisé d'exposés soumis est dépassé.
  3. Si tout va bien, nous créons une nouvelle discussion avec le statut SOUMIS.

Il existe ici une condition de concurrence potentielle, mais par souci de simplicité, nous ne nous concentrerons pas sur cela.

Avantages de cette approche?:

  1. Le SQL en cours d'exécution est simple et prévisible. Il est facile de le modifier pour améliorer les performances si nécessaire.
  2. Nous récupérons uniquement les données nécessaires de la base de données.
  3. Avec JOOQ, ce code peut être écrit de manière plus simple, plus concise et avec un typage statique !

Inconvénients?:

  1. Il est impossible de tester la logique métier avec les seuls tests unitaires. Vous aurez besoin de tests d’intégration (et de nombreux d’entre eux).
  2. Si le domaine est complexe, cette approche peut rapidement conduire à du code spaghetti.
  3. Il existe un risque de duplication de code, ce qui pourrait entra?ner des bugs inattendus au fur et à mesure de l'évolution du système.

Cette approche est valable et logique si votre service a une logique très simple qui ne devrait pas devenir plus complexe avec le temps. Cependant, les domaines sont souvent plus grands. Par conséquent, nous avons besoin d’une alternative.

Modèle de domaine

L'idée du modèle de modèle de domaine est que nous ne lions plus notre logique métier directement aux commandes SQL. Au lieu de cela, nous créons des objets de domaine (dans le contexte de Java, des classes) qui décrivent le comportement et stockent des données sur les entités de domaine.

Dans cet article, nous ne discuterons pas de la différence entre les modèles anémiques et riches. Si vous êtes intéressé, j'ai écrit un article détaillé sur ce sujet.

Les scénarios métier (services) doivent utiliser uniquement ces objets et éviter d'être liés à des requêtes de base de données spécifiques.

Bien s?r, en réalité, nous pouvons avoir un mélange d'interactions avec des objets de domaine et de requêtes directes de base de données pour répondre aux exigences de performances. Ici, nous discutons de l'approche classique de mise en ?uvre du modèle de domaine, où l'encapsulation et l'isolation ne sont pas violées.

Par exemple, si nous parlons des entités Speaker et Talk, comme mentionné précédemment, les objets de domaine pourraient ressembler à ceci?:

@Service
@RequiredArgsConstructor
public class TalkService {
    private final Jdbi jdbi;

    public TalkSubmittedResult submitTalk(Long speakerId, String title) {
        var talkId = jdbi.inTransaction(handle -> {
            // Count the number of accepted talks by the speaker
            var acceptedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'ACCEPTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // Check if the speaker is experienced
            var experienced = acceptedTalksCount >= 10;
            // Determine the maximum allowable number of submitted talks
            var maxSubmittedTalksCount = experienced ? 5 : 3;
            var submittedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'SUBMITTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // If the maximum number of submitted talks is exceeded, throw an exception
            if (submittedTalksCount >= maxSubmittedTalksCount) {
                throw new CannotSubmitTalkException("Submitted talks count is maximum: " + maxSubmittedTalksCount);
            }
            return handle.createUpdate(
                    "INSERT INTO talk (speaker_id, status, title) " +
                    "VALUES (:id, 'SUBMITTED', :title)"
                ).bind("id", speakerId)
                   .bind("title", title)
                   .executeAndReturnGeneratedKeys("id")
                   .mapTo(Long.class)
                   .one();
        });
        return new TalkSubmittedResult(talkId);
    }
}

Ici, la classe Speaker contient la logique métier pour soumettre un exposé. L'interaction avec la base de données est abstraite, permettant au modèle de domaine de se concentrer sur les règles métier.

En supposant cette interface de référentiel?:

@AllArgsConstructor
public class Speaker {
    private Long id;
    private String firstName;
    private String lastName;
    private List<Talk> talks;

    public Talk submitTalk(String title) {
        boolean experienced = countTalksByStatus(Status.ACCEPTED) >= 10;
        int maxSubmittedTalksCount = experienced ? 3 : 5;
        if (countTalksByStatus(Status.SUBMITTED) >= maxSubmittedTalksCount) {
            throw new CannotSubmitTalkException(
              "Submitted talks count is maximum: " + maxSubmittedTalksCount);
        }
        Talk talk = Talk.newTalk(this, Status.SUBMITTED, title);
        talks.add(talk);
        return talk;
    }

    private long countTalksByStatus(Talk.Status status) {
        return talks.stream().filter(t -> t.getStatus().equals(status)).count();
    }
}

@AllArgsConstructor
public class Talk {
    private Long id;
    private Speaker speaker;
    private Status status;
    private String title;
    private int talkNumber;

    void setStatus(Function<Status, Status> fnStatus) {
        this.status = fnStatus.apply(this.status);
    }

    public enum Status {
        SUBMITTED, ACCEPTED, REJECTED
    }
}

Ensuite, SpeakerService peut être implémenté de cette fa?on?:

public interface SpeakerRepository {
    Speaker findById(Long id);
    void save(Speaker speaker);
}

Avantages du modèle de domaine?:

  1. Les objets de domaine sont complètement découplés des détails d'implémentation (c'est-à-dire la base de données). Cela les rend faciles à tester avec des tests unitaires réguliers.
  2. La logique métier est centralisée au sein des objets du domaine. Cela réduit considérablement le risque de propagation de la logique dans l'application, contrairement à l'approche Transaction Script.
  3. Si vous le souhaitez, les objets de domaine peuvent être rendus entièrement immuables, ce qui augmente la sécurité lorsque vous travaillez avec eux (vous pouvez les transmettre à n'importe quelle méthode sans vous soucier des modifications accidentelles).
  4. Les champs des objets de domaine peuvent être remplacés par des objets de valeur, ce qui non seulement améliore la lisibilité mais garantit également la validité des champs au moment de l'affectation (vous ne pouvez pas créer un objet de valeur avec un contenu non valide).

Bref, les avantages ne manquent pas. Il existe cependant un défi important. Il est intéressant de noter que dans les livres sur la conception basée sur le domaine, qui font souvent la promotion du modèle de modèle de domaine, ce problème n'est pas mentionné du tout ou n'est que brièvement évoqué.

Le problème est comment enregistrer les objets de domaine dans la base de données, puis les relire?? En d’autres termes, comment implémenter un référentiel ?

Aujourd’hui, la réponse est évidente. Utilisez simplement Hibernate (ou encore mieux, Spring Data JPA) et évitez les ennuis. Mais imaginons que nous soyons dans un monde où les frameworks ORM n’ont pas été inventés. Comment pourrions-nous résoudre ce problème??

Cartographie manuelle

Pour implémenter SpeakerRepository, j'utilise également JDBI?:

@Service
@RequiredArgsConstructor
public class TalkService {
    private final Jdbi jdbi;

    public TalkSubmittedResult submitTalk(Long speakerId, String title) {
        var talkId = jdbi.inTransaction(handle -> {
            // Count the number of accepted talks by the speaker
            var acceptedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'ACCEPTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // Check if the speaker is experienced
            var experienced = acceptedTalksCount >= 10;
            // Determine the maximum allowable number of submitted talks
            var maxSubmittedTalksCount = experienced ? 5 : 3;
            var submittedTalksCount =
                handle.select("SELECT count(*) FROM talk WHERE speaker_id = :id AND status = 'SUBMITTED'")
                    .bind("id", speakerId)
                    .mapTo(Long.class)
                    .one();
            // If the maximum number of submitted talks is exceeded, throw an exception
            if (submittedTalksCount >= maxSubmittedTalksCount) {
                throw new CannotSubmitTalkException("Submitted talks count is maximum: " + maxSubmittedTalksCount);
            }
            return handle.createUpdate(
                    "INSERT INTO talk (speaker_id, status, title) " +
                    "VALUES (:id, 'SUBMITTED', :title)"
                ).bind("id", speakerId)
                   .bind("title", title)
                   .executeAndReturnGeneratedKeys("id")
                   .mapTo(Long.class)
                   .one();
        });
        return new TalkSubmittedResult(talkId);
    }
}

L'approche est simple. Pour chaque référentiel, nous écrivons une implémentation distincte qui fonctionne avec la base de données en utilisant n'importe quelle bibliothèque SQL (comme JOOQ ou JDBI).

à première vue (et peut-être même au second), cette solution peut para?tre plut?t bonne. Considérez ceci?:

  1. Le code reste très transparent, tout comme dans l'approche Transaction Script.
  2. Plus de problèmes liés au test de la logique métier uniquement via des tests d'intégration. Ceux-ci ne sont nécessaires que pour les implémentations de référentiels (et peut-être quelques scénarios E2E).
  3. Le code de cartographie est juste devant nous. Aucune magie Hibernate n’est impliquée. Vous avez trouvé un bug ? Localisez la bonne ligne et corrigez-la.

Le besoin d’hiberner

Les choses deviennent beaucoup plus intéressantes dans le monde réel, où vous pourriez rencontrer des scénarios comme ceux-ci?:

  1. Les objets de domaine peuvent devoir prendre en charge l'héritage.
  2. Un groupe de champs peut être combiné dans un objet de valeur distinct (intégré dans JPA/Hibernate).
  3. Certains champs ne doivent pas être chargés à chaque fois que vous récupérez un objet de domaine, mais uniquement lors de l'accès, pour améliorer les performances (chargement paresseux).
  4. Il peut y avoir des relations complexes entre les objets (un-à-plusieurs, plusieurs-à-plusieurs, etc.).
  5. Vous devez inclure uniquement les champs qui ont changé dans l'instruction UPDATE car les autres champs changent rarement et cela ne sert à rien de les envoyer sur le réseau (annotation DynamicUpdate).

En plus de cela, vous devrez conserver le code de mappage à mesure que votre logique métier et vos objets de domaine évoluent.

Si vous essayez de gérer chacun de ces points par vous-même, vous finirez par vous retrouver (surprise?!) à écrire votre framework de type Hibernate - ou plus probablement, une version beaucoup plus simple de celui-ci.

Objectifs de JOOQ et Hibernate

JOOQ résout le manque de typage statique lors de l'écriture de requêtes SQL. Cela permet de réduire le nombre d'erreurs au stade de la compilation. Avec la génération de code directement à partir du schéma de base de données, toute mise à jour du schéma indiquera immédiatement où le code doit être corrigé (il ne sera tout simplement pas compilé).

Hibernate résout le problème du mappage des objets de domaine à une base de données relationnelle et vice versa (lire les données de la base de données et les mapper aux objets de domaine).

Par conséquent, cela n’a aucun sens de prétendre qu’Hibernate est pire ou que JOOQ est meilleur. Ces outils sont con?us à des fins différentes. Si votre application est construite autour du paradigme Transaction Script, JOOQ est sans aucun doute le choix idéal. Mais si vous souhaitez utiliser le modèle de modèle de domaine et éviter la mise en veille prolongée, vous devrez composer avec les joies du mappage manuel dans les implémentations de référentiels personnalisés. Bien s?r, si votre employeur vous paie pour créer encore un autre tueur Hibernate, pas de questions. Mais très probablement, ils s'attendent à ce que vous vous concentriez sur la logique métier, et non sur le code d'infrastructure pour le mappage objet-base de données.

Au fait, je pense que la combinaison d'Hibernate et de JOOQ fonctionne bien pour CQRS. Vous disposez d'une application (ou d'une partie logique de celle-ci) qui exécute des commandes, comme les opérations CREATE/UPDATE/DELETE — c'est là qu'Hibernate s'intègre parfaitement. D'un autre c?té, vous disposez d'un service de requête qui lit les données. Ici, JOOQ est génial. Cela rend la création de requêtes complexes et leur optimisation beaucoup plus faciles qu'avec Hibernate.

Qu’en est-il des DAO dans JOOQ??

C'est vrai. JOOQ vous permet de générer des DAO contenant des requêtes standard pour récupérer des entités de la base de données. Vous pouvez même étendre ces DAO avec vos méthodes. De plus, JOOQ générera des entités qui pourront être renseignées à l'aide de setters, similaires à Hibernate, et transmises aux méthodes d'insertion ou de mise à jour du DAO. N'est-ce pas comme Spring Data??

Pour les cas simples, cela peut effectivement fonctionner. Cependant, ce n’est pas très différent de l’implémentation manuelle d’un référentiel. Les problèmes sont similaires?:

  1. Les entités n’auront aucune relation : pas de ManyToOne, pas de OneToMany. Juste les colonnes de la base de données, ce qui rend l'écriture de la logique métier beaucoup plus difficile.
  2. Les entités sont générées individuellement. Vous ne pouvez pas les organiser selon une hiérarchie d’héritage.
  3. Le fait que les entités soient générées avec les DAO signifie que vous ne pouvez pas les modifier à votre guise. Par exemple, remplacer un champ par un objet de valeur, ajouter une relation à une autre entité ou regrouper des champs dans un élément intégrable ne sera pas possible car la régénération des entités écrasera vos modifications. Oui, vous pouvez configurer le générateur pour créer des entités légèrement différemment, mais les options de personnalisation sont limitées (et pas aussi pratiques que d'écrire le code vous-même).

Donc, si vous souhaitez créer un modèle de domaine complexe, vous devrez le faire manuellement. Sans Hibernate, la responsabilité de la cartographie vous incombera entièrement. Bien s?r, utiliser JOOQ est plus agréable que JDBI, mais le processus demandera toujours beaucoup de travail.

Même Lukas Eder, le créateur de JOOQ, mentionne dans son blog que les DAO ont été ajoutés à la bibliothèque parce que c'est un modèle populaire, pas parce qu'il recommande nécessairement de les utiliser.

Conclusion

Merci d’avoir lu l’article. Je suis un grand fan d’Hibernate et je le considère comme un excellent framework. Cependant, je comprends que certains puissent trouver JOOQ plus pratique. Le point principal de mon article est qu’Hibernate et JOOQ ne sont pas rivaux. Ces outils peuvent coexister même au sein d'un même produit s'ils apportent de la valeur.

Si vous avez des commentaires ou des retours sur le contenu, je serai ravi d'en discuter. Passez une journée productive?!

Ressources

  1. JDBI
  2. Script de transaction
  3. Modèle de domaine
  4. Mon article – Modèle de domaine enrichi avec Spring Boot et Hibernate
  5. Modèle de référentiel
  6. Objet valeur
  7. JPA intégré
  8. Mise à jour dynamique JPA
  9. CQRS
  10. Lukas Eder : Vers DAO ou pas vers DAO

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefa?on, veuillez contacter admin@php.cn

Outils d'IA chauds

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Différence entre le hashmap et le hashtable? Différence entre le hashmap et le hashtable? Jun 24, 2025 pm 09:41 PM

La différence entre le hashmap et le hashtable se reflète principalement dans la sécurité des threads, la prise en charge de la valeur nul et les performances. 1. En termes de sécurité des threads, le hashtable est en filetage et ses méthodes sont principalement des méthodes synchrones, tandis que HashMAP n'effectue pas de traitement de synchronisation, qui n'est pas un filetage; 2. En termes de support de valeur nulle, HashMap permet une clé nul et plusieurs valeurs nulles, tandis que le hashtable ne permet pas les clés ou les valeurs nulles, sinon une nulpointerexception sera lancée; 3. En termes de performances, le hashmap est plus efficace car il n'y a pas de mécanisme de synchronisation et le hashtable a une faible performance de verrouillage pour chaque opération. Il est recommandé d'utiliser à la place ConcurrentHashMap.

Pourquoi avons-nous besoin de cours d'emballage? Pourquoi avons-nous besoin de cours d'emballage? Jun 28, 2025 am 01:01 AM

Java utilise des classes de wrapper car les types de données de base ne peuvent pas participer directement aux opérations orientées objet, et les formulaires d'objets sont souvent nécessaires dans les besoins réels; 1. Les classes de collecte ne peuvent stocker que des objets, tels que les listes, l'utilisation de la boxe automatique pour stocker des valeurs numériques; 2. Les génériques ne prennent pas en charge les types de base et les classes d'emballage doivent être utilisées comme paramètres de type; 3. Les classes d'emballage peuvent représenter les valeurs nulles pour distinguer les données non définies ou manquantes; 4. Les cours d'emballage fournissent des méthodes pratiques telles que la conversion de cha?nes pour faciliter l'analyse et le traitement des données, donc dans les scénarios où ces caractéristiques sont nécessaires, les classes de packaging sont indispensables.

Quelles sont les méthodes statiques dans les interfaces? Quelles sont les méthodes statiques dans les interfaces? Jun 24, 2025 pm 10:57 PM

StaticMethodsinInterfaceswereintrocedInjava8TollowutilityfonctionwithIntheInterface self.beforejava8, telfunctionsrequuresepatehelperclasses, leadstodisorganizedCode.now, staticmethodsprovidethrekeyefits: 1) ils sont en train

Comment le compilateur JIT optimise-t-il le code? Comment le compilateur JIT optimise-t-il le code? Jun 24, 2025 pm 10:45 PM

Le compilateur JIT optimise le code à travers quatre méthodes: méthode en ligne, détection et compilation de points chauds, spéculation et dévigtualisation de type et élimination redondante. 1. La méthode en ligne réduit les frais généraux d'appel et inserte fréquemment appelées petites méthodes directement dans l'appel; 2. Détection de points chauds et exécution de code haute fréquence et optimiser de manière centralisée pour économiser des ressources; 3. Type Speculations collecte les informations de type d'exécution pour réaliser des appels de déviptualisation, améliorant l'efficacité; 4. Les opérations redondantes éliminent les calculs et les inspections inutiles en fonction de la suppression des données opérationnelles, améliorant les performances.

Qu'est-ce qu'un bloc d'initialisation d'instance? Qu'est-ce qu'un bloc d'initialisation d'instance? Jun 25, 2025 pm 12:21 PM

Les blocs d'initialisation d'instance sont utilisés dans Java pour exécuter la logique d'initialisation lors de la création d'objets, qui sont exécutés avant le constructeur. Il convient aux scénarios où plusieurs constructeurs partagent le code d'initialisation, l'initialisation du champ complexe ou les scénarios d'initialisation de classe anonyme. Contrairement aux blocs d'initialisation statiques, il est exécuté à chaque fois qu'il est instancié, tandis que les blocs d'initialisation statiques ne s'exécutent qu'une seule fois lorsque la classe est chargée.

Quel est le mot-clé ?final? des variables? Quel est le mot-clé ?final? des variables? Jun 24, 2025 pm 07:29 PM

Injava, thefinalkeywordpreventsavariable'svaluefrombeingchangedafterAsssignment, mais cetsbehaviDiffersFortimitives et objectreferences.forprimitivevariables, finalMakeShevalueConstant, AsinfininTMax_peed = 100; whitereSsignmentCausAnesanerror.ForobjectRe

Quel est le modèle d'usine? Quel est le modèle d'usine? Jun 24, 2025 pm 11:29 PM

Le mode d'usine est utilisé pour encapsuler la logique de création d'objets, ce qui rend le code plus flexible, facile à entretenir et à couplé de manière lache. La réponse principale est: en gérant de manière centralisée la logique de création d'objets, en cachant les détails de l'implémentation et en soutenant la création de plusieurs objets liés. La description spécifique est la suivante: Le mode d'usine remet la création d'objets à une classe ou une méthode d'usine spéciale pour le traitement, en évitant directement l'utilisation de newClass (); Il convient aux scénarios où plusieurs types d'objets connexes sont créés, la logique de création peut changer et les détails d'implémentation doivent être cachés; Par exemple, dans le processeur de paiement, Stripe, PayPal et d'autres instances sont créés par le biais d'usines; Son implémentation comprend l'objet renvoyé par la classe d'usine en fonction des paramètres d'entrée, et tous les objets réalisent une interface commune; Les variantes communes incluent des usines simples, des méthodes d'usine et des usines abstraites, qui conviennent à différentes complexités.

Qu'est-ce que le casting de type? Qu'est-ce que le casting de type? Jun 24, 2025 pm 11:09 PM

Il existe deux types de conversion: implicite et explicite. 1. La conversion implicite se produit automatiquement, comme la conversion INT en double; 2. La conversion explicite nécessite un fonctionnement manuel, comme l'utilisation de (int) MyDouble. Un cas où la conversion de type est requise comprend le traitement de l'entrée des utilisateurs, les opérations mathématiques ou le passage de différents types de valeurs entre les fonctions. Les problèmes qui doivent être notés sont les suivants: transformer les nombres à virgule flottante en entiers tronqueront la partie fractionnaire, transformer les grands types en petits types peut entra?ner une perte de données, et certaines langues ne permettent pas la conversion directe de types spécifiques. Une bonne compréhension des règles de conversion du langage permet d'éviter les erreurs.

See all articles