IT/Secure Coding

잘못된 캡슐화

바바옄 2015. 4. 24. 14:51
반응형

1. 잘 못 사용되고 있는 캡슐화

클래스의 멤버변수로 자리잡고 있는 아래 두가지에 대해서는 getter/setter 의 내용을 변경해야 한다.

  •  배열
  •  Class

위 두 타입은 모두 "메모리 주소" 를 저장하고 있으므로, 일반적인 방법으로 캡슐화 하면 외부에서 값의 변경이 가능하다.

따라서 아래와 같이 변경되어야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
         // 배열
     public String[] getColors() {
         String[] newColor = new String[colors.length];
         System.arraycopy(colors, 0, newColor, 0, colors.length);
         return newColor;
     }  
     public void setColors(String[] colors) {
         String[] newColor = new String[colors.length];
         System.arraycopy(colors, 0, newColor, 0, colors.length);
         this.colors = newColor;
     }  
    // Class : 
     public Color getColors() {
         Color newColor = new Color();
         newColor = this.color.clone();
         return newColor;
     }  
     public void setColors(Color color) {
         Color newColor = new Color();
         newColor = color.clone();
         this.color = newColor;
     } 
cs

 

Encapsulation 프로젝트 생성.

Main.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
 * 어떤 클래스 안의 클래스의 데이터를 사용하기 위해서는 반드시 Cloneable을 사용해야 한다.
 * 배열은 Cloneable이 없기 때문에 새로운 배열을 생성하여 데이터를 복사한다.
 * 리스트도 배열과 같이 새로운 리스트에 데이터를 복제해서 사용하면 된다.
 */
 
public class Main {
 
    public static void main(String[] args){
        
        ClassRoom cr = new ClassRoom();
        
        
        int[] numbers = cr.getComputerNumbers();
        
        numbers[0= 11;
        numbers[1= 21;
        numbers[2= 31;
        numbers[3= 41;
        numbers[4= 51;
        
        cr.setComputerNumbers(numbers);
        numbers[3= 100;
        
        int[] numbers2 = cr.getComputerNumbers();
        
        for(int number : numbers2){
            System.out.println(number);
        }
        /*
        Computer computer = cr.getComputer();
        computer.setComputerNumber("20");
        
        cr.setComputer(computer);
        
        computer.setComputerNumber("30");
        
        System.out.println(cr.getComputer().getComputerNumber());
        System.out.println(computer.getComputerNumber());
        */
    }
}
 
cs


 ClassRoom.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import java.util.ArrayList;
import java.util.List;
 
/*
 * 어떤 클래스 안의 클래스의 데이터를 사용하기 위해서는 반드시 Cloneable을 사용해야 한다.
 * 배열은 Cloneable이 없기 때문에 새로운 배열을 생성하여 데이터를 복사한다.
 * 리스트도 배열과 같이 새로운 리스트에 데이터를 복제해서 사용하면 된다.
 */
 
public class ClassRoom {
 
    private Computer computer;
    private int[] computerNumbers;
    private List<Computer> computerList;
    
    public ClassRoom(){
        computer = new Computer();
        computer.setComputerNumber("10");
        
        computerNumbers = new int[5];
        computerNumbers[0= 10;
        computerNumbers[1= 20;
        computerNumbers[2= 30;
        computerNumbers[3= 40;
        computerNumbers[4= 50;
    }
    
    // 일반 변수 getter, setter
    public Computer getComputer() {
        
        return this.computer.getClone();
    }
 
    
    public void setComputer(Computer computer) {
        this.computer = computer.getClone();
    }
 
    // 배열 getter, setter
    public int[] getComputerNumbers() {
        
        int[] tempNumbers = new int[this.computerNumbers.length];
        
        for(int i=0; i<tempNumbers.length; i++){
            tempNumbers[i] = this.computerNumbers[i];
        }
        
        return tempNumbers;
    }
 
    public void setComputerNumbers(int[] computerNumbers) {
        
        int[] tempNumbers = new int[computerNumbers.length];
        
        for(int i=0; i<tempNumbers.length; i++){
            tempNumbers[i] = computerNumbers[i];
        }
                
        this.computerNumbers = tempNumbers;
    }
 
    // List getter, setter
    public List<Computer> getComputerList() {
        
        List<Computer> tempList = new ArrayList<Computer>();
        tempList.addAll(this.computerList);
        
        return tempList;
    }
 
    public void setComputerList(List<Computer> computerList) {
        
        List<Computer> tempList = new ArrayList<Computer>();
        tempList.addAll(computerList);
        
        this.computerList = tempList;
    }
    
    
    
    
}
 
cs

 

Computer.java 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.ObjectInputStream.GetField;
 
/*
 * 어떤 클래스 안의 클래스의 데이터를 사용하기 위해서는 반드시 Cloneable을 사용해야 한다.
 * 배열은 Cloneable이 없기 때문에 새로운 배열을 생성하여 데이터를 복사한다.
 * 리스트도 배열과 같이 새로운 리스트에 데이터를 복제해서 사용하면 된다.
 */
 
public class Computer implements Cloneable{
 
    private String computerNumber;
 
    public String getComputerNumber() {
        return computerNumber;
    }
 
    public void setComputerNumber(String computerNumber) {
        this.computerNumber = computerNumber;
    }
    
    public Computer getClone(){
        
        try {
            // 복제한 컴퓨터를 리턴
            return (Computer) this.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
        
    }
    
    // 클래스 복제 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        
        Computer computer = new Computer();
        computer.setComputerNumber(this.computerNumber);
        
        return computer;
    }
}
 
cs

 

반응형

'IT > Secure Coding' 카테고리의 다른 글

주기적인 비밀번호 변경  (1) 2015.04.24
잘못된 접근 제한(사용자의 행동 기록)  (0) 2015.04.24
로그인 제한  (0) 2015.04.24
Open Redirect  (0) 2015.04.23
Encrypt Password  (0) 2015.04.23