← Back to list

EP7: Java Design Patterns in Action

Prototype Pattern — สร้างโคลนอย่างเทพ โดยไม่ต้อง new ใหม่

Chiwa Kantawong (Pea) · 2025-07-16 11:03 · 3 claps · 1.4 min read
#design-patterns #prototype-pattern #java #spring-boot
Open on Medium ↗
Wiki topics: UX · UI/UX Design

EP7: Java Design Patterns in Action

Prototype Pattern — สร้างโคลนอย่างเทพ โดยไม่ต้อง new ใหม่

ปัญหาที่เราเจอบ่อย ๆ

  • มี object ที่ต้องสร้างซ้ำๆ เยอะมาก เช่น template หรือ config object
  • เวลา new แล้ว set แต่ละ field มันสิ ซ้ำซาก
  • อยาก clone ได้เลย จะ shallow/deep ก็แล้วแต่

Prototype Pattern คือ…

“Clone object ที่มีอยู่แล้ว แทนที่จะสร้างใหม่”

ใช้ interface Cloneable + method clone() เพื่อคัดลอก object ได้รวดเร็วมาก โดยเฉพาะพวกที่สร้างยาก ๆ

ใช้ต่อ Spring Boot ได้ไม่?

จริง ๆ ถ้าใช้ Spring Boot เราจะไม่เขียน clone() เองบ่อย เพราะสามารถใช้:

  • BeanUtils.copyProperties(...)
  • หรือใช้ @Scope("prototype") เพื่อสร้าง bean ใหม่ทุกครั้ง
@Component
@Scope("prototype")
public class MyPrototypeBean {
   ...
}

@Component
public class MyService {
    @Autowired
    private ApplicationContext context;

    public void test() {
        context.getBean(MyPrototypeBean.class);
        context.getBean(MyPrototypeBean.class);
        context.getBean(MyPrototypeBean.class);
    }
}
  • ถ้า class เป็น Singleton (default) → getBean() จะได้ object เดิม
  • ถ้า class ใส่ @Scope("prototype")getBean() จะได้ object ใหม่ทุกครั้ง

พี่พีเคยงงเหมือนกันว่า ถ้าเรียก getBean() แล้วมันใหม่อยู่แล้ว จะใส่ @Scope("prototype") ไปทำไม? คำตอบคือ... ไม่ใส่ = ได้ object เดิมนะครับ! ต้องประกาศให้ชัดด้วย @Scope("prototype") ด้วยถึงจะได้ผล

ตัวอย่าง

package com.zengcode.designpatterns.prototype;

public class Main {

    public static class Product implements Cloneable {
        private String name;
        private double price;
        private String category;
        public Product(String name, double price, String category) {
            this.name = name;
            this.price = price;
            this.category = category;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public Product clone() {
            try {
                return (Product) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }
        @Override
        public String toString() {
            return "Product{" +
                    "name='" + name + '\'' +
                    ", price=" + price +
                    ", category='" + category + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) {
        Product template = new Product("Basic T-Shirt", 299.0, "Clothing");
        Product redShirt = template.clone();
        redShirt.setName("Red T-Shirt");
        Product blueShirt = template.clone();
        blueShirt.setName("Blue T-Shirt");
        System.out.println(template);
        System.out.println(redShirt);
        System.out.println(blueShirt);
    }
}

เทียบกับ Builder และ Factory?

  • Builder: สร้าง object ที่มีการตั้งค่าเยอะ ๆ และ flow แบบ fluent interface (การเขียนโค้ดที่ออกแบบให้ อ่านต่อเนื่องเหมือนประโยคภาษาอังกฤษ โดยเน้นการ return ตัวเอง (this) เพื่อให้สามารถ chain method ต่อกันได้ในรูปแบบที่สวยและเข้าใจง่าย)
  • Factory: ซ่อนไว้ว่า new ตัวไหน ขึ้นอยู่กับ logic
  • Prototype: copy object ที่สร้างเสร็จแล้ว เอาไปใช้ต่อ

สรุป

“Prototype Pattern คือ pattern ที่เราชอบใช้ตอนขี้เกียจ set ค่าใหม่ ๆ แต่ยังอยากได้ object ใหม่ที่แก้ไขได้”


메타데이터
post_id
2df1e4c4d3ab
slug
ep7-java-design-patterns-in-action-2df1e4c4d3ab
url
https://medium.com/@zengcode/ep7-java-design-patterns-in-action-2df1e4c4d3ab
canonical_url
https://medium.com/@zengcode/ep7-java-design-patterns-in-action-2df1e4c4d3ab
author_url
https://medium.com/@zengcode
status
ok
fetched_at
2026-08-06 22:49:14