Replace Inheritance With Delegation Refactoring

 


 

�� ������ ��ſ��� Replace Inheritance With Delegation �����丵 ����� ��������  overview��  how  �� �����丵�� IntelliJ IDEA���� ���� �� �ִ°��� �����մϴ�.

����


Replace Inheritance With Delegation ï¿½ï¿½ï¿½ï¿½ï¿½ä¸µ ����� ����ڿ��� ���̽� Ŭ����/�������̽����� ���� Ŭ���� �ν��Ͻ�

�Ǵ� ���� �������̽��� �����ϴ� ���� Ŭ������ �Ļ��� ���� �޼ҵ��� ������ �븮�ϴ� ���� ����մϴ�.

�� �����丵 ��ɴ� ���� ��� ���� �� ���� ���� �� �ֽ��ϴ�:

 1.   ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ìµï¿½ �޼ҵ��

 
public class ClassParent {
    public void method1(){
        method2();
    }
 
    public void method2(){
        System.out.println("ClassParent");
    }
}
 
public class ClassChild extends ClassParent {
    public void method2(){
        System.out.println("ClassChild");
    }
}

 

���� Ŭ��������, method2�� �θ� Ŭ������ �����ϴ� �޼ҵ带 �������̵� �մϴ�.  ï¿½ï¿½ï¿½ï¿½ï¿½ä¸µ method2 ï¿½ï¿½ �븮�ǰ� 
�� �Ŀ� ���� Ŭ������ �ڵ�κ����� ����Ŭ�������� ������ ������ ���� ���� ���Դϴ�:
 
public class ClassChild {
 
private final MyClassParent classParent = new MyClassParent();
 
    public void method2() {
      classParent.method2();
    }
 
    private class MyClassParent extends ClassParent {
      public void method2(){
          System.out.println("ClassChild");
      }
    }
}



 2.  
 ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ì½ï¿½ï¿½ï¿½

 
public interface ParentInterface {
    void method1();
    void method2();
}
 
public class ClassParent implements ParentInterface {
    public void method1(){
        method2();
    }
 
    public void method2(){
        System.out.println("ClassParent");
    }
}

 

�׸��� ����� method1()�� �븮�� ���� �ڵ�.
  
public class ClassParent {
private final MyParentInterface parentInterface = new MyParentInterface();
 
    public void method1() {
        parentInterface.method1();
    }
 
    private class MyParentInterface implements ParentInterface {
       public void method1(){
           method2();
       }
 
       public void method2(){
           System.out.println("ClassParent");
       }
     }
}


��� ��쿡, �θ� Ŭ����/�������̽��� �޼ҵ带 �����ϰ� �ִ� ���� Ŭ������ �� �ν��Ͻ��� �Բ� �����˴ϴ�.  

�׸��� �븮�� �޼ҵ���� ��� ���� �� ���� Ŭ���� �ν��Ͻ��� ����ϸ鼭 ����˴ϴ�.

 3.   Å¬ï¿½ï¿½ï¿½ï¿½ ��� ���:

 
������ ���� Ȯ���ϰ� ClassParent�� ����ϰ� �ִ� �� �ϳ��� Ŭ������ �߰��Ͻʽÿ�.
 
public class ClassUsage {
    public ClassParent classParent = new ClassParent();
 
    void methodInChild(){
        classParent.method2();
        classParent.method1();
        myMethod(classParent);
        ParentInterface pi = classParent;
 
        //some code here
    }
 
void myMethod(ParentInterface p){
        //some code here
    }
}

 

�� ���� �����丵�� ClassParent ���� ����˴ϴ�. �׸��� �ٽ� method1()�� �븮�˴ϴ�.  
 
public class ClassParent {
    private final MyParentInterface parentInterface = new MyParentInterface();
 
    public ParentInterface getParentInterface() {
        return parentInterface;
    }
 
    public void method1() {
        parentInterface.method1();
    }
 
    private class MyParentInterface implements ParentInterface {
        public void method1(){
            method2();
        }
 
        public void method2(){
            //some code here
        }
    }
}
 
public class ClassUsage {
    public ClassParent classParent = new ClassParent();
 
    void methodInChild(){
        classParent.getParentInterface().method2();
        classParent.method1();
        myMethod(classParent.getParentInterface());
        ParentInterface pi = classParent.getParentInterface();
 
        //some code here
    }
 
void myMethod(ParentInterface p){
        //some code here
    }
}
 

����� ���� ��ó��, �����丵 �Ŀ� ������ �ʴ� Ŭ���� ����� ����ϱ� ���ؼ�, Ư���� ���� �޼ҵ�(getParentInterface())�� �����˴ϴ�.  ï¿½×·ï¿½ï¿½ï¿½, �ٸ� Ŭ���� ����� ����� �ٲ��� �ʾҽ��ϴ�.

Replacing Inheritance With Delegation  


��ӵ� Ŭ���� ����� �븮�� ��ü�ϱ� ���ؼ�:

 1.   ï¿½ï¿½ï¿½ï¿½ï¿½Í¿ï¿½ï¿½ï¿½ �Ǵ� Project View  / Commander ï¿½ï¿½ï¿½ï¿½, �޼ҵ�/�������̽��� �븮�� ��ü�Ǿ�߸� �ϴ� Ŭ���� ���� ij���� �����ϰ� ���� �޴� �Ǵ� ������ ��ư�� Ŭ���ϴ� �Ϳ� ���� �ҷ����� �˾� �޴����� Refactor Replace Inheritance With Delegation... ï¿½ï¿½ Ŭ���Ͻʽÿ�.

 2.   ï¿½ï¿½ï¿½ï¿½ï¿½ Replace Inheritance With Delegation  ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ���� �� �� �Դϴ�

�븮�� ����� ��ü

���-�ٿ� �ڽ����� ����� �븮�� ��ü�� ��� Ŭ����/�������̽��� ������ �� �ֽ��ϴ�.

�ʵ� �̸�

�̸��� �Է����ų�, ��� Ŭ����/�������̽� �ν��Ͻ��� ���� �̸��� �Ǵ� �ʵ忡 ���� IDEA�� ���� ���ȵ� �ϳ��� ����մϴ�.

���� Ŭ���� �̸�

�̸��� �Է����ų�, ��� Ŭ����/�������̽� ����� �����ϴ� ���� Ŭ������ ���� IDEA�� ���� ���ȵ� �ϳ��� ����մϴ�.

�븮 ���

�� ��� ���� �������̽��� �޼ҵ带 �����ϸ鼭 �븮�� �� �ִ� ��� ��� Ŭ���� ����� ����� ǥ���մϴ�.  ï¿½ë¸®ï¿½ï¿½ ���� Ŭ���� ����� ��ũ�ϱ� ����, ����� �� ���ʿ� üũ �ڽ��� �����ؾ߸� �մϴ�.

�븮�� ���� ����� ���� ���� ����

���� ���õǸ�, �븮�� Ÿ���� ���� ���Ͱ� �����˴ϴ�.  ï¿½ï¿½ ���ʹ� �����丵 ���� �������� �ʴ� �븮�� ���� ����� �׼����ϱ� ���� ���˴ϴ�.

����� �̸� ���� ���

�� üũ �ڽ��� �����ϸ� ��ſ��� ����� �߰ߵ� ���� ������ ��� ��� ���� ����ϰ�, ��ſ��� �׵��� ��ü�� �����ϴ� ���� ����մϴ�.  ï¿½ï¿½ üũ �ڽ��� ���õ��� ���� ��, IDEA�� ��ü ��ɸ� �ڵ������� �����մϴ�.


������ üũ �ڽ��� Ȯ�ε��� �ʾ��� ����, ���� �߰ߵ� ����� � �б� ���� ���Ͽ��� �����ϸ� ��ſ��� ��� ��ü�� Ȯ���ϱ� ���� ������Ʈ �� ���Դϴ�.


Refactoring Preview  ���̾�α�(���� �װ��� ��Ÿ����)����, ����� ����� ������ ��� �� �ֽ��ϴ�.  ï¿½ï¿½ï¿½ï¿½ï¿½ä¸µï¿½ï¿½ �Բ� �����ϱ� ���ؼ�, Do Refactor   Ŭ���Ͻʽÿ�, �׷��� �ʴٸ� Cancel �� Ŭ���Ͻʽÿ�. ���� ���� ����  Refactoring Preview�� ���ʽÿ�.


����� OK ï¿½ï¿½ Ŭ���ϰ� �� �Ŀ� ï¿½ï¿½ï¿½ï¿½ï¿½ä¸µï¿½ï¿½ ����� ���Դϴ�.

 

�Ϲ�������, ����� ������ ������ �� ���Դϴ�:

 

1.  ������(�ҽ�)Ŭ��������:

o �븮 Ÿ��(������ Ŭ���� ����� �븮�� Ŭ������ �ν��Ͻ�)�� �����ϴ� �ʵ尡 �����˴ϴ�.

o ���� ������ Ŭ������ �븮�� Ÿ�� Ŭ����/�������̽��� �������̵�/�����ϴ� �޼ҵ带 �����ϸ�, ���� Ŭ������ �����˴ϴ�.

o �븮�� Ÿ���� ���ӵ� �޼ҵ尡 �����˴ϴ�

o������ �븮 Ÿ�ٿ� �븮�����鼭�� �޼ҵ�� �����˴ϴ�.

o ����� ���ŵ˴ϴ�.

 

2.  ������ Ŭ���� �ν��Ͻ��� ��뿡��:


���� Generate getter for delegated component �� üũ�Ǹ�,  Å¬ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ������ Ŭ���� �ν��Ͻ� �����

����˴ϴ�.


����� �� ���� Ÿ������ �������ϴ�:

o not-delegated Ŭ���� ����� �ڰ��� �ִ� ���.
���� �����丵 ���� �׷� ����� ���̸� �ƹ��͵� ���� �ʽ��ϴ�.  ï¿½×¸ï¿½ï¿½ï¿½ ���� �� ����� ������ ������, ���� ���� ���Ե˴ϴ�.  ï¿½ï¿½ï¿½Í°ï¿½ ������(���� Generate getter for delegated component �� üũ���� ������) �׷��� ��쿡 ��ſ��� Problems Detected ���̾�αװ� ������Ʈ �� �� �Դϴ�.

 

o������ �Ҵ�ǰų�, �Ű� �����μ� �Ѿ�� ���.
 
�����丵 ���� ���� �ν��Ͻ� Ŭ������ Ÿ�� Ÿ��(�װ��� �Ҵ�� ������ ���� �Ǵ� �װ��� �Ѿ�� �� ����)���� �ƴϸ�, ���ʹ� ���� ���Ե˴ϴ�.  ï¿½ï¿½ï¿½ï¿½ ����(���� Generate getter for delegated component ï¿½ï¿½ üũ���� ������) �׷��� ��쿡 ��ſ��� Problems Detected ���̾�αװ� ������Ʈ �� �� �Դϴ�.

 

 

Ư���� �ּ�


������ �ּ��� ������ �� ��쿡 �־����ϴ�:

 1.   ï¿½ï¿½ï¿½ Ÿ�� Ÿ���� java.lang.Object ï¿½ï¿½ ��, IDEA�� ���� ���� �����ϴ��� �ƴ��� �˰� ���� �ʽ��ϴ�.

���� ���

 
public class ClassParent implements ParentInterface {
    public void method1(){
        method2();
    }
 
    public void method2(){
        //some code here
    }
}
 
public class ClassChild {
 
    public ClassParent classParent = new ClassParent();
 
    void methodInChild(){
        ArrayList list = new ArrayList();
        list.add(classParent);
 
        // some complicated code...
 
        ParentInterface intf = (ParentInterface) list.get(0);
        ClassParent p = (ClassParent) list.get(0);
    }
}
 

�̷� ��쿡, �ֿ� ������ ParentInterface intf = (ParentInterface) list.get(0); ï¿½Ç´ï¿½ 

ClassParent p = (ClassParent) list.get(0); ï¿½ß¿ï¿½ � ���� ��� ���ƿ��� ��� ��Ұ� ���߿� ���� ������

���� ���ϴ� ���� ��� ����� ( lis.add(classParent)  )�� �߰� �� �� IDEA�� ���͸� �ҷ��� �ϴ��� �ƴ��� ������

�ƹ��� ��Ұ� ���ٴ� �� �Դϴ�.


Problems Detected  ���������� ����� ���  method1  ���� �븮�ϰ� �ִ� ClassParent ï¿½ï¿½ï¿½ï¿½ �����丵�� �����ϸ�

 java.lang.Object ï¿½ï¿½ upcasting�� �õ��˴ϴ�.




�׸��� ���� ����� ����ϱ�� �����ϸ�, Instances upcast to Object ��� �ҷ����� ��� Find ï¿½ï¿½ï¿½ï¿½ ��ſ��� ��

�ν��Ͻ��� ������ ���Դϴ�.




�� ���� ���� �������� ���� ���˴ϴ�.


���� ����� �����丵�� �����ϱ�� �������� Refactoring preview ï¿½Ç¿ï¿½ï¿½ï¿½ Do Refactor�� �����ٸ�,
������ not-Object-upcast �ν��Ͻ��� ����� ���Դϴ�. 

 2.    �����丵�� �߻� Ŭ�������� ���� �� ���� ���� ��Ÿ���� �Ϳ� ���� Ư���� �� �ٸ� ��찡 �ֽ��ϴ�.  
public abstract class AbstractClass implements Runnable {
    void activity() {
        // ... some setup
        run();
        // ... some postprocessing
    }
}
 
public class ImplementationClass extends AbstractClass {
    public void run() {
        // do something useful
    }
}
 
�׸��� �����丵�� AbstractClass ���� �������̽� ����� �븮�ϱ� ���� ����˴ϴ�.  
 
public abstract class AbstractClass {
    private final MyRunnable runnable = new MyRunnable();
 
    void activity() {
        // ... some setup
        runnable.run();
        // ... some postprocessing
    }
 
    protected abstract void run();
 
    public Runnable getRunnable() {
        return runnable;
    }
 
    private class MyRunnable implements Runnable {
        public void run() {
            AbstractClass.this.run();
        }
    }
}

 

�����丵 ����, ������ ������ �����ϴ�:

 

*   �븮�� �����(��� �� �����丵 ��ɿ�)���� �ʵ�� �߰��˴ϴ�.

*   Ÿ�� �������̽��� �����ϰ� �ִ� ���� Ŭ������ �߰��˴ϴ�.
�߻� Ŭ������ ��쿡��, �������̽� �޼ҵ尡 ������ Ŭ����(����- AbstractClass)�� ���� Ŭ���� (����- ImplementationClass) ���� ������ �� �Դϴ�.  ï¿½ï¿½ï¿½ï¿½, �̸��� ''reverse delegation '�� ���� �Ʒ��� ������ �ٿ� ���� �޼��� �� �ִ� ���� Ŭ�����κ��� �� ���� Ŭ������ �޼ҵ��� ������ ����ؾ߸� �մϴ�.

*    ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ Ŭ������ �������̽� �� ����������� �߻� �޼ҵ�� ���ڿ� ������ �߰��˴ϴ�.  ï¿½×¸ï¿½ï¿½ï¿½ ���� Ŭ������ �������̽� ������ �� �޼ҵ带 �θ��ϴ�.  ï¿½Ì°ï¿½ï¿½ï¿½ ''reverse delegation '��� �Ҹ��ϴ�.


����, ����� �ൿ�� ������ ���� ���α׷� �մϴ�.
�� Ư¡�� Ŭ���� ������ �Բ� ������� ���� �Ϻ� ���ۿ� �����մϴ�.  ï¿½ï¿½ï¿½ï¿½ ���� ��� �ϳ��� Extract Superclass 

�����丵�� ������ �� �ֽ��ϴ�. ������ ����Ŭ������ runnable �� �ʵ�� �޼ҵ� activity �� �ű�ϴ�.