Item 1. Static Factory Method

์ƒ์„ฑ์ž ๋Œ€์‹  ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ๊ณ ๋ คํ•˜๋ผ

๋ณดํ†ต Java๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” public ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ• ๋ง๊ณ ๋„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ(static factory method)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

public class Example {

    private Example() {
    }

    public static Example of() {
        return new Example();
    }
}

public class Main {

    public static void main(String[] args) {
        Example example = Example.of();
    }
}

์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ์˜ ์žฅ์ 

์œ„ ์˜ˆ์‹œ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์„ ํ•˜๋ฉด ๋‹น์—ฐํžˆ ๋‹จ์ ๋“ค๋„ ์กด์žฌํ•˜์ง€๋งŒ ์žฅ์ ๋“ค๋„ ์กด์žฌํ•œ๋‹ค.

1. ์ƒ์„ฑ์ž์— ์ด๋ฆ„(์˜๋ฏธ) ๋ถ€์—ฌ

public ์ƒ์„ฑ์ž๋Š” ํด๋ž˜์Šค์˜ ์ด๋ฆ„๊ณผ ๋งค๊ฐœ๋ณ€์ˆ˜๋งŒ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€๋งŒ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋Š” ๋ฉ”์„œ๋“œ ์ž์ฒด์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์–ด ๊ฐ€๋…์„ฑ์ด ์ข‹์•„์ง„๋‹ค.

class UUIDExample {
    public static void main(String[] args) {
        // ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด ์ƒ์„ฑ
        UUID randomUUID1 = UUID.randomUUID();
        UUID nameUUID1 = UUID.nameUUIDFromBytes("example".getBytes());

        // public ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด ์ƒ์„ฑ(์‹ค์ œ ์กด์žฌํ•˜๋Š” ์ฝ”๋“œx)
        UUID randomUUID2 = new UUID();
        UUID nameUUID2 = new UUID("example".getBytes());
    }
}

๋‹จ์ˆœํžˆ public ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑํ–ˆ๋‹ค๋ฉด ์ •ํ™•ํžˆ ์–ด๋–ค ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š”์ง€ ์•Œ๊ธฐ ์–ด๋ ค์› ์„ ๊ฒƒ์ด๋‹ค. ๋•Œ๋ฌธ์— ๋งŒ์•ฝ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค๋ฉด pulbic ์ƒ์„ฑ์ž๋ณด๋‹ค๋Š” ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

2. ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ํ•„์š” ์—†์Œ

public ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์ง€๋งŒ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘” ์ธ์Šคํ„ด์Šค๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

class SingletonExample {

    // ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ด€๋ฆฌ
    private static SingletonExample instance;

    // private ์ƒ์„ฑ์ž๋กœ ์™ธ๋ถ€์—์„œ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ฐฉ์ง€
    private SingletonExample() {
    }

    // ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ
    public static SingletonExample getInstance() {
        if (instance == null) {
            instance = new SingletonExample();
        }
        return instance;
    }

    public void doSomething() {
        System.out.println("Singleton instance is here!");
    }
}

class Main {
    public static void main(String[] args) {
        // ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์Šคํ„ด์Šค ์กฐํšŒ
        SingletonExample singleton = SingletonExample.getInstance();

        // ์ธ์Šคํ„ด์Šค๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ๊ฐ€์ ธ์™€๋„ ๋™์ผํ•œ ์ธ์Šคํ„ด์Šค ๋ฐ˜ํ™˜
        SingletonExample anotherSingleton = SingletonExample.getInstance();

        // ๋‘ ๊ฐ์ฒด๋Š” ์™„์ „ ๋™์ผํ•œ ๊ฐ์ฒด์ด๋ฏ€๋กœ true
        System.out.println(singleton == anotherSingleton); // true

        // ๊ฐ์ฒด ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
        singleton.doSomething();
    }
}

์œ„์™€ ๊ฐ™์ด ์ƒ์„ฑํ•˜๋ฉด ์ธ์Šคํ„ด์Šค๋ฅผ ํ•˜๋‚˜๋กœ ์ œํ•œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋˜ํ•œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•ด๋‘๊ณ  ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด์™€ ๊ฐ™์ด ์ธ์Šคํ„ด์Šค๋ฅผ ํ•˜๋‚˜๋กœ ์ œํ•œํ•˜๋Š” ๊ฒƒ์€ ํ”Œ๋ผ์ด์›จ์ดํŠธ ํŒจํ„ด์˜ ๊ทผ๊ฐ„์ด ๋˜๋Š” ๊ธฐ๋ฒ•์ด๋‹ค.

3. ๋ฐ˜ํ™˜ ํƒ€์ž…์˜ ํ•˜์œ„ ํƒ€์ž… ๊ฐ์ฒด ๋ฐ˜ํ™˜ ๊ฐ€๋Šฅ

public ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋งŒ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค์˜ ํ•˜์œ„ ํƒ€์ž… ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

interface Shape {
    // ...

    // ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ Circle ๊ฐ์ฒด ์ƒ์„ฑ
    static Shape createCircle(double radius) {
        return new Circle(radius);
    }

    // ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ Rectangle ๊ฐ์ฒด ์ƒ์„ฑ
    static Shape createRectangle(double width, double height) {
        return new Rectangle(width, height);
    }
}

class Circle implements Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    // ...
}

class Rectangle implements Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    // ...
}

class Main {
    public static void main(String[] args) {
        Shape circle = Shape.createCircle(10);
        Shape rectangle = Shape.createRectangle(10, 20);
    }
}

์œ„์™€ ๊ฐ™์ด ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Shape ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ Circle๊ณผ Rectangle ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ๋กœ Collection ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ, ์‚ฌ์šฉ์ž๋Š” ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด๋ฅผ ์•Œ ํ•„์š” ์—†์ด ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

4. ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋”ฐ๋ผ ๋งค๋ฒˆ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด ๋ฐ˜ํ™˜ ๊ฐ€๋Šฅ

public ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋งŒ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ๋กœ EnumSet ํด๋ž˜์Šค์˜ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋Š” ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋”ฐ๋ผ RegularEnumSet(์›์†Œ 64๊ฐœ ์ดํ•˜)๊ณผ JumboEnumSet(์›์†Œ 64๊ฐœ ์ดˆ๊ณผ)์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์•„๋ž˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฌธ์ž์—ด์„ ์ž…๋ ฅ๋ฐ›์•„ ํ•ด๋‹น ๋ฌธ์ž์—ด์— ํ•ด๋‹นํ•˜๋Š” Shape ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์˜ˆ์‹œ์ด๋‹ค.

interface Shape {
    static Shape createShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        }
        return null;
    }

    void draw();
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Circle");
    }
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Rectangle");
    }
}

public class test {
    public static void main(String[] args) {
        Shape circle = Shape.createShape("circle");
        circle.draw();
        Shape rectangle = Shape.createShape("rectangle");
        rectangle.draw();
    }
}

3๋ฒˆ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํด๋ผ์ด์–ธํŠธ๋Š” ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด๋ฅผ ์•Œ ํ•„์š” ์—†์ด ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์„ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.

5. ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‹œ์ ์—๋Š” ๋ฐ˜ํ™˜ํ•  ๊ฐ์ฒด์˜ ํด๋ž˜์Šค๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„๋„ ๋จ

public ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ๋ฐ˜๋“œ์‹œ ์กด์žฌํ•ด์•ผ ํ•˜์ง€๋งŒ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ์ด๋Ÿฐ ํŠน์ง•์€ ์„œ๋น„์Šค ์ œ๊ณต์ž ํ”„๋ ˆ์ž„์›Œํฌ(Service Provider Framework)๋ฅผ ๋งŒ๋“œ๋Š” ๊ทผ๊ฐ„์ด ๋œ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ์„œ๋น„์Šค ์ œ๊ณต์ž ํ”„๋ ˆ์ž„์›Œํฌ๋กœ๋Š” JDBC๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ทธ ์ค‘ DriverManager ํด๋ž˜์Šค์˜ ์‹ค์ œ ๊ตฌํ˜„ ์ฝ”๋“œ๋ฅผ ์ผ๋ถ€ ๊ฐ€์ ธ์™€ ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

// Connection.java
public interface Connection extends Wrapper, AutoCloseable {
    // ...
}

// Driver.java
public interface Driver {
    // ...
}

// DriverManager.java
public class DriverManager {

    // List of registered JDBC drivers
    private static final CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
    // ...

    /* Prevent the DriverManager class from being instantiated. */
    private DriverManager() {
    }

    public static void registerDriver(java.sql.Driver driver,
                                      DriverAction da)
            throws SQLException {

        /* Register the driver if it has not already been added to our list */
        if (driver != null) {
            registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
        } else {
            // This is for compatibility with the original DriverManager
            throw new NullPointerException();
        }

        println("registerDriver: " + driver);

    }

    @CallerSensitive
    public static Connection getConnection(String url)
            throws SQLException {

        java.util.Properties info = new java.util.Properties();
        return (getConnection(url, info, Reflection.getCallerClass()));
    }

    //  Worker method called by the public getConnection() methods.
    private static Connection getConnection(
            String url, java.util.Properties info, Class<?> caller) throws SQLException {

        // ...

        for (DriverInfo aDriver : registeredDrivers) {
            // If the caller does not have permission to load the driver then
            // skip it.
            if (isDriverAllowed(aDriver.driver, callerCL)) {
                try {
                    println("    trying " + aDriver.driver.getClass().getName());
                    Connection con = aDriver.driver.connect(url, info);
                    if (con != null) {
                        // Success!
                        println("getConnection returning " + aDriver.driver.getClass().getName());
                        return (con);
                    }
                } catch (SQLException ex) {
                    if (reason == null) {
                        reason = ex;
                    }
                }

            } else {
                println("    skipping: " + aDriver.driver.getClass().getName());
            }

        }

        // if we got here nobody could connect.
        if (reason != null) {
            println("getConnection failed: " + reason);
            throw reason;
        }

        println("getConnection: no suitable driver found for " + url);
        throw new SQLException("No suitable driver found for " + url, "08001");
    }
}

์œ„ ์ฝ”๋“œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์ •๋ฆฌํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • private ์ƒ์„ฑ์ž๋กœ ์™ธ๋ถ€์—์„œ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ฐฉ์ง€

  • ArrayList๋กœ ๊ฐ์ฒด๋“ค์„ ๊ด€๋ฆฌ

  • registerDriver() ๋ฉ”์„œ๋“œ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ Driver ์ธํ„ฐํŽ˜์ด์Šค(= ์„œ๋น„์Šค ์ œ๊ณต์ž ์ธํ„ฐํŽ˜์ด์Šค)๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ(= ์ œ๊ณต์ž ๋“ฑ๋ก API)

  • getConnection() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด Connection ์ธํ„ฐํŽ˜์ด์Šค(= ์„œ๋น„์Šค ์ธํ„ฐํŽ˜์ด์Šค)๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜(= ์„œ๋น„์Šค ์ ‘๊ทผ API)

์ด๋ฅผ ๊ฐ„๋žตํ™” ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ •๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋‹ค.

// Service ์ธํ„ฐํŽ˜์ด์Šค: ๊ตฌํ˜„์ฒด์˜ ๋™์ž‘์„ ์ •์˜
interface Service {
    void execute();
}

// ์„œ๋น„์Šค ์ œ๊ณต์ž ํด๋ž˜์Šค 1
class ServiceProvider1 implements Service {
    @Override
    public void execute() {
        // ๊ตฌํ˜„ ๋‚ด์šฉ
        System.out.println("ServiceProvider1 ์‹คํ–‰");
    }
}

// ์„œ๋น„์Šค ์ œ๊ณต์ž ํด๋ž˜์Šค 2
class ServiceProvider2 implements Service {
    @Override
    public void execute() {
        // ๊ตฌํ˜„ ๋‚ด์šฉ
        System.out.println("ServiceProvider2 ์‹คํ–‰");
    }
}

class ServiceRegistry {
    private static Map<String, Service> services = new HashMap<>();

    // ์„œ๋น„์Šค ์ œ๊ณต์ž ๋“ฑ๋ก API: ์ œ๊ณต์ž๊ฐ€ ๊ตฌํ˜„์ฒด๋ฅผ ๋“ฑ๋กํ•  ๋•Œ ์‚ฌ์šฉ
    public static void registerService(String name, Service service) {
        services.put(name, service);
    }

    // ์„œ๋น„์Šค ์ ‘๊ทผ API: ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋น„์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์–ป์„ ๋•Œ ์‚ฌ์šฉ
    public static Service getService(String name) {
        return services.get(name);
    }
}

์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ์˜ ๋‹จ์ 

1. private ์ƒ์„ฑ์ž๋งŒ ์กด์žฌํ•˜๋ฉด ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†์–ด ์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅ

public class Parent {
    private Parent() {
    }

    public static Parent createInstance() {
        return new Parent();
    }
}

public class Child extends Parent { // ์ปดํŒŒ์ผ ์˜ค๋ฅ˜, ์ƒ์† ๋ถˆ๊ฐ€๋Šฅ
}

์ด๋Š” ๋‹จ์ ์ด์ง€๋งŒ, ์ƒ์†๋ณด๋‹ค๋Š” ์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•˜๋„๋ก ์œ ๋„ํ•˜๊ณ  ๋ถˆ๋ณ€ ํƒ€์ž…์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

2. ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์„ ์•Œ์•„์•ผ ํ•จ

์ƒ์„ฑ์ž๋Š” ํด๋ž˜์Šค์˜ ์ด๋ฆ„๊ณผ ๋™์ผํ•˜์ง€๋งŒ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋Š” ์ด๋ฆ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์„ ์•Œ์•„์•ผ ํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๋‹จ์  ์žˆ์–ด ๋„๋ฆฌ ์•Œ๋ ค์ง„ ๋„ค์ด๋ฐ ๊ทœ์•…์„ ํ†ตํ•ด ๋ฌธ์ œ๋ฅผ ์™„ํ™”ํ•˜๊ณ  ์žˆ๋‹ค.

๋ฉ”์„œ๋“œ ์ด๋ฆ„
์„ค๋ช…
์˜ˆ์‹œ

from

๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋ฐ›์•„์„œ ํ•ด๋‹น ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ˜•๋ณ€ํ™˜ ๋ฉ”์„œ๋“œ

Date d = Date.from(instant);

of

์—ฌ๋Ÿฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„์„œ ์ ํ•ฉํ•œ ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ง‘๊ณ„ ๋ฉ”์„œ๋“œ

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

๋งค๋ฒˆ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๋ณด์žฅ

Object newArray = Array.newInstance(classObject, arrayLen);

getType

getInstance์™€ ๊ฐ™์œผ๋‚˜, ์ƒ์„ฑํ•  ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํด๋ž˜์Šค์— ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉ

FileStore fs = Files.getFileStore(path);

newType

newInstance์™€ ๊ฐ™์œผ๋‚˜, ์ƒ์„ฑํ•  ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ํด๋ž˜์Šค์— ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉ

BufferedReader br = Files.newBufferedReader(path);

type

getType๊ณผ newType์˜ ๊ฐ„๊ฒฐํ•œ ๋ฒ„์ „

List<Complaint> litany = Collections.list(legacyLitany);

Last updated

Was this helpful?