2018년 12월 15일 토요일

개발덕후 남편과 함께 상암 누리꿈스퀘어에서 진행한 [마소콘 2018 - 기술부채 회고] 를 다녀왔다. 

https://www.imaso.co.kr/masocon2018/


기술부채는 진행 할 수 있지만, 일정 또는 기타 사정으로 인해 진행하지 못하는 일종의 빚 같은 개념이다.

이 주제로 세미나와 컨퍼런스를 진행을 해 주셨다.


기술부채를 해결하기 위해서는 팀원들간의 협업, 소스코드 리뷰의 중요성이 이 컨퍼런스의 핵심이라고 생각한다.
실제로 SI업계에서 6년을 일했는데, 저 위의 핵심들은 분명 모든 임직원들이 인지할 것이라고 생각한다.
하지만 갑님이 제시하는 지나치게 힘든 일정과 무리한 일정요구로 인해 할 수 없는 환경이 핵심인 듯 싶다.
실제로 소기업이 할 수 있는 기술부채 탕감 방안을 제안해 주었어도 괜찮았을 것 같다.

컨퍼런스 세션에 대한 기록은 남편이 했으니 링크를 따라가서 보는 것을 추천한다.

남편 블로그는  github jekyll blog 로 구성되어있다. 주로 기술에 대한 내용을 서술한다.

(사실 난 재미없음)

http://jmlim.github.io/%EB%A7%88%EC%86%8C%EC%BD%98/2018/12/17/masocon-2080/






Java의 Collection은 기본적으로 얕은 복사(shallow copy)는 제공하나 깊은 복사기능은 제공하지 않는다. 즉, 원본 목록과 복제된 목록에 저장된 객체가 동일하고 그렇다는것은 Java 힙 공간에서 동일한 메모리 위치를 가리켜 문제가 될 수 있다.

예를 들면 직원 정보가 들어있는 ArrayList의 생성자를 사용하여 복제시엔 직원 객체 정보는 그대로 있으므로 복제된 list의 객체를 수정시에 같이 영향을 받게 된다.

아래 예제이다.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CollectionCloningTest {
    public static void main(String args[]) { 
        List<Employee> org = new ArrayList<>();
        org.add(new Employee("MA", "Manager"));
        org.add(new Employee("AH", "Developer"));
        org.add(new Employee("JM", "Developer"));

        // 생성자를 통해 copy list 생성.
        List<Employee> copy = new ArrayList<>(org);

        System.out.println("ORG LIST : " + org);
        System.out.println("COPY LIST : " + copy);

        Iterator<Employee> itr = org.iterator();
        while (itr.hasNext()) {
            itr.next().setDesignation("Specialist");
        }

        //org list 에 해당하는 값을 바꿨으나 copy list 에 들어있는 객체값도 같이 바뀌게 된다.
        System.out.println("ORG LIST : " + org);
        System.out.println("COPY LIST : " + copy);
    }
}

class Employee {
    private String name;
    private String designation;

    public Employee(String name, String designation) {
        this.name = name;
        this.designation = designation;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return String.format("%s: %s", name, designation);
    }
}
  • 출력값 : org list 에 해당하는 값을 바꿨으나 copy list 에 들어있는 객체값도 같이 바뀌게 된다.

    ORG LIST : [MA: Manager, AH: Developer, JM: Developer]
    COPY LIST : [MA: Manager, AH: Developer, JM: Developer]
    ORG LIST : [MA: Specialist, AH: Specialist, JM: Specialist]
    COPY LIST : [MA: Specialist, AH: Specialist, JM: Specialist]

복제본이 단순 복사이고 힙의 동일한 Employee 개체를 가리 키기 때문에 원본 컬렉션의 Employee 개체 ( “Specialist”로 변경된 지정)가 복제 된 컬렉션에도 반영되어 있음을 확인할 수 있다. 
이 문제를 해결하려면 Collection을 반복할 시 Employee 객체를 깊게 복제해야하며 그 전에 Employee 객체의 복제 메소드를 재정의해서 넣어야한다.

해결방법

1) 객체 복사를 할 수 있도록 하는 인터페이스 구현 (Employee가 Cloneable 인터페이스를 구현하도록 한다.) 2) Employee 클래스에 clone() 메소드 추가

/** 1. 기존 Employee 클래스에 Cloneable을 구현하도록 추가. 2. clone 메소드 구현. */

class Employee implements Cloneable {
    private String name;
    private String designation;

    public Employee(String name, String designation) {
        this.name = name;
        this.designation = designation;
    }

    public String getDesignation() {
        return designation;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return String.format("%s: %s", name, designation);
    }

    @Override
    public Employee clone() {
        Employee clone = null;
        try {
            clone = (Employee) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        return clone;
    }
}

생성자를 사용하여 List를 복사하는 대신 다음 코드를 사용하여 Java에서 콜렉션 전체 복사

public class CollectionCloningTest {
    public static void main(String args[]) { // deep cloning Collection in Java
		....위와 같은 로직...
			
		//deep copy 로직
		List<Employee> deepCopy = new ArrayList<>(org.size());
		Iterator<Employee> iterator = org.iterator();
		while (iterator.hasNext()) {
			deepCopy.add(iterator.next().clone());
		}

		//deepCopy list 에 해당하는 값을 바꿨으나 org list 에 있는 객체값이 영향을 받지 않는다..
		deepCopy.get(0).setDesignation("Expert");

		System.out.println("ORG LIST : " + org);
		System.out.println("DEEP COPY LIST : " + deepCopy);
	}
}

참고자료



[출처]

http://jmlim.github.io/java/2018/12/13/java-deep-copy/


+ Recent posts