์ผ๊ธ ์ปฌ๋ ์ (First-Class Collection)์ด๋?
์ผ๊ธ ์ปฌ๋ ์ (First-Class Collection)์ด๋?
Java์์ ์ผ๊ธ ์ปฌ๋ ์ (First-Class Collection)์ ๋ค๋ฅธ ๊ฐ์ฒด์ ๋๋ฑํ ์ง์๋ฅผ ๊ฐ๋ ์ปฌ๋ ์ ๊ฐ์ฒด๋ฅผ ๋งํฉ๋๋ค.
์ผ๊ธ ์ปฌ๋ ์ ์ ๋ค์๊ณผ ๊ฐ์ ํน์ง์ ๊ฐ์ง๋๋ค.
- ์ปฌ๋ ์ ๊ฐ์ฒด๋ ๋ณ์๋ ๋งค๊ฐ๋ณ์์ ํ ๋นํ ์ ์๋ค.
- ์ปฌ๋ ์ ๊ฐ์ฒด๋ ๋ค๋ฅธ ๊ฐ์ฒด์ ๋๋ฑํ ์ง์๋ฅผ ๊ฐ์ง๋ค.
- ์ปฌ๋ ์ ๊ฐ์ฒด๋ ๋ฐํ๊ฐ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
- ์ปฌ๋ ์ ๊ฐ์ฒด๋ ํ์ํ ๊ฒฝ์ฐ ๋ฉ์๋์์ ์์ฑํ ์ ์๋ค.
๊ทธ๋ฅ ๊ฐ๋จํ๊ฒ ํ ๋ฌธ์ฅ์ผ๋ก ๋งํ๋ฉด Collection์ Wrapping ํ๋ฉด์, ๊ทธ ์ธ ๋ค๋ฅธ ๋ฉค๋ฒ ๋ณ์๊ฐ ์๋ ์ํ๋ฅผ ์ผ๊ธ ์ปฌ๋ ์
์ด๋ผ ํฉ๋๋ค.
์์ ์ฝ๋
์ฝ๋๋ก ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋จผ์ ์ผ๊ธ ์ปฌ๋ ์ ์ ์ฌ์ฉํ์ง ์์ ์ฝ๋์ ๋๋ค.
public class Student {
private List<String> subjects;
public Student(List<String> subjects) {
this.subjects = subjects;
}
public List<String> getSubjects() {
return subjects;
}
}
์ ์ฝ๋์์ Student ํด๋์ค์์ List<String> ํ์ ์ subjects๋ฅผ ์ง์ ๋ค๋ฃจ๊ณ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ Student ํด๋์ค๋ List ํ์ ์ ์์กด์ฑ์ ๊ฐ๊ฒ ๋๋ฉฐ, List์ ๊ตฌํ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ Student ํด๋์ค๋ ํจ๊ป ๋ณ๊ฒฝ๋์ด์ผ ํ๋ ๋ฌธ์ ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๋ค์์ ์ผ๊ธ ์ปฌ๋ ์ ์ ์ฌ์ฉํ ์ฝ๋์ ๋๋ค.
public class Student {
private Subjects subjects;
public Student(Subjects subjects) {
this.subjects = subjects;
}
public Subjects getSubjects() {
return subjects;
}
}
public class Subjects {
private List<String> subjects;
public Subjects(List<String> subjects) {
this.subjects = subjects;
}
public void addSubject(String subject) {
subjects.add(subject);
}
public List<String> getSubjects() {
return new ArrayList<>(subjects);
}
}
์ ์ฝ๋์์๋ Student ํด๋์ค์์ Subjects ํด๋์ค๋ฅผ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค. Subjects ํด๋์ค๋ List<Strring>ํ์ ์ Subjects๋ฅผ ๊ฐ์ธ๊ณ ์์ผ๋ฉฐ, Subject ๊ฐ์ฒด๋ฅผ ์ถ๊ฐํ๊ฑฐ๋, ๋ชจ๋ Subject ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด๋ ๊ฒ ํจ์ผ๋ก์จ Student ํด๋์ค๋ Subjects ํด๋์ค์๋ง ์์กด์ฑ์ ๊ฐ๊ฒ ๋๊ณ ์ด์ ์ ์ง๋ ๋ ๋ฌธ์ ์ ์ธ List ํ์ ์ ๋ํ ์์กด์ฑ์ ์ ๊ฑฐํ ์ ์์ต๋๋ค.
๋ค๋ฅธ ์์๋ฅผ ํ๋ฒ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ๋จผ์ , ์ผ๊ธ ์ปฌ๋ ์ ์ ์ฌ์ฉํ์ง ์์ ์ฝ๋์ ๋๋ค.
public class Book {
private Map<String, String> properties;
public Book(Map<String, String> properties) {
this.properties = properties;
}
public String getProperty(String key) {
return properties.get(key);
}
public void setProperty(String key, String value) {
properties.put(key, value);
}
}
์ ์ฝ๋์์๋ Book ํด๋์ค์์ Map<String, String> ํ์ ์ properties๋ฅผ ์ง์ ๋ค๋ฃจ๊ณ ์์ต๋๋ค. ์ด์ ๋ฌธ์ ์ ์ด ๋ณด์ด์๋์? ์ด ๊ฒฝ์ฐ Book ํด๋์ค๋ Map ํ์ ์ ์์กด์ฑ์ ๊ฐ๊ฒ ๋๋ฉฐ, Map์ ๊ตฌํ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ Book ํด๋์ค๋ ํจ๊ป ๋ณ๊ฒฝ๋์ด์ผ ํฉ๋๋ค.
๋ฐ๋ฉด์ ์ผ๊ธ ์ปฌ๋ ์ ์ ์ฌ์ฉํ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
public class Book {
private Properties properties;
public Book(Properties properties) {
this.properties = properties;
}
public String getProperty(String key) {
return properties.getProperty(key);
}
public void setProperty(String key, String value) {
properties.setProperty(key, value);
}
}
public class Properties {
private Map<String, String> properties;
public Properties() {
this.properties = new HashMap<>();
}
public void setProperty(String key, String value) {
properties.put(key, value);
}
public String getProperty(String key) {
return properties.get(key);
}
public Map<String, String> getAllProperties() {
return new HashMap<>(properties);
}
}
์ ์ฝ๋์์๋ Book ํด๋์ค์์ Properties ํด๋์ค๋ฅผ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค. Properties ํด๋์ค๋ Map<String, String> ํ์ ์ Properties๋ฅผ ๊ฐ์ธ๊ณ ์์ผ๋ฉฐ, Property ๊ฐ์ฒด๋ฅผ ์ถ๊ฐํ๊ฑฐ๋, ๋ชจ๋ Property ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด๋ ๊ฒ ํจ์ผ๋ก์จ Book ํด๋์ค๋ Properties ํด๋์ค์๋ง ์์กด์ฑ์ ๊ฐ๊ณ Map ํ์
์ ๋ํ ์์กด์ฑ์ ์ ๊ฑฐํ๊ฒ ๋ฉ๋๋ค.
์ฅ์
๊ทธ๋ ๋ค๋ฉด ์ด๋ ๊ฒ ์์กด์ฑ์ ์ ๊ฑฐํ๊ฒ ๋จ์ผ๋ก์จ ์ป์ ์ ์๋ ์ฅ์ ๋ค์ ๋ฌด์์ผ๊น์? ์ฅ์ ์ ์๋์ ๊ฐ์ต๋๋ค.
- ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ํฅ์๋๋ค.
- ์ ํจ์ฑ ๊ฒ์ฆ์ด ์ฉ์ดํด์ง๋ค.
- ๋ถ๋ณ์ฑ์ ๋ณด์ฅํ๊ฒ ๋ง๋ค ์ ์๋ค.
๊ฐ๊ฐ์ ์ฅ์ ๋ค์ ์ฝ๋๋ก ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1. ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ํฅ์๋๋ค.
์ผ๊ธ ์ปฌ๋ ์ ์ ์ฌ์ฉํ๋ฉด ํด๋น ์ปฌ๋ ์ ์ ์ฌ์ฉํ๋ ํด๋์ค์์ ํด๋น ์ปฌ๋ ์ ์ ์ญํ ๊ณผ ์๋ฏธ๋ฅผ ๋ฐ๋ก ํ์ ํ ์ ์๊ณ , ์ ์ง๋ณด์์ฑ์ด ํฅ์๋ฉ๋๋ค.
๋ค์์ ์ผ๊ธ ์ปฌ๋ ์ ์ ์ฌ์ฉํ์ง ์์ ์์ ์ฝ๋์ ๋๋ค.
public class Order {
private List<String> items;
private String paymentMethod;
public Order() {
this.items = new ArrayList<>();
}
public void setPaymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
}
}
Orderํด๋์ค๊ฐ ์ฃผ๋ฌธ๊ณผ ๊ด๋ จ๋ ๋ฐ์ดํฐ์ ์ฃผ๋ฌธ์ ๊ฒฐ์ ๋ฐฉ๋ฒ์ ๋ชจ๋ ๊ด๋ฆฌํ๊ณ ์์ต๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ ๊ฒฐ์ ๋ฐฉ๋ฒ๊ณผ ๊ด๋ จ๋ ๋ก์ง์ด ์ถ๊ฐ๋ ๋๋ง๋ค Order ํด๋์ค์ ์ฝ๋๋ฅผ ์์ ํด์ผ ํฉ๋๋ค. ๋ํ ๊ฒฐ์ ๋ฐฉ๋ฒ๊ณผ ๊ด๋ จ๋ ๋ฐ์ดํฐ์ ์ฃผ๋ฌธ๊ณผ ๊ด๋ จ๋ ๋ฐ์ดํฐ๊ฐ ์์ฌ ์๊ธฐ ๋๋ฌธ์ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ๊ฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
์ผ๊ธ ์ปฌ๋ ์ ์ ์ฌ์ฉํ๋ฉด ์์ ๊ฐ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ์๋๋ ์ผ๊ธ ์ปฌ๋ ์ ์ผ๋ก ๋ฆฌํฉํ ๋งํ ์ฝ๋์ ๋๋ค.
public class Order {
private OrderItems items;
private PaymentMethod paymentMethod;
public Order() {
this.items = new OrderItems();
}
public void setPaymentMethod(PaymentMethod paymentMethod) {
this.paymentMethod = paymentMethod;
}
}
public class OrderItems {
private List<String> items;
public OrderItems() {
this.items = new ArrayList<>();
}
// ์์ดํ
๊ด๋ จ ๋ก์ง
}
public abstract class PaymentMethod {
// ๊ฒฐ์ ๋ฐฉ๋ฒ ๊ด๋ จ ์ถ์ ๋ฉ์๋
}
public class CardPayment extends PaymentMethod {
// ์นด๋ ๊ฒฐ์ ๊ด๋ จ ๋ก์ง
}
public class CashPayment extends PaymentMethod {
// ํ๊ธ ๊ฒฐ์ ๊ด๋ จ ๋ก์ง
}
์์ ์ฝ๋์์๋ Order ํด๋์ค๊ฐ OrderItems ํด๋์ค์ PaymentMethod ์ถ์ ํด๋์ค๋ฅผ ๊ฐ๊ฐ ํฌํจํ๊ณ ์์ต๋๋ค.
OrderItems ํด๋์ค๋ ์ฃผ๋ฌธ์ ๋ํ ์์ดํ ์ ๊ด๋ฆฌํ๋ ํด๋์ค์ด๋ฉฐ, PaymentMethod ์ถ์ ํด๋์ค๋ ๊ฒฐ์ ๋ฐฉ๋ฒ ๊ด๋ จ ๋ก์ง์ ๊ด๋ฆฌํ๋ ์ถ์ ํด๋์ค์ ๋๋ค. ์ด ์ถ์ ํด๋์ค๋ฅผ ์์๋ฐ์ CardPayment์ CashPayment ํด๋์ค๋ ๊ฐ๊ฐ ์นด๋ ๊ฒฐ์ ์ ํ๊ธ ๊ฒฐ์ ์ ๋ํ ๋ก์ง์ ๊ด๋ฆฌํฉ๋๋ค.
์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด, ์ฃผ๋ฌธ๊ณผ ๊ด๋ จ๋ ๋ฐ์ดํฐ์ ๊ฒฐ์ ๋ฐฉ๋ฒ๊ณผ ๊ด๋ จ๋ ๋ฐ์ดํฐ๊ฐ ๊ฐ๊ฐ์ ํด๋์ค์ ์บก์ํ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ํฅ์๋ฉ๋๋ค. ๋ํ ์๋ก์ด ๊ฒฐ์ ๋ฐฉ๋ฒ์ ์ถ๊ฐํ ๊ฒฝ์ฐ PaymentMethod ์ถ์ ํด๋์ค๋ฅผ ์์๋ฐ์ ํด๋น ๊ฒฐ์ ๋ฐฉ๋ฒ์ ๋ก์ง์ ๊ตฌํํ๊ธฐ๋ง ํ๋ฉด ๋๋ฏ๋ก ์ฝ๋ ์์ ์ด ๊ฐํธํด์ง๋๋ค.
2. ์ ํจ์ฑ ๊ฒ์ฆ์ด ์ฉ์ดํด์ง๋ค.
์ผ๊ธ ์ปฌ๋ ์ ์ ์ฌ์ฉํ๋ฉด ํด๋น ์ปฌ๋ ์ ์ ๋ด๋ถ ๊ตฌํ์ ์บก์ํํ ์ ์๊ธฐ ๋๋ฌธ์ ์ ํจ์ฑ ๊ฒ์ฆ ์ฝ๋๋ฅผ ํด๋น ์ปฌ๋ ์ ํด๋์ค ๋ด๋ถ์ ๊ตฌํํ์ฌ ์ปฌ๋ ์ ์ ์ฌ์ฉ์๋ค์ด ํด๋น ์ ํจ์ฑ ๊ฒ์ฆ ๋ก์ง์ ํธ์ถํ๋ ๋ฒ๊ฑฐ๋ก์์ ์ค์ผ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด OrderItems ํด๋์ค์์ add() ๋ฉ์๋์ null์ด๋ ๋น ๋ฌธ์์ด์ ์ถ๊ฐํ๋ ค๋ ๊ฒฝ์ฐ ์์ธ๋ฅผ ํฐํธ๋ฆฌ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
public class Order {
private OrderItems items;
public Order() {
this.items = new OrderItems();
}
public OrderItems getItems() {
return items;
}
public void addItem(String item) {
this.items.add(item);
}
public void removeItem(String item) {
this.items.remove(item);
}
}
public class OrderItems {
private List<String> items;
public OrderItems() {
this.items = new ArrayList<>();
}
public List<String> getItems() {
return items;
}
public void add(String item) {
if (item == null || item.isEmpty()) {
throw new IllegalArgumentException("Item cannot be null or empty.");
}
this.items.add(item);
}
public void remove(String item) {
this.items.remove(item);
}
}
์ ์ฝ๋์์๋ OrderItems ํด๋์ค์ add() ๋ฉ์๋์์ item์ด null์ด๊ฑฐ๋ ๋น ๋ฌธ์์ด("") ์ผ ๊ฒฝ์ฐ IllegalArgumentException์ ๋์ง๋๋ก ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ํด๋น ์ปฌ๋ ์ ์ ์ฌ์ฉํ๋ ์ฝ๋์์๋ add() ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ์ ํจ์ฑ ๊ฒ์ฆ์ ์ํํ์ง ์์๋ ๋ฉ๋๋ค(Order ํด๋์ค์์ ์ ํจ์ฑ ๊ฒ์ฆ ๋ก์ง์ ์ํํ์ง ์์๋ ๋จ) ๋ฐ๋ผ์ OrderItems ํด๋์ค ๋ด๋ถ์์ ํด๋น ๊ฒ์ฆ์ ์ํํ๋ฏ๋ก ์ฝ๋์ ๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ์ข์์ง๋๋ค.
3. ๋ถ๋ณ์ฑ์ ๋ณด์ฅํ๊ฒ ๋ง๋ค ์ ์๋ค.
ํด๋น ์ปฌ๋ ์ ์ ๋ถ๋ณ(immutable)์ผ๋ก ๋ง๋ค์ด์ ๋ณ๊ฒฝ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
public class Order {
private final OrderItems items;
public Order(OrderItems items) {
this.items = items;
}
public OrderItems getItems() {
return items;
}
}
public class OrderItems {
private final List<String> items;
public OrderItems(List<String> items) {
if (items == null) {
throw new IllegalArgumentException("Items cannot be null.");
}
this.items = Collections.unmodifiableList(new ArrayList<>(items));
}
public List<String> getItems() {
return items;
}
}
์ ์ฝ๋์์๋ OrderItems ํด๋์ค์์ ์์ฑ์์์ ๋ฐ์ List ๊ฐ์ฒด๋ฅผ ์์ ํ ์ ์๋๋ก Collections.unmodifiableList()๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋ณ ๋ฆฌ์คํธ๋ก ๋ณํํ ๋ค, ์ด๋ฅผ ์ธ์คํด์ค ๋ณ์๋ก ์ ์ฅํฉ๋๋ค. ์ด๋ก ์ธํด OrderItems ๊ฐ์ฒด๋ฅผ ์์ฑํ ํ์๋ ํด๋น ๊ฐ์ฒด ๋ด๋ถ์ List ์ปฌ๋ ์ ์ ์์ ํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ Order ํด๋์ค์์ OrderItems ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ ๊ฒฝ์ฐ, ํด๋น ๊ฐ์ฒด ๋ด๋ถ์ List ์ปฌ๋ ์ ์ ์์ ํ ์ ์์ผ๋ฏ๋ก ๋ถ๋ณ์ฑ์ด ๋ณด์ฅ๋ฉ๋๋ค. ๋ํ OrderItems ํด๋์ค ๋ด๋ถ์์ List ๊ฐ์ฒด๋ฅผ ์์ ํ ์ ์๋ add()๋ remove()์ ๊ฐ์ ๋ฉ์๋๊ฐ ์๊ธฐ ๋๋ฌธ์ ํด๋น ๊ฐ์ฒด๋ฅผ ์์ฑํ ํ์๋ ๋ด๋ถ์ List ์ปฌ๋ ์ ์ ์๋ก์ด ์์๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ ์ ์์ต๋๋ค. ๋๋ถ์ OrderItems ๊ฐ์ฒด์ ๋ถ๋ณ์ฑ๋ ๋ณด์ฅ๋ฉ๋๋ค.
ํ์ง๋ง ์ผ๊ธ์ปฌ๋ ์
์ ํญ์ ๋ถ๋ณํ๊ฒ ๋ง๋ค ํ์๋ ์๊ณ , ์ํฉ์ ๋ง๊ฒ ์ ์ฉํ์๋ฉด ๋ฉ๋๋ค.
๋ง๋ฌด๋ฆฌ
์ต์ข ์ ์ผ๋ก ์ผ๊ธ ์ปฌ๋ ์ ์ ์ฌ์ฉํ ์ฝ๋์์๋ OrderItems ํด๋์ค๊ฐ ์ง์ ๋ฆฌ์คํธ์ ๋ํ ์์ ์ ์ํํฉ๋๋ค. ๋ฐ๋ผ์ Order ํด๋์ค๋ ๋จ์ํ OrderItems ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ฐํํ๊ธฐ๋ง ํ๋ฉด ๋๋ฏ๋ก OrderItems ํด๋์ค์ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ์ ํ์๊ฐ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๊ฒฐํฉ๋๊ฐ ๋ฎ์์ง๊ณ ์ฝ๋์ ์ ์ง๋ณด์์ฑ์ด ํฅ์๋ฉ๋๋ค.
์ผ๊ธ ์ปฌ๋ ์ ์ ์ฝ๋์ ๊ฐ๋ ์ฑ, ์ ์ง๋ณด์์ฑ, ํ ์คํธ ์ฉ์ด์ฑ ๋ฑ์ ๊ฐ์ ํ ์ ์๋ ๋งค์ฐ ์ ์ฉํ ๊ฐ๋ ์ ๋๋ค. ์ผ๊ธ ์ปฌ๋ ์ ์ ๊ฐ๋ ์ ์ดํดํ๊ณ , ์ ์ ํ๊ฒ ํ์ฉํ๋ฉด ์ข ๋ ๋์ ํด๋ฆฐ ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ ๊ฒ์ ๋๋ค.