From 99c03df62e16060ab00cad69ae96429620d0c5d8 Mon Sep 17 00:00:00 2001 From: EuiSung <52964858+gowoonsori@users.noreply.github.com> Date: Thu, 10 Mar 2022 12:20:46 +0900 Subject: [PATCH 1/3] Create code.md --- .../summary/code.md" | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 "\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/code.md" diff --git "a/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/code.md" "b/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/code.md" new file mode 100644 index 0000000..8536d6c --- /dev/null +++ "b/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/code.md" @@ -0,0 +1,104 @@ +## Java +```java +public class Order implements Cloneable{ + private Orderer orderer; + private long orderIdx; + private long totalAmount; + private long lastAmount; + private long giftCouponPrice; + private long giftCouponUsedAmount; + private int discountRate; + private LocalDateTime expiryDt; + private LocalDateTime earliesstDt; + + @Override + public Order clone() throws CloneNotSupportedException { + return (Order) super.clone(); //Object의 clone()이용해서 복제후 Object에서 Order로 클래스 형변환 + } +} + +public class Client { + public static void main(String[] args) throws CloneNotSupportedException { + Order order1 = new Order(); + Order order2 = order1.clone(); + + System.out.println(order1 == order2); //false + System.out.println(order1.equals(order2)); //false + } +} +``` +자바에서는 객체를 복제할 수 있도록 최상위 클래스인 Object에서 `clone()`를 지원한다. 하지만 Object의 clone을 이용하기 위해서는 Cloneable을 implements해야만 사용이 가능하다. + +또한, 객체간의 동등성을 판단하기 위해 String의 equals() 처럼 object의 equals()를 이용하면 기대했던 값과는 다르게 `false` 가 반환된다.
이는 Object의 equals()는 `==`를 통해 비교하기 때문에 동일성비교와 같은 결과를 보여주는 것이고, String의 equals()는 값만을 비교하도록 재정의 했기 때문에 동등성 비교가 가능한 것이다. + +따라서 객체의 동등성을 비교하고 싶다면 `equals()`를 재정의 해주면 된다. + +```java +public class Order implements Cloneable{ + private Orderer orderer; + private long orderIdx; + private long totalAmount; + private long lastAmount; + private long giftCouponPrice; + private long giftCouponUsedAmount; + private int discountRate; + private LocalDateTime expiryDt; + private LocalDateTime earliesstDt; + + @Override + public Order clone() throws CloneNotSupportedException { + return (Order) super.clone(); //Object의 clone()이용해서 복제후 Object에서 Order로 클래스 형변환 + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Order)) return false; + Order order = (Order) o; + return orderIdx == order.orderIdx && totalAmount == order.totalAmount && lastAmount == order.lastAmount && giftCouponPrice == order.giftCouponPrice && giftCouponUsedAmount == order.giftCouponUsedAmount && discountRate == order.discountRate && Objects.equals(orderer, order.orderer) && Objects.equals(expiryDt, order.expiryDt) && Objects.equals(earliesstDt, order.earliesstDt); + } + + @Override + public int hashCode() { + return Objects.hash(orderer, orderIdx, totalAmount, lastAmount, giftCouponPrice, giftCouponUsedAmount, discountRate, expiryDt, earliesstDt); + } +} + +public class Client { + public static void main(String[] args) throws CloneNotSupportedException { + Order order1 = new Order(); + Order order2 = order1.clone(); + + System.out.println(order1 == order2); //false + System.out.println(order1.equals(order2)); //true + } +} +``` + +
+ +## PHP +```php +class Order{ + private $orderer; + private $orderIdx; + private $totalAmount; + private $lastAmount; + private $giftCouponPrice; + private $giftCouponUsedAmount; + private $discountRate; + private $expiryDt; + private $earliesstDt; +} + +class client extends PHPUnit\Framework\TestCase{ + function test_clone객체비교() { + $order1 = new Order(); + $order2 = clone $order1; + + $this->assertFalse($order == $order2); + $this->assertTrue($order === $order3); + } +} +``` +php는 `clone`이라는 키워드로 객체 복제를 지원하고 있으며, `==`,`===` 연산자로 동일성, 동등성을 비교해보면 복제된 객체와 동등하지만 동일하지는 않게 복제가 되는 것을 볼 수 있다. \ No newline at end of file From a89502a23ffaec2bf3aea0b174297213dd8a8db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=B0=BD=EC=84=AD?= Date: Thu, 17 Mar 2022 00:19:45 +0900 Subject: [PATCH 2/3] =?UTF-8?q?add)=20=ED=94=84=EB=A1=9C=ED=86=A0=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\355\204\264 \354\240\225\353\246\254.md" | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 "\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/\353\270\214\353\246\277\354\247\200 \355\214\250\355\204\264 \354\240\225\353\246\254.md" diff --git "a/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/\353\270\214\353\246\277\354\247\200 \355\214\250\355\204\264 \354\240\225\353\246\254.md" "b/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/\353\270\214\353\246\277\354\247\200 \355\214\250\355\204\264 \354\240\225\353\246\254.md" new file mode 100644 index 0000000..185a534 --- /dev/null +++ "b/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/\353\270\214\353\246\277\354\247\200 \355\214\250\355\204\264 \354\240\225\353\246\254.md" @@ -0,0 +1,150 @@ +# 프로토타입 패턴 + +> **원본 객체를 새로운 객체로 복사**하여 사용하는 패턴 + +![](https://refactoring.guru/images/patterns/diagrams/prototype/structure.png) + +이름이 뭐더라.. + +## 프로토타입은 언제 사용되는가? + +... + +## 프로토타입 패턴 예제 코드 + +## Java + +```java +public class Order implements Cloneable{ + private Orderer orderer; + private long orderIdx; + private long totalAmount; + private long lastAmount; + private long giftCouponPrice; + private long giftCouponUsedAmount; + private int discountRate; + private LocalDateTime expiryDt; + private LocalDateTime earliesstDt; + + @Override + public Order clone() throws CloneNotSupportedException { + return (Order) super.clone(); //Object의 clone()이용해서 복제후 Object에서 Order로 클래스 형변환 + } +} + +public class Client { + public static void main(String[] args) throws CloneNotSupportedException { + Order order1 = new Order(); + Order order2 = order1.clone(); + + System.out.println(order1 == order2); //false + System.out.println(order1.equals(order2)); //false + } +} +``` + +자바에서는 객체를 복제할 수 있도록 최상위 클래스인 Object에서 `clone()`를 지원한다. 하지만 Object의 clone을 이용하기 위해서는 Cloneable을 implements해야만 사용이 가능하다. + +또한, 객체간의 동등성을 판단하기 위해 String의 equals() 처럼 object의 equals()를 이용하면 기대했던 값과는 다르게 `false` 가 반환된다. +이는 Object의 equals()는 `==`를 통해 비교하기 때문에 동일성비교와 같은 결과를 보여주는 것이고, String의 equals()는 값만을 비교하도록 재정의 했기 때문에 동등성 비교가 가능한 것이다. + +따라서 객체의 동등성을 비교하고 싶다면 `equals()`를 재정의 해주면 된다. + +```java +public class Order implements Cloneable{ + private Orderer orderer; + private long orderIdx; + private long totalAmount; + private long lastAmount; + private long giftCouponPrice; + private long giftCouponUsedAmount; + private int discountRate; + private LocalDateTime expiryDt; + private LocalDateTime earliesstDt; + + @Override + public Order clone() throws CloneNotSupportedException { + return (Order) super.clone(); //Object의 clone()이용해서 복제후 Object에서 Order로 클래스 형변환 + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Order)) return false; + Order order = (Order) o; + return orderIdx == order.orderIdx && totalAmount == order.totalAmount && lastAmount == order.lastAmount && giftCouponPrice == order.giftCouponPrice && giftCouponUsedAmount == order.giftCouponUsedAmount && discountRate == order.discountRate && Objects.equals(orderer, order.orderer) && Objects.equals(expiryDt, order.expiryDt) && Objects.equals(earliesstDt, order.earliesstDt); + } + + @Override + public int hashCode() { + return Objects.hash(orderer, orderIdx, totalAmount, lastAmount, giftCouponPrice, giftCouponUsedAmount, discountRate, expiryDt, earliesstDt); + } +} + +public class Client { + public static void main(String[] args) throws CloneNotSupportedException { + Order order1 = new Order(); + Order order2 = order1.clone(); + + System.out.println(order1 == order2); //false + System.out.println(order1.equals(order2)); //true + } +} +``` + +## PHP + +```php +class Order{ + private $orderer; + private $orderIdx; + private $totalAmount; + private $lastAmount; + private $giftCouponPrice; + private $giftCouponUsedAmount; + private $discountRate; + private $expiryDt; + private $earliesstDt; +} + +class client extends PHPUnit\Framework\TestCase{ + function test_clone객체비교() { + $order1 = new Order(); + $order2 = clone $order1; + + $this->assertFalse($order == $order2); + $this->assertTrue($order === $order3); + } +} +``` + +php는 `clone`이라는 키워드로 객체 복제를 지원하고 있으며, `==`,`===` 연산자로 동일성, 동등성을 비교해보면 복제된 객체와 동등하지만 동일하지는 않게 복제가 되는 것을 볼 수 있다. + +## 패턴의 장/단점 + +장점: + +- 구체적인 클래스로부터 커플링 없이 객체 복사 가능 +- 반복적인 초기화 코드를 제거해서, 프로토타입을 복제 할 수 있음. +- 복잡한 객체를 더 편리하게 생산할 수 있음 +- 복잡한 객체에 대한 사전 설정을 처리할때 상속 대신 사용 가능 + +단점: + +- 순환 참조가 있는 복잡한 객체를 복제하는 것은 매우 까다로울 수 있음. + +## 비슷한 패턴 + +- 많은 디자인패턴들이 **팩토리 메소드**(하위 클래스를 통해서 덜 복잡하고, 더 커스터마이징 가능하게)를 사용하는데, 추**상 팩토리 패턴, 프로토타입, 빌더**(더 유연하지만 좀 더 복잡한 형태)로 발전 했다. + +- **추상팩토리** 클래스는 **팩토리 메소드**의 기반으로 설계되어있지만, **프로토타입**을 쓰면 이런 클래스들의 메소드들을 구성할 수 도 있음. + +- **프로토 타입**은 **커멘드 패턴**의 복사본을 기록에 저장해야할때 도움을 줍니다. + +- **데코레이터**와 **컴포짓 패턴**을 많이 사용한 설계의 경우 **프로토타입**을 사용하는게 많은 이점을 누릴 수 있다. 적용하면, 복잡한 구조를 처음부터 재구성할 필요가 없고, 복제 가능해진다. + +- **프로토타입**은 상속에 기반하지 않아서, 상속에 문제점이 없다. 반면에 복제할 객체의 초기화가 복잡해진다. 반대로 **팩토리 메소드**는 상속을 사용하지만, 초기화 단계가 필수적이지 않다. + +- **프로토타입**은 **메멘토 패턴**의 간단한 대체제가 될 수 있다. 이력에 저장하려는 상태인 객체가 매우 단순하고 외부 리소스에 대한 연결성이 없거나, 재연결성이 쉽게 되는 경우에 사용하는 것이 좋다. + +- **추상 팩토리 패턴, 빌더, 프로토타입**은 싱글톤으로 구현 가능하다. From 29ff2917eb7b46a736f9acf358d1a2469ccb3677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=B0=BD=EC=84=AD?= Date: Mon, 21 Mar 2022 23:42:58 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Add)=20=EB=82=A0=EB=9D=BC=EA=B0=84=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\250\355\204\264 \354\240\225\353\246\254.md" | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git "a/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/\353\270\214\353\246\277\354\247\200 \355\214\250\355\204\264 \354\240\225\353\246\254.md" "b/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/\353\270\214\353\246\277\354\247\200 \355\214\250\355\204\264 \354\240\225\353\246\254.md" index 185a534..d490758 100644 --- "a/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/\353\270\214\353\246\277\354\247\200 \355\214\250\355\204\264 \354\240\225\353\246\254.md" +++ "b/\352\260\235\354\262\264\354\203\235\354\204\261/3\354\243\274\354\260\250-\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/summary/\353\270\214\353\246\277\354\247\200 \355\214\250\355\204\264 \354\240\225\353\246\254.md" @@ -4,11 +4,13 @@ ![](https://refactoring.guru/images/patterns/diagrams/prototype/structure.png) -이름이 뭐더라.. +**Prototype**: clone 메소드를 선언되어있는 인터페이스 + +**Concrete Prototype**: 실제로 클론 메소드를 구현하는 클래스. ## 프로토타입은 언제 사용되는가? -... +- 다수의 객체를 많이 만들고 싶은 경우 ## 프로토타입 패턴 예제 코드 @@ -122,22 +124,22 @@ php는 `clone`이라는 키워드로 객체 복제를 지원하고 있으며, `= ## 패턴의 장/단점 -장점: +✅ 장점: - 구체적인 클래스로부터 커플링 없이 객체 복사 가능 - 반복적인 초기화 코드를 제거해서, 프로토타입을 복제 할 수 있음. - 복잡한 객체를 더 편리하게 생산할 수 있음 - 복잡한 객체에 대한 사전 설정을 처리할때 상속 대신 사용 가능 -단점: +🚨 단점: -- 순환 참조가 있는 복잡한 객체를 복제하는 것은 매우 까다로울 수 있음. +- 순환 참조가 있는 복잡한 객체를 복제하는 것은 매우 까다로울 수 있다. ## 비슷한 패턴 -- 많은 디자인패턴들이 **팩토리 메소드**(하위 클래스를 통해서 덜 복잡하고, 더 커스터마이징 가능하게)를 사용하는데, 추**상 팩토리 패턴, 프로토타입, 빌더**(더 유연하지만 좀 더 복잡한 형태)로 발전 했다. +- 많은 디자인패턴들이 **팩토리 메소드**(하위 클래스를 통해서 덜 복잡하고, 더 커스터마이징 가능하게)를 사용하는데, 추**상 팩토리 패턴, 프로토타입, 빌더**(더 유연하지만 좀 더 복잡한 형태)로 발전했다. -- **추상팩토리** 클래스는 **팩토리 메소드**의 기반으로 설계되어있지만, **프로토타입**을 쓰면 이런 클래스들의 메소드들을 구성할 수 도 있음. +- **추상팩토리** 클래스는 **팩토리 메소드**의 기반으로 설계되어있지만, **프로토타입**을 쓰면 이런 클래스들의 메소드들을 구성할 수 도 있다. - **프로토 타입**은 **커멘드 패턴**의 복사본을 기록에 저장해야할때 도움을 줍니다.