Try using it in your preferred language.

English

  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar
translation

Dit is een door AI vertaalde post.

제이온

Laten we de weersomstandigheden van vandaag onderzoeken.

Selecteer taal

  • Nederlands
  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • हिन्दी
  • Magyar

Samengevat door durumis AI

  • Laten we de weersomstandigheden van vandaag onderzoeken.
  • Het weer is helder.
  • Je kunt het weer achterhalen.

Overzicht

De traditionele manier om een ​​instantie van een klasse aan te maken, is via een publieke constructor.


public class Lid {

    private String naam;

    private int leeftijd;

    private String hobby;

    private LidStatus lidStatus;

    public Lid(String naam, int leeftijd, String hobby, LidStatus lidStatus) {
        this.naam = naam;
        this.leeftijd = leeftijd;
        this.hobby = hobby;
        this.lidStatus = lidStatus;
    }
}

public enum LidStatus {

    Gevorderd,
    Intermediair,
    Basis;


Over het algemeen volstaat een publieke constructor, maar door naast de constructor ook een statische fabrieksmethode aan te bieden, wordt het voor gebruikers vaak gemakkelijker om instanties te maken zoals ze dat willen.


Een typerend voorbeeld van een statische fabrieksmethode is de valueOf()-methode van Boolean.


public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;


De methode ontvangt een boolean-waarde als primitief type en retourneert deze als een Boolean-object.


Voordelen van de statische fabrieksmethode

Kan een naam hebben.

De parameters die naar een constructor worden doorgegeven, en de constructor zelf beschrijven niet volledig de aard van het object dat zal worden geretourneerd. Het is bijvoorbeeld moeilijk om te achterhalen wat voor soort lid de hoofconstructor (naam, leeftijd, hobby, lidStatus) van de bovenstaande Lid-klasse is, alleen door naar deze te kijken.


Bovendien kan er met één handtekening maar één constructor worden gemaakt, terwijl een statische fabrieksmethode een naam kan hebben, waardoor er met één handtekening meerdere statische fabrieksmethoden kunnen worden gemaakt om instanties te retourneren.


public class Lid {

    private String naam;

    private int leeftijd;

    private String hobby;

    private LidStatus lidStatus;

    public Lid(String naam, int leeftijd, String hobby, LidStatus lidStatus) {
        this.naam = naam;
        this.leeftijd = leeftijd;
        this.hobby = hobby;
        this.lidStatus = lidStatus;
    }

    public static Lid basislid(String naam, int leeftijd, String hobby) {
        return new Lid(naam, leeftijd, hobby, LidStatus.BASIS);
    }

    public static Lid intermediairLid(String naam, int leeftijd, String hobby) {
        return new Lid(naam, leeftijd, hobby, LidStatus.INTERMEDIAIR);
    }

    public static Lid gevorderdLid(String naam, int leeftijd, String hobby) {
        return new Lid(naam, leeftijd, hobby, LidStatus.GEVORDERD);
    }


In plaats van LidStatus te onderscheiden met een constructor zoals hierboven, kunnen er meerdere statische fabrieksmethoden worden gemaakt met dezelfde handtekening, zodat gebruikers een lid-instantie kunnen maken met een bepaalde vaardigheid zonder enige verwarring.

Laten we de in de JDK gedefinieerde bibliotheek eens bekijken. Er bestaat een statische fabrieksmethode probablePrime() voor BigInteger.


public static BigInteger probablePrime(int bitLengte, Random rnd) {
    if (bitLengte < 2)
        throw new ArithmeticException("bitLengte < 2");

    return (bitLengte < SMALL_PRIME_THRESHOLD ?
            smallPrime(bitLengte, DEFAULT_PRIME_CERTAINTY, rnd) :
            largePrime(bitLengte, DEFAULT_PRIME_CERTAINTY, rnd));


Als we de BigInteger probablePrime()-methode vergelijken met de algemene constructor van BigInteger, is het laatste waarschijnlijk duidelijker, omdat het expliciet stelt: "Dit keert een BigInteger-instantie terug die een priemgetal is".


Het is niet nodig om telkens een nieuwe instantie te maken wanneer deze wordt aangeroepen.

public static Boolean valueOf(boolean b) {
    return (b ? Boolean.TRUE : Boolean.FALSE);


We kunnen zien dat de valueOf()-methode van Boolean vooraf gecachete instanties retourneert. Deze functie kan de prestaties aanzienlijk verbeteren in situaties waar er vaak om objecten met hoge productiekosten wordt gevraagd, Flyweight-patroonkan ook als een vergelijkbaar mechanisme worden beschouwd.


Klassen die statische fabrieksmethoden gebruiken om hetzelfde object voor herhaalde verzoeken te retourneren, worden instantiebeheerklassen genoemd, omdat ze de levenscyclus van instanties kunnen beheren. Door instanties te beheren kunnen singletonklassen worden gemaakt of kunnen klassen worden gemaakt die geen instanties kunnen instantiëren. Bovendien kan in onveranderlijke waardeclasses worden gegarandeerd dat er maar één instantie is.

Instantiebeheer is het hart van het Flyweight-patroon en opsommingen garanderen dat slechts één instantie wordt gemaakt.


Voorbeeld

In Minecraft moeten bomen worden geplant. Als er voor elke boom een ​​nieuw object wordt gemaakt, kan dat leiden tot overloop van het geheugen.

Daarom kunnen bomen met rode en groene bladeren worden opgeslagen en alleen de posities worden gewijzigd, waarna ze worden geretourneerd. Natuurlijk kunnen bomen, behalve de twee genoemde kleuren, in aantal toenemen, dus het zou efficiënt zijn om de bomen op te slaan in een datastructuur zoals een map, gesorteerd op kleur.


public class Boom {

    // Een boom heeft 3 verschillende eigenschappen.
    private String kleur;
    private int x;
    private int y;

    // Er wordt alleen een constructor met kleur gemaakt.
    public Boom(String kleur) {
        this.kleur = kleur;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    // Wanneer je een boom plant.
    public void installeer(){
        System.out.println("X:"+x+" Y:"+y+" Boom met "+kleur+" kleur geïnstalleerd!");
    }
}

public class BoomFabriek {
    // Bomen worden beheerd met behulp van de HashMap-datastructuur.
    public static final Map boomMap = new HashMap<>();
    
   
    public static Boom getBoom(String boomKleur){
        // Controleer eerst in de map of er een boom met de opgegeven kleur is. Als die er is, geef dan dat object.
        Boom boom = (Boom)boomMap.get(boomKleur); 

       // Als er nog geen boom met die kleur in de map is, maak dan een nieuwe aan en geef hem terug.
        if(boom == null){
            boom = new Boom(boomKleur);
            boomMap.put(boomKleur, boom);
            System.out.println("Nieuw object gemaakt");
        }

        return boom;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("Voer de gewenste kleur in :)");
        for(int i=0;i<10;i++){
            // Boomkleur ophalen
            String invoer = scanner.nextLine();
            // Eén boom opvragen bij de fabriek
            Boom boom = (Boom)BoomFabriek.getBoom(invoer);
            // Stel x,y op de boom in
            boom.setX((int) (Math.random()*100));
            boom.setY((int) (Math.random()*100));
            // Boom installeren
            boom.installeer();
        }
    }


Verschil met het singleton-patroon

Het singleton-patroon staat slechts één boom toe in de boomklasse. Daarom, wanneer we het singleton-patroon zouden gebruiken, zou de kleur van het ene object dat wordt gemaakt moeten worden gewijzigd. In wezen kan het singleton-patroon er maar één van elk type hebben, ongeacht het type.


Gebruik

Het String Constant Pool in Java gebruikt het Flyweight-patroon.


Kan subtypen van het retourtype retourneren.

Als je de asList()-methode van de Arrays utility-klasse hebt gebruikt, begrijp je dit voordeel misschien al.


public static  List asList(T... a) [
    return new ArrayList<>(a);


Deze methoden geven een waarde terug die is ingepakt als een ArrayList die een subtype is van List en gebruikers hoeven niet op de hoogte te zijn van deze implementatie. Dat wil zeggen, het geeft je de flexibiliteit om de klasse van het geretourneerde object vrij te kiezen, waardoor API's klein kunnen worden gehouden door implementaties niet openbaar te hoeven maken.


Over gerelateerde discussies over statische methoden van Java-interfaces.

Voor Java 8 was het niet mogelijk om statische methoden te declareren in interfaces, dus als er een statische fabrieksmethode nodig was die een interface of type "Type" retourneerde, werd er een begeleidende klasse Type gemaakt die geen instanties kon maken met de methode erin gedefinieerd.


Een typerend voorbeeld is dat er 45 hulpprogramma-implementaties zijn geleverd door het JCF, en de implementaties van de meesten worden verkregen van de ene begeleidende klasse, java.util.Collections, via statische fabrieksmethoden. In het bijzonder zijn er implementaties die niet openbaar zijn, dus ze kunnen alleen via statische fabrieksmethoden worden gemaakt. (Deze implementaties kunnen uiteraard niet worden geërfd.)


Bovendien werden de 45 implementaties niet openbaar gemaakt, waardoor de API veel kleiner kon worden gehouden.


// Voorbeeld van interface en begeleidende klasse.


Sinds Java 8 is het mogelijk om statische methoden direct aan interfaces toe te voegen, dus het is niet nodig om een ​​begeleidende klasse afzonderlijk te definiëren.


Kan afhankelijk van de invoerparameters objecten van verschillende klassen retourneren.

Ver voorbij het eenvoudig retourneren van een subtype, kan de methode verschillende subtypes retourneren afhankelijk van de waarde van de parameter. Als je bijvoorbeeld LidStatus wilt retourneren op basis van hun score, kun je, zoals hieronder te zien is, een statische fabrieksmethode maken met daarin logica voor vergelijking.


public enum LidStatus {

    Gevorderd(80, 100),
    Intermediair(50, 79),
    Basis(0, 49);

    private final int minScore;
    private final int maxScore;

    LidStatus(int minScore, int maxScore) {
        this.minScore = minScore;
        this.maxScore = maxScore;
    }

    public static LidStatus of(int score) {
        return Arrays.stream(values())
                .filter(decideMemberStatus(score))
                .findAny()
                .orElseThrow(() -> new NoSuchElementException("Er bestaat geen overeenkomend LidStatus-object."));
    }

    private static Predicate decideMemberStatus(int score) {
        return element -> element.minScore <= score && element.maxScore >= score;
    }
}

@DisplayName("LidStatus-test")
class LidStatusTest {

    @ParameterizedTest
    @CsvSource(value = {"0:Basis", "30:Basis", "50:Intermediair", "70:Intermediair", "80:Gevorderd", "100:Gevorderd"}, delimiter = ':')
    @DisplayName("Retourneert LidStatus op basis van score.")
    void of(int invoer, LidStatus verwacht) {
        assertThat(LidStatus.of(invoer)).isEqualTo(verwacht);
    }


Op het moment dat de statische fabrieksmethode wordt geschreven, hoeft de geretourneerde objectklasse nog niet te bestaan.

In de bovenstaande zin, objectklasseis het klassebestand dat we schrijven.

Ter referentie: Class is de Class-object dat de klasselader toewijst aan het heap-gebied wanneer het de klasse laadt. Dit Class-object bevat diverse metadata over de klasse die we hebben geschreven.


package algorithm.dataStructure;

public abstract class StaticFactoryMethodType {

    public abstract void getName();

    public static StaticFactoryMethodType getNewInstance() {
        StaticFactoryMethodType temp = null;
        try {
            Class childClass = Class.forName("algorithm.dataStructure.StaticFactoryMethodTypeChild"); // Reflectie
            temp = (StaticFactoryMethodType) childClass.newInstance(); // Reflectie

        } catch (ClassNotFoundException e) {
           System.out.println("Klasse bestaat niet.");
        } catch (InstantiationException  e) {
            System.out.println("Het kan niet naar het geheugen worden geladen.");
        } catch (IllegalAccessException  e) {
            System.out.println("Toegangsfout voor klassenbestand.");
        }

        return temp;
    }


Als we in de bovenstaande code kijken, kunnen we zien dat aan de hand van de locatie van de implementatie van de interface een Class-object wordt gemaakt en dat het daadwerkelijk geimplementeerde object wordt geïnitialiseerd met behulp van reflectietechnieken. In dit geval, op het moment dat de statische fabrieksmethode wordt geschrevenhoeft de StaticFactoryMethodTypeChild-klasse niet te bestaan.


Als het pad naar de implementatie algorithm.dataStructure.StaticFactoryMethodTypeChild op het moment dat de statische fabrieksmethode wordt gebruikt niet bestaat, zal er een fout optreden, maar op het moment dat de statische fabrieksmethode wordt geschreven is dit geen probleem, dus wordt gezegd dat het flexibel is.


public interface Test {

    int Som(int a, int b);

    // Hoewel Test een interface is en er geen implementatie is, is er geen probleem
    // tijdens het schrijven van statische fabrieksmethoden.
    static Test create() {
        return null;
    }
}

public class Main {

    public static void main(String[] args) {
        Test test = Test.create();
        System.out.println(test.som(1, 2)); // NPE treedt op
    }


Zelfs zonder reflectie te gebruiken, is het mogelijk om dezelfde mate van flexibiliteit te krijgen. In de create()-methode van de statische fabrieksmethode Test kan er geen implementatie zijn van de interface, maar dit is geen probleem op het moment van schrijven. De NPE treedt natuurlijk op tijdens daadwerkelijke gebruik, dus je moet later een implementatieobject retourneren.


Deze flexibiliteit is de basis van serviceframeworkleveranciers. Typische JDBC is hier een van. Het JDBC service framework leverancier is de implementatie van de service, en het framework heeft de taak om deze implementaties aan de cliënten ter beschikking te stellen en de cliënten te isoleren van de implementaties. (DIP)


Componenten van serviceframeworkleveranciers

  • Leverancier interface
    • Definiërt servicegedrag
    • JDBC Connection-klasse
  • Leveranciersregistratie-API
    • De leverancier registreert de implementatie
    • JDBC's DriverManager.registerDriver()
  • Servicetoegang-API
    • Wordt gebruikt door een cliënt om een ​​service-instantie te verkrijgen, en als er geen voorwaarde is opgegeven, retourneert hij een standaard- of ondersteunde implementatie.
    • Overeenkomend met de statische fabrieksmethode van de klasse.
    • JDBC's DriverManager.getConnection()
  • Optionele serviceproviderinterface
    • Als deze niet beschikbaar is, moeten reflecties worden gebruikt bij het instantiëren van elke implementatie.
    • JDBC Driver-interface


Het patroon van serviceleveranciers heeft vele varianten, waaronder het adapterpatroon en het dependency injection framework.


Typisch JDBC-voorbeeld.

Class.forName("oracle.jdbc.driver.OracleDriver"); 
Connection connection = null; 
connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORA92", "root", "root"); 


Over het algemeen wordt JDBC zoals hierboven geschreven. Class.forName() wordt gebruikt om OracleDriver, een van de implementaties van Driver, te registreren, en DriverManager.getConnection() wordt gebruikt om Connection, een van de implementaties van Connection, met OracleDriver te verkrijgen.


Hier kunnen we zien dat Connection de service-interface is, DriverManager.getConnection() de servicetoegang-API, en Driver de serviceproviderinterface. Echter, DriverManager.registerDriver(), de leveranciersregistratie-API, werd niet gebruikt. Toch kunnen we Driver-implementaties zoals OracleDriver registreren met alleen Class.forName(). hoe is dit mogelijk ?


Het mechanisme van Class.forName().

Deze methode vraagt ​​de JVM om de gegeven klasse te laden door de volledige naam van het klassebestand als argument door te geven. Dit zal de klassenlader ertoe aanzetten om de metagegevens van de klasse op te slaan in het methodengebied en parallel daaraan een Class-object toe te wijzen aan het heapgebied. Bovendien, wanneer het klasseladen is voltooid, worden statische velden en statische blokken geïnitialiseerd, en dit is waar de providerregistratie-API wordt gebruikt.


public class OracleDriver implements Driver {

    static {
        defaultDriver = null;
        Timestamp timestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
        try {
            if (defaultDriver == null) {
                defaultDriver = new OracleDriver();
                DriverManager.registerDriver(defaultDriver); // OracleDriver registreren
            }
        } catch (RuntimeException runtimeexception) {
        } catch (SQLException sqlexception) {
        }
    }

    ...


Als we naar de OracleDriver-klasse kijken, kunnen we zien dat de DriverManager.registerDriver()-methode wordt gebruikt in een statisch blok om de Driver-implementatie OracleDriver te registreren.


Analyse van de DriverManager-klasse.

public class DriverManager {

    private DriverManager() {
    }

    private static final Map drivers = new ConcurrentHashMap();
    public static final String DEFAULT_DRIVER_NAME = "default";

    public static void registerDefaultPrivider(Driver d) {
        System.out.println("Driver registreren");
        registerDriver(DEFAULT_DRIVER_NAME, d);
    }

    public static void registerDriver(String name, Driver d) {
        drivers.put(name, d);
    }

    public static Connection getConnection() {
        return getConnection(DEFAULT_DRIVER_NAME);
    }

    public static Connection getConnection(String name) {
        Driver d = drivers.get(name);
        if (d == null) throw new IllegalArgumentException();
        return d.getConnection();
    }


De DriverManager-klasse is in feite veel complexer, maar vereenvoudigd tot de kern lijkt hij op de bovenstaande. Zoals hierboven uitgelegd, wordt er een Driver geregistreerd door registerDriver() in het statische blok van OracleDriver aan te roepen, en kan de gebruiker Connection-implementaties ophalen door getConnection() aan te roepen.


Als we de getConnection()-methode van de API voor toegang tot gebruikers nader bekijken, kunnen we zien dat Connection wordt verkregen van de Driver-interface. Als er geen Driver-serviceproviderinterface zou zijn, zou reflectie zoals Class.forName() kunnen worden gebruikt om de gewenste Connection-implementatie te retourneren. Hiermee de Connection-implementatie hoeft op het moment dat de statische fabrieksmethode wordt geschreven nog niet te bestaan.


In plaats daarvan gebruiken we de Driver-interface en kunnen we, na dynamische registratie van de Driver-implementatie, eenvoudig de juiste Connection-implementatie verkrijgen.


Voor uw referentie, ik heb geprobeerd de werkelijke JDK-code voor de getConnection()-methode van DriverManager te analyseren, maar u kunt deze desgewenst overslaan.


@CallerSensitive
public static Connection getConnection(String url,
    String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();

    if (user != null) {
        info.put("user", user);
    }
    if (password != null) {
        info.put("password", password);
    }

    return (getConnection(url, info, Reflection.getCallerClass()));


Eerst wordt de openbare statische methode getConnection() aangeroepen en worden url, Properties en CallerClass doorgegeven als argumenten voor de private statische methode getConnection(). De methode Reflection.getCallerClass() wordt hierbij gebruikt om de door de beller van deze openbare statische methode getConnection() aangeroepen klasse op te halen. Als de Car-klasse getConnection() aanriep, zou een Class-object worden verkregen met behulp van Reflection.getCallerClass().


private static Connection getConnection(String url, java.util.Properties info, Class caller) throws SQLException {
    ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
    synchronized(DriverManager.class) {
        if (callerCL == null) {
            callerCL = Thread.currentThread().getContextClassLoader();
        }
    }

    if(url == null) {
        throw new SQLException("URL mag niet leeg zijn", "08001");
    }

    SQLException reason = null;
    for(DriverInfo aDriver : registeredDrivers) {
        if(isDriverAllowed(aDriver.driver, callerCL)) {
            try {
                Connection con = aDriver.driver.connect(url, info);
                if (con != null) {
                    return (con);
                }
            } catch (SQLException ex) {
                if (reason == null) {
                    reason = ex;
                }
            }
        }
    }

    if (reason != null)    {
        throw reason;
    }
    throw new SQLException("Geen geschikte driver voor "+ url, "08001");


callerCL is het object van de klassenlader en wordt gemaakt door caller of de huidige thread klassenlader. Hierna worden de aDriver één voor één opgehaald uit registeredDrivers, de lijst met geregistreerde drivers van deze applicatie. Vervolgens wordt gecontroleerd of aDriver aanwezig is in caller, wat gedaan wordt door isDriverAllowed().


Voordelen van JDBC-frameworks.

Het belangrijkste punt van het JDBC-framework is dat de Driver, Connection-interface en de daadwerkelijke implementatieklassen die die interfaces implementeren volledig gescheiden zijn en worden geleverd. Omdat er een sjabloon is gemaakt met interfaces en er implementatieclasses zijn gemaakt die bij dat sjabloon passen, is het zeer flexibel.


Daarom kunnen, zelfs als er een ander DBMS verschijnt, de leveranciers van dat DBMS een Driver en een Connection-interface implementeren en leveren die de Java-ontwikkelaars kunnen gebruiken om met die andere DBMS-driver te werken, net als met andere JDBC-drivers.


Nadelen van de statische fabrieksmethode

Omdat er een publieke of beschermde constructor nodig is bij het overerven, kan een statische fabrieksmethode alleen worden gebruikt als er geen subklassen kunnen worden gemaakt.


Deze beperking bevordert echter compositie boven overerving en kan zelfs een voordeel zijn, omdat u onveranderlijke typen kunt maken die deze beperking afdwingen.


Statische fabrieksmethoden zijn moeilijk te vinden voor programmeurs.

Omdat ze niet expliciet worden vermeld in API-documentatie, moeten ontwikkelaars ervoor zorgen dat ze goede API-documentatie schrijven en methodenamen bedenken die bekende conventies volgen.


Naamgevingsconventies voor statische fabrieksmethoden

  • van
    • Retourneert een instantie van het juiste type door één parameter te ontvangen.
    • Date date = Date.from(instant);
  • van
    • Retourneert een instantie van het juiste type door meerdere parameters te ontvangen.
    • Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
  • valueOf
    • Een meer gedetailleerde versie van from en of.
    • BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
  • instance of getInstance
    • Retourneert een instantie die is gespecificeerd als parameter, maar garandeert niet dat het dezelfde instantie is.
    • StackWalker luke = StackWalker.getInstance(options);
  • create of newInstance
    • Net als instance of getInstance, maar garandeert dat er telkens een nieuwe instantie wordt gemaakt en geretourneerd.
    • Object newArray = Array.newInstance(classObject, arraylen);
  • type
    • Hetzelfde als getInstance, maar definieer de fabrieksmethode in een andere klasse dan de te creëren klasse.
    • FileStore fs = Files.getFileStore(path);
  • newType
    • Hetzelfde als newInstance, maar definieer de fabrieksmethode in een andere klasse dan de te creëren klasse.
    • BufferedReader br = Files.newBufferedReader(path);
  • type
    • Een beknopte versie van getType en newType.
    • List<Complaint> litany = Collections.list(legacyLitany);


Samenvatting

Statische fabrieksmethoden en publieke constructors hebben elk hun toepassingen, dus gebruik ze dienovereenkomstig.


Bron

제이온
제이온
제이온
제이온
[Effectieve Java] Item 4. Gebruik een private constructor om instantiatie te voorkomen Voor utility-klassen die alleen statische methoden en velden bevatten, is het een goed idee om de toegangsmodifier van de constructor op 'private' te zetten om instantiatie te voorkomen. Dit voorkomt dat gebruikers de constructor verwarren met een automat

28 april 2024

[Spring] Wat zijn Filter, Interceptor en Argument Resolver? Leer meer over de concepten en verschillen van filters, interceptors en argument resolvers in Spring-webtoepassingen. We bespreken hoe elk van deze functies wordt geïmplementeerd, wanneer ze worden gebruikt, hun voor- en nadelen en een vergelijking van de

27 april 2024

[Effectieve Java] Item 5. Gebruik afhankelijke objectinjectie in plaats van resources expliciet te noemen Wanneer een klasse afhankelijk is van externe resources, is het gebruik van singletons en statische utility-klassen af te raden. Door afhankelijke objectinjectie te gebruiken, kunt u de flexibiliteit, herbruikbaarheid en testbaarheid van de klasse verbete

28 april 2024

[Javascript] Object-structuur (V8) Het JavaScript Object wordt in de V8-engine geoptimaliseerd als een structuur afhankelijk van de toestand en werkt als een Fast-modus en een Dictionary-modus die als een hashmap werkt. De Fast-modus is snel met keys en waarden in een bijna vaste vorm, maa
곽경직
곽경직
곽경직
곽경직
곽경직

18 maart 2024

[Niet-major, overleven als ontwikkelaar] 14. Samenvatting van veelgestelde technische interviewvragen voor beginnende ontwikkelaars Deze gids is bedoeld om beginnende ontwikkelaars te helpen met de voorbereiding op technische interviews. Het behandelt concepten die vaak ter sprake komen tijdens interviews, zoals het hoofdgeheugengebied, gegevensstructuren, RDBMS en NoSQL, procedurele
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 april 2024

Conceptueel gegevensmodellering Conceptueel gegevensmodellering is het proces van het scheiden van entiteiten en het uitdrukken van relaties tussen entiteiten in een ERD. Entiteiten zijn onafhankelijke informatie-eenheden, en attributen zijn de gegevens die een entiteit bezit. Identific
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

8 april 2024

Logisch gegevensmodelleren Logisch gegevensmodelleren is het proces van het transformeren van een conceptueel gegevensmodel naar het relationele databaseparadigma, waarbij 1:1, 1:N en N:M relaties worden verwerkt en normalisatie wordt gebruikt om gegevensintegriteit te waarborgen.
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

9 april 2024

[Niet-technische, ontwikkelen voor een levensonderhoud] 16. Tips voor het maken van een portfolio voor beginnende ontwikkelaars Beginnende ontwikkelaars (met name niet-technische) moeten bij het maken van een portfolio niet alleen hun vaardigheden, maar ook de ontwikkelde diensten of functies duidelijk beschrijven. Bijvoorbeeld, voor een "baanzoekersgemeenschap" project, moet je c
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 april 2024

[Metaalmaterialen Master Craftsman Praktijk] 35e oplossing Dit document beschrijft verschillende termen en concepten met betrekking tot metaalmaterialen, zoals microscopische structurele analyse van metaalmaterialen, bepalen van de korrelgrootte van ferriet, de pakkingsdichtheid van BCC, enz. Het behandelt ook pr
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi

23 april 2024