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

นี่คือโพสต์ที่แปลด้วย AI

제이온

ปล่อยให้เราค้นหาสภาพอากาศของวันนี้

เลือกภาษา

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

สรุปโดย AI ของ durumis

  • ปล่อยให้เราค้นหาสภาพอากาศของวันนี้
  • เป็นสภาพอากาศที่แจ่มใส
  • คุณสามารถค้นหาสภาพอากาศได้

บทนำ

วิธีการดั้งเดิมในการรับอินสแตนซ์ของคลาสคือคอนสตรัคเตอร์แบบ public


public class Member {

    private String name;

    private int age;

    private String hobby;

    private MemberStatus memberStatus;

    public Member(String name, int age, String hobby, MemberStatus memberStatus) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
        this.memberStatus = memberStatus;
    }
}

public enum MemberStatus {

    ADVANCED,
    INTERMEDIATE,
    BASIC;


แม้ว่าโดยทั่วไปแล้วคอนสตรัคเตอร์แบบ public จะเพียงพอแล้ว แต่บ่อยครั้งที่การมีเมธอดแบบคงที่ (static factory method) นอกเหนือจากคอนสตรัคเตอร์สามารถทำให้ผู้ใช้สร้างอินสแตนซ์ได้ง่ายขึ้นตามที่ตั้งใจไว้


ตัวอย่างทั่วไปของวิธีการสร้างแบบคงที่คือวิธี valueOf() ของ Boolean


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


เมธอดด้านบนรับค่า boolean เป็นค่าอินพุตและส่งคืนเป็นวัตถุ Boolean


ข้อดีของวิธีการสร้างแบบคงที่

สามารถมีชื่อได้

ตามพารามิเตอร์และคอนสตรัคเตอร์เองไม่สามารถอธิบายลักษณะของวัตถุที่จะส่งคืนได้อย่างเพียงพอ ตัวอย่างเช่น จากคอนสตรัคเตอร์หลัก (name, age, hobby, memberStatus) ของคลาส Member ข้างต้น คุณไม่สามารถบอกได้ว่าสมาชิกมีลักษณะอย่างไร


นอกจากนี้ สำหรับลายเซ็นเดียว คุณสามารถสร้างคอนสตรัคเตอร์ได้เพียงหนึ่งแบบเท่านั้น ในขณะที่เมธอดแบบคงที่สามารถมีชื่อได้ ดังนั้นคุณจึงสามารถสร้างเมธอดแบบคงที่หลายรายการสำหรับลายเซ็นเดียวเพื่อส่งคืนอินสแตนซ์


public class Member {

    private String name;

    private int age;

    private String hobby;

    private MemberStatus memberStatus;

    public Member(String name, int age, String hobby, MemberStatus memberStatus) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
        this.memberStatus = memberStatus;
    }

    public static Member basicMember(String name, int age, String hobby) {
        return new Member(name, age, hobby, MemberStatus.BASIC);
    }

    public static Member intermediateMember(String name, int age, String hobby) {
        return new Member(name, age, hobby, MemberStatus.INTERMEDIATE);
    }

    public static Member advancedMember(String name, int age, String hobby) {
        return new Member(name, age, hobby, MemberStatus.ADVANCED);
    }


การสร้างเมธอดแบบคงที่หลายรายการสำหรับลายเซ็นเดียวกันที่มีการแยกความแตกต่างโดย MemberStatus นั้นดีกว่าการสร้างคอนสตรัคเตอร์หลักเพียงรายการเดียว ในกรณีนี้ ผู้ใช้สามารถสร้างอินสแตนซ์สมาชิกที่มีทักษะเฉพาะได้โดยไม่ต้องสับสน

พิจารณาไลบรารีที่กำหนดไว้ใน JDK มีวิธีการแบบคงที่ probablePrime() ของ BigInteger


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

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


หากเปรียบเทียบเมธอดแบบคงที่ probablePrime() กับคอนสตรัคเตอร์ทั่วไปของ BigInteger ค่าหลังจะมีประโยชน์มากกว่ามาก เมื่อคุณกำลังมองหาวัตถุ BigIntegerที่มีค่าเป็นจำนวนเฉพาะ


ไม่จำเป็นต้องสร้างอินสแตนซ์ใหม่ทุกครั้งที่มีการเรียกใช้

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


เมธอด valueOf() ของ Boolean แสดงให้เห็นว่าอินสแตนซ์ถูกแคชไว้ล่วงหน้าและส่งคืน พฤติกรรมนี้อาจเพิ่มประสิทธิภาพได้อย่างมาก ในสถานการณ์ที่ต้นทุนการสร้างสูงและวัตถุมีการร้องขอบ่อย flyweight patternคล้ายกับเทคนิคนี้


คลาสที่ใช้รูปแบบเมธอดแบบคงที่เพื่อส่งคืนอินสแตนซ์เดียวกันสำหรับการร้องขอที่ซ้ำกัน เรียกว่าคลาสควบคุมอินสแตนซ์ ด้วยการควบคุมอินสแตนซ์ คุณสามารถสร้างคลาสซิงเกิลตันหรือคลาสที่ไม่สามารถแปลงเป็นอินสแตนซ์ได้ นอกจากนี้ คุณยังสามารถรับประกันได้ว่ามีอินสแตนซ์คงที่เดียวในคลาสค่าคงที่

การควบคุมอินสแตนซ์เป็นพื้นฐานสำคัญของรูปแบบ flyweight และชนิดการแจกแจงรับประกันว่าอินสแตนซ์มีอยู่เพียงตัวเดียว


ตัวอย่าง

ใน Minecraft คุณต้องปลูกต้นไม้ หากคุณสร้างวัตถุทรีใหม่ทุกครั้ง จะนำไปสู่หน่วยความจำล้น

ดังนั้น คุณควรบันทึกต้นไม้ชนิดต่างๆ (ต้นไม้สีแดงและต้นไม้สีเขียว) ไว้ แล้วเปลี่ยนแปลงเฉพาะตำแหน่งเท่านั้น แน่นอน สีอาจมีมากกว่าสองสี ดังนั้น หากคุณเก็บต้นไม้ไว้ในโครงสร้างข้อมูล เช่นMap คุณจะทำได้อย่างมีประสิทธิภาพ


public class Tree {

    // ต้นไม้มีข้อมูลสามอย่างดังนี้
    private String color;
    private int x;
    private int y;

    // สร้างตัวสร้างด้วยสีเท่านั้น
    public Tree(String color) {
        this.color = color;
    }

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

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

    // ที่ปลูกต้นไม้
    public void install(){
        System.out.println("ได้ปลูกต้นไม้สี "+color+" ที่ตำแหน่ง x:"+x+" y:"+y+"!");
    }
}

public class TreeFactory {
    // ใช้ออบเจ็กต์แฮชแมปเพื่อจัดการต้นไม้ที่สร้างขึ้น
    public static final Map treeMap = new HashMap<>();
    
   
    public static Tree getTree(String treeColor){
        // ค้นหาต้นไม้สีเดียวกับที่ใส่เข้ามา หากมีอยู่ จะให้วัตถุนั้น
        Tree tree = (Tree)treeMap.get(treeColor); 

       // หากยังไม่มีวัตถุท้นไม้นั้น ให้สร้างวัตถุใหม่
        if(tree == null){
            tree = new Tree(treeColor);
            treeMap.put(treeColor, tree);
            System.out.println("สร้างวัตถุใหม่");
        }

        return tree;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("กรุณาป้อนสีที่คุณต้องการ :)");
        for(int i=0;i<10;i++){
            // อินพุตสีของต้นไม้
            String input = scanner.nextLine();
            // รับต้นไม้หนึ่งต้นจากโรงงาน
            Tree tree = (Tree)TreeFactory.getTree(input);
            // ตั้งค่า x,y ต้นไม้ และ
            tree.setX((int) (Math.random()*100));
            tree.setY((int) (Math.random()*100));
            // ปลูกต้นไม้
            tree.install();
        }
    }


ความแตกต่างจากรูปแบบซิงเกิลตัน

รูปแบบซิงเกิลตันอนุญาตให้คุณสร้างต้นไม้ได้เพียงต้นเดียวในคลาส Tree ดังนั้น หากคุณใช้รูปแบบซิงเกิลตัน คุณต้องเปลี่ยนสีของวัตถุต้นไม้ที่สร้างขึ้น กล่าวคือ รูปแบบซิงเกิลตัน สามารถมีได้เพียงตัวเดียวโดยไม่คำนึงถึงประเภท


กรณีการใช้งาน

รูปแบบ flyweight ใช้ในพูลคงที่ของสตริงของ Java


สามารถส่งคืนวัตถุประเภทย่อยของประเภทส่งคืนได้

หากคุณเคยใช้เมธอด asList() ของคลาสอรรถประโยชน์ Arrays คุณจะเข้าใจข้อดีนี้


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


ส่งคืนค่าที่ห่อหุ้มไว้เป็น ArrayList ซึ่งเป็นคลาสการนำไปใช้จริงของ List ผู้ใช้ไม่จำเป็นต้องรู้แม้กระทั่งการนำไปใช้จริง ผู้ใช้มีอิสระในการเลือกคลาสส่งคืน นั่นคือ ความยืดหยุ่นที่ได้จากการเลือกคลาสส่งคืนโดยอิสระ ช่วยให้ผู้พัฒนาสามารถทำให้ API มีขนาดเล็กลงโดยไม่เปิดเผยการใช้งาน


เกี่ยวกับเรื่องของเมธอดคงที่ของอินเทอร์เฟซ Java

ก่อน Java 8 ไม่มีวิธีการประกาศเมธอดคงที่ในอินเทอร์เฟซ ดังนั้น หากคุณต้องการเมธอดคงที่ที่จะส่งคืนอินเทอร์เฟซที่มีชื่อ“Type” คุณต้องสร้างคลาสคู่หูที่ไม่สามารถสร้างอินสแตนซ์ได้ซึ่งมีวิธีการภายใน


ตัวอย่างทั่วไปคือ 45 คลาสการใช้งานยูทิลิตี้ที่ JCF จัดไว้ โดยคลาสการใช้งานเหล่านี้ส่วนใหญ่ได้รับการประกาศว่าเป็นเมธอดคงที่จากคลาสคู่หูเพียงตัวเดียว java.util.Collectionsโดยเฉพาะ อย่างยิ่ง ในคลาสการใช้งานเหล่านี้ มีบางคลาสที่ไม่ใช่แบบสาธารณะ กล่าวคือ มีเพียงเมธอดคงที่เท่านั้นที่สามารถสร้างอินสแตนซ์ได้ (คลาสการใช้งานนี้ไม่สามารถสืบทอดได้อย่างชัดเจน)


นอกจากนี้ เนื่องจากไม่ได้เผยแพร่คลาสการใช้งาน 45 คลาส API จึงมีขนาดเล็กลงมากมาย


// ตัวอย่างของอินเทอร์เฟซและคลาสคู่หู


อย่างไรก็ตาม ตั้งแต่ Java 8 อินเทอร์เฟซมีเมธอดคงที่โดยตรง ดังนั้น คุณจึงไม่จำเป็นต้องกำหนดคลาสคู่หูแยกต่างหาก


สามารถส่งคืนประเภทคลาссыย่อยต่างกันตามพารามิเตอร์อินพุต

ยิ่งไปกว่านั้น นอกเหนือจากการส่งคืนประเภทย่อย การเปรียบเทียบกับค่าพารามิเตอร์สามารถใช้เพื่อส่งคืนประเภทย่อยอื่นได้ ตัวอย่างเช่น หากคุณต้องการส่งคืน MemberStatus ต่างกันตามคะแนน คุณสามารถสร้างเมธอดแบบคงที่ด้านล่างและสร้างตรรกะการเปรียบเทียบภายใน


public enum MemberStatus {

    ADVANCED(80, 100),
    INTERMEDIATE(50, 79),
    BASIC(0, 49);

    private final int minScore;
    private final int maxScore;

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

    public static MemberStatus of(int score) {
        return Arrays.stream(values())
                .filter(decideMemberStatus(score))
                .findAny()
                .orElseThrow(() -> new NoSuchElementException("ไม่พบวัตถุ MemberStatus ที่สอดคล้องกัน"));
    }

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

@DisplayName("การทดสอบ MemberStatus")
class MemberStatusTest {

    @ParameterizedTest
    @CsvSource(value = {"0:BASIC", "30:BASIC", "50:INTERMEDIATE", "70:INTERMEDIATE", "80:ADVANCED", "100:ADVANCED"}, delimiter = ':')
    @DisplayName("ส่งคืน MemberStatus ต่างกันตามคะแนน")
    void of(int input, MemberStatus expected) {
        assertThat(MemberStatus.of(input)).isEqualTo(expected);
    }


ขณะสร้างเมธอดแบบคงที่ ไม่จำเป็นต้องมีคลาสของวัตถุที่จะส่งคืน

ในประโยคข้างต้น คลาสของวัตถุคือไฟล์คลาสที่เราสร้าง

โปรดทราบว่า Class หมายถึงวัตถุ Class ที่โหลดเดอร์คลาสจัดสรรให้กับฮีปเมื่อโหลดคลาส วัตถุ Class นี้มีเมตาข้อมูลต่างๆ ของคลาสที่เราเขียน


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"); // reflection
            temp = (StaticFactoryMethodType) childClass.newInstance(); // reflection

        } catch (ClassNotFoundException e) {
           System.out.println("ไม่พบไฟล์คลาส");
        } catch (InstantiationException  e) {
            System.out.println("ไม่สามารถโหลดเข้าหน่วยความจำ");
        } catch (IllegalAccessException  e) {
            System.out.println("ไม่สามารถเข้าถึงไฟล์คลาส");
        }

        return temp;
    }


หากคุณลองใช้โค้ดด้านบน จะเห็นได้ว่าอินเทอร์เฟซการใช้งานถูกสร้างขึ้นโดยใช้การสะท้อน และอินสแตนซ์การใช้งานจริงจะถูกเตรียมโดยใช้เทคนิคการสะท้อน ณ จุดนี้ เวลาสร้างเมธอดแบบคงที่ไม่จำเป็นต้องมีคลาส StaticFactoryMethodTypeChild


ถ้าไม่มีคลาสการใช้งานในพาธ algorithm.dataStructure.StaticFactoryMethodTypeChild ในเวลาที่ใช้เมธอดแบบคงที่ ข้อผิดพลาดจะเกิดขึ้น แต่ไม่มีปัญหา ในขณะที่สร้างเมธอดแบบคงที่ นั่นคือ เหตุผลที่เราบอกว่ามีความยืดหยุ่น


public interface Test {

    int sum(int a, int b);

    // Test เป็นอินเทอร์เฟซ และสร้างเมธอดแบบคงที่แม้ว่าคลาสการใช้งานจะไม่มีก็ตาม
    static Test create() {
        return null;
    }
}

public class Main {

    public static void main(String[] args) {
        Test test = Test.create();
        System.out.println(test.sum(1, 2)); // NPE เกิดขึ้น
    }


แม้ว่าคุณจะไม่ใช้การสะท้อน แต่คุณก็สามารถรับความยืดหยุ่นแบบเดียวกันได้ หากคุณลองดูที่ create() เมธอดแบบคงที่ของ Test จะเห็นว่าไม่มี คลาสการใช้งาน แต่ไม่มีปัญหาในขณะที่เขียน แน่นอน NPE จะเกิดขึ้นในเวลาจริง ดังนั้น คุณต้องส่งคืนคลาสการใช้งานในภายหลัง


ความยืดหยุ่นนี้เป็นรากฐานสำคัญของการสร้างเฟรมเวิร์กผู้ให้บริการ และตัวอย่างทั่วไปคือ JDBC เฟรมเวิร์กผู้ให้บริการ JDBC เป็นผู้ให้บริการและไคลเอ็นต์มีหน้าที่รับผิดชอบในการควบคุมการเข้าถึงบริการ (Dependency Inversion Principle)


  • องค์ประกอบของเฟรมเวิร์กผู้ให้บริการ
    • อินเทอร์เฟซเซอร์วิส
      • กำหนดพฤติกรรมของคลาสการใช้งาน
      • JDBC Connection
    • API การลงทะเบียนผู้ให้บริการ
      • ผู้ให้บริการลงทะเบียนคลาสการใช้งาน
      • JDBC DriverManager.registerDriver()
    • API การเข้าถึงบริการ
      • ไคลเอ็นต์ใช้เมื่อต้องการได้รับอินสแตนซ์ของบริการ และคลาสการใช้งานเริ่มต้น หรือคลาสการใช้งานที่รองรับจะถูกส่งคืนแบบวนซ้ำหากไม่มีระบุเงื่อนไข
      • สอดคล้องกับเมธอดแบบคงที่
      • JDBC DriverManager.getConnection()
    • (ตัวเลือก) อินเทอร์เฟซผู้ให้บริการ
      • หากไม่มีอินเทอร์เฟซนี้ คุณต้องใช้การสะท้อนเพื่อสร้างอินสแตนซ์ของแต่ละคลาสการใช้งาน
      • JDBC Driver


เฟรมเวิร์กผู้ให้บริการมีตัวแปรหลายตัว และมีรูปแบบบริดจ์ และเฟรมเวิร์กการพึ่งพา


ตัวอย่าง JDBC ทั่วไป

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


โดยทั่วไปแล้ว JDBC ถูกเขียนดังนี้ โดยลงทะเบียน OracleDriver ซึ่งเป็นหนึ่งในคลาสการใช้งานของ Driver ผ่าน Class.forName() และรับ อินสแตนซ์ OracleDriver เป็นหนึ่งในคลาสการใช้งานของ Connection ผ่าน DriverManager.getConnection()


ที่นี่ Connection คืออินเทอร์เฟซเซอร์วิส DriverManager.getConnection() คือ API การเข้าถึงเซอร์วิส และ Driver คืออินเทอร์เฟซผู้ให้บริการ อย่างไรก็ตาม API การลงทะเบียนผู้ให้บริการ DriverManager.registerDriver() ไม่ได้ถูกใช้ แม้จะไม่เป็นเช่นนั้น แต่เราสามารถลงทะเบียน OracleDriver ซึ่งเป็นคลาสการใช้งานของ Driverใช้ Class.forName() เท่านั้น เป็นไปได้อย่างไร


กลไกของ Class.forName()

เมธอดนี้จะขอให้ JVM โหลดคลาสนี้โดยการป้อนชื่อไฟล์คลาสทางกายภาพเป็นอาร์กิวเมนต์ จากนั้น ตัวโหลดคลาสจะจัดสรร Class วัตถุในพื้นที่วิธีการในขณะที่บันทึกเมตาข้อมูลของคลาส นอกจากนี้ ในตอนท้ายของการโหลดคลาส ฟิลด์คงที่และบล็อกคงที่จะถูกเตรียมไว้ และที่นี่ API การลงทะเบียนผู้ให้บริการจะถูกเรียกใช้


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
            }
        } catch (RuntimeException runtimeexception) {
        } catch (SQLException sqlexception) {
        }
    }

    ...


ที่จริงแล้ว หากคุณดู OracleDriver คุณจะเห็นว่ามีการลงทะเบียน OracleDriver ซึ่งเป็นคลาสการใช้งานของ Driver โดยใช้ DriverManager.registerDriver() ใน บล็อกคงที่ ดังนั้น ลูกค้าสามารถรับอินสแตนซ์ของคลาสการใช้งานของ Connection ได้โดยใช้ getConnection()


หากคุณดู API การเข้าถึงแบบผู้ใช้ getConnection() อย่างใกล้ชิด คุณจะเห็นว่าใช้วิธีการรับ Connection จากอินเทอร์เฟซ Driver หากไม่มี อินเทอร์เฟซเซอร์วิส Driver คุณสามารถใช้การสะท้อน เช่น Class.forName() เพื่อส่งคืนคลาสการใช้งาน Connection ที่คุณต้องการ ณ จุดนี้ ไม่จำเป็นต้องมีคลาสการใช้งาน Connection ในเวลาที่สร้างเมธอดแบบคงที่


แทนที่จะเป็น เราใช้ Driver interface และสามารถรับอินสแตนซ์ของคลาสการใช้งาน Driver แบบไดนามิก และรับอินสแตนซ์ของคลาสการใช้งาน Connection ที่เหมาะสมได้อย่างง่ายดาย


โปรดสังเกตว่า หากคุณวิเคราะห์โค้ด JDK จริงของเมธอด getConnection() ของ DriverManager คุณอาจข้ามไปได้หากไม่สนใจมาก


@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()));


เมธอด getConnection() สาธารณะคงที่ ถูกเรียกใช้ก่อน จากนั้น url, Properties และ CallerClass จะถูกส่งไปยังเมธอด getConnection() ส่วนตัวคงที่ ในขณะเดียวกัน Reflection.getCallerClass() มีบทบาทในการรับคลาสที่เรียกใช้เมธอด getConnection() สาธารณะคงที่นี้ ตัวอย่างเช่น หากคลาส Car เรียก getConnection() ตัวโหลดคลาสจะรับคลาสวัตถุโดย 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("The url cannot be null", "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("No suitable driver found for "+ url, "08001");


callerCL เป็นวัตถุตัวโหลดคลาส และสร้างขึ้นโดยตัวโหลดคลาสของ caller หรือเธรดปัจจุบัน จากนั้น รายการไดรเวอร์ที่ลงทะเบียนจากแอปพลิเคชันปัจจุบันaDriver จะถูกรวมทีละรายการ ณ จุดนี้ isDriverAllowed() ตรวจสอบว่า aDriver มีอยู่ในการโทรหรือไม่


ข้อดีของเฟรมเวิร์ก JDBC

ประเด็นสำคัญของเฟรมเวิร์ก JDBC คือ อินเทอร์เฟซ Driver อินเทอร์เฟซ Connection และคลาสการใช้งาน ที่ใช้ในการนำอินเทอร์เฟซเหล่านี้ไปใช้นั้นแยกออกจากกันอย่างสมบูรณ์ สามารถสร้างอินเทอร์เฟซโดยใช้เทมเพลต และหากคุณสร้างคลาสการใช้งานตามเทมเพลต นั้น จะมีความยืดหยุ่นสูงมาก


ด้วยเหตุนี้ แม้ว่าจะมี DBMS ตัวอื่นปรากฏขึ้น แต่ผู้ขายสามารถจัดเตรียมไดรเวอร์และอินเทอร์เฟซ Connection เพื่อให้นักพัฒนาที่ใช้ Java สามารถใช้ API ไดรเวอร์ DBMS อื่นในลักษณะเดียวกับ JDBC


ข้อเสียของวิธีการสร้างแบบคงที่

ไม่สามารถสร้างคลาสย่อยได้ เนื่องจากต้องมีคอนสตรัคเตอร์ public หรือ protected เพื่อการสืบทอด


อย่างไรก็ตาม ข้อจำกัดนี้อาจเป็นข้อดีได้ เนื่องจากสนับสนุนการเขียนคลาสแทนการสืบทอด และจำเป็นต้องปฏิบัติตามข้อจำกัดนี้เพื่อสร้างคลาสคงที่


เป็นการยากสำหรับโปรแกรมเมอร์ในการค้นหาวิธีการแบบคงที่

เนื่องจากวิธีการแบบคงที่ไม่ได้อธิบายไว้อย่างชัดเจนในเอกสาร API นักพัฒนาจึงควรเขียนเอกสาร API อย่างดีและปฏิบัติตามอนุสัญญาการตั้งชื่อที่รู้จักกันทั่วไปเพื่อบรรเทาปัญหา


วิธีการตั้งชื่อเมธอดแบบคงที่

  • จาก
    • รับพารามิเตอร์เดียวและส่งคืนอินสแตนซ์ของประเภทนั้น
    • Date date = Date.from(instant);
  • ของ
    • รับหลายพารามิเตอร์และส่งคืนอินสแตนซ์ของประเภทที่เหมาะสม
    • Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
  • valueOf
    • เวอร์ชันที่ละเอียดมากขึ้นของ from และ of
    • BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
  • instance หรือ getInstance
    • ส่งคืนอินสแตนซ์ที่ระบุโดยพารามิเตอร์ แต่ไม่รับประกันว่าจะเป็นอินสแตนซ์เดียวกัน
    • StackWalker luke = StackWalker.getInstance(options);
  • create หรือ newInstance
    • เหมือนกับ instance หรือ getInstance แต่รับประกันว่าจะส่งคืนอินสแตนซ์ใหม่เสมอ
    • Object newArray = Array.newInstance(classObject, arraylen);
  • type
    • เหมือนกับ getType และ newType แต่สั้นกว่า
    • List<Complaint> litany = Collections.list(legacyLitany);


บทสรุป

ใช้วิธีการแบบคงที่และคอนสตรัคเตอร์แบบ public อย่างเหมาะสม


แหล่งที่มา

제이온
제이온
제이온
제이온
[Spring] Filter, Interceptor, Argument Resolver คืออะไร? เรียนรู้เกี่ยวกับแนวคิดและความแตกต่างของตัวกรอง อินเทอร์เซปเตอร์ และ Argument Resolver ในแอปพลิเคชันเว็บสปริง อย่างละเอียด บทความนี้จะอธิบายวิธีการใช้งานของฟังก์ชันแต่ละอย่าง รวมถึงเวลาที่เหมาะสมในการใช้งาน ข้อดีและข้อเสียของฟังก์ชัน และการวิเคราะห์เปรียบ

27 เมษายน 2567

[Effective Java] รายการ 4. ใช้ตัวสร้างส่วนตัวเพื่อป้องกันการสร้างอินสแตนซ์ สำหรับคลาสยูทิลิตี้ที่มีเพียงเมธอดคงที่และฟิลด์ ควรตั้งค่าตัวสร้างให้เป็นส่วนตัวเพื่อป้องกันการสร้างอินสแตนซ์ วิธีนี้จะช่วยป้องกันผู้ใช้จากการเข้าใจผิดว่าตัวสร้างถูกสร้างขึ้นโดยอัตโนมัติ และทำให้ไม่สามารถสืบทอดได้ ทำให้ความตั้งใจของคลาสชัดเจนขึ้น

28 เมษายน 2567

[Effective Java] รายการที่ 2. พิจารณาตัวสร้างหากมีพารามิเตอร์มากมาย เมื่อสร้างวัตถุที่มีพารามิเตอร์มากมาย การใช้รูปแบบตัวสร้างจะช่วยให้คุณเขียนโค้ดได้ชัดเจนและอ่านง่ายขึ้น สร้างวัตถุตัวสร้างด้วยพารามิเตอร์ที่จำเป็น และตั้งค่าพารามิเตอร์ทางเลือกด้วยเมธอด setter จากนั้นเรียกใช้เมธอด build() เพื่อทำให้วัตถุเสร็จสมบูรณ์ รูปแบ

27 เมษายน 2567

[ไม่มีพื้นฐานทางวิศวกรรมคอมพิวเตอร์ การอยู่รอดในฐานะนักพัฒนา] 14. สรุปเนื้อหาการสัมภาษณ์ทางเทคนิคที่นักพัฒนาหน้าใหม่ถามบ่อย คู่มือเตรียมตัวสัมภาษณ์งานเทคนิคสำหรับนักพัฒนาหน้าใหม่ บทความนี้จะอธิบายแนวคิดที่มักปรากฏใน การสัมภาษณ์งาน เช่น พื้นที่หน่วยความจำหลัก โครงสร้างข้อมูล RDBMS และ NoSQL การเขียนโปรแกรมเชิงโครงสร้างและเชิงวัตถุ การโอเวอร์ไรด์และการโอเวอร์โหลด อัลกอริทึมการเป
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 เมษายน 2567

[Javascript] โครงสร้างของวัตถุ (V8) วัตถุของ JavaScript ในเครื่องยนต์ V8 ถูกแปลงเป็น Fast mode ที่ปรับให้เหมาะสมเหมือนโครงสร้างข้อมูลตามสถานะและ Dictionary mode ที่ทำงานเป็นแฮชแมป Fast mode เร็วเนื่องจากคีย์และค่าอยู่ในรูปแบบคงที่เกือบทั้งหมด แต่เมื่อมีการเพิ่มคีย์ใหม่หรือดำเนินการลบองค์ประ
곽경직
곽경직
곽경직
곽경직
곽경직

18 มีนาคม 2567

การสร้างแบบจำลองข้อมูลเชิงแนวคิด การสร้างแบบจำลองข้อมูลเชิงแนวคิดเป็นกระบวนการแยกเอนทิตีและแสดงความสัมพันธ์ระหว่างเอนทิตีในรูปแบบ ERD เอนทิตีเป็นหน่วยข้อมูลอิสระ และแอตทริบิวต์คือข้อมูลที่เอนทิตีมี ตัวระบุคือสิ่งที่ระบุเอนทิตีเฉพาะและความสัมพันธ์แสดงถึงการโต้ตอบระหว่างเอนทิตี คาร์ดินัลลิ
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

8 เมษายน 2567

JWT (JSON Web Token) คืออะไร? JSON Web Token (JWT) เป็นมาตรฐานเปิดสำหรับการส่งข้อมูลอย่างปลอดภัย โดยใช้โทเค็นที่ลงนามเพื่อรักษาความสมบูรณ์และความปลอดภัยของข้อมูล ส่วนหัวประกอบด้วยประเภทโทเค็นและอัลกอริทึมการลงนาม และเพย์โหลดประกอบด้วยข้อมูลผู้ใช้ที่ผู้พัฒนาต้องการ รวมอยู่ด้วย JWT ที่ล
Seize the day
Seize the day
Seize the day
Seize the day
Seize the day

4 มีนาคม 2567

การสร้างแบบจำลองข้อมูลเชิงตรรกะ การสร้างแบบจำลองข้อมูลเชิงตรรกะคือกระบวนการแปลงแบบจำลองข้อมูลเชิงแนวคิดให้สอดคล้องกับรูปแบบฐานข้อมูลเชิงสัมพันธ์ โดยใช้กฎการแมป ซึ่งเกี่ยวข้องกับ การจัดการความสัมพันธ์ 1:1, 1:N, N:M และการทำให้เป็นปกติเพื่อให้ได้มาซึ่งความสมบูรณ์ของข้อมูล 1NF, 2NF, 3NF ผ่
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

9 เมษายน 2567

[การสอบช่างฝีมือระดับสูงสาขาโลหะวิทยา] 39 ครั้ง การแก้ปัญหา บล็อกโพสต์นี้ครอบคลุมเนื้อหาพื้นฐานเกี่ยวกับสมบัติเชิงกลของวัสดุ การอบชุบความร้อน วิธีการทดสอบ และการตรวจสอบแบบไม่ทำลาย บทความนี้ได้อธิบายแนวคิดและคำศัพท์ต่างๆ เช่น ความต้านทานแรงดึง ความแข็ง การชุบแข็งด้วยคาร์บอน การทดสอบการปล่อยคลื่นเสียง เป็นต้น
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi
blog.naver.com/gksmftordldi

24 เมษายน 2567