이제 원하는 기능을 수행하고 있으니, "2) 객체지향의 기본원리를 사용해서 소프트웨어를 유연하게 하라." 하도록 해봅시다.
책을 보면 3가지를 말하고 있습니다.
객체는 자신의 이름에 해당되는 일만 해야합니다. 자동차 객체는 전진 후진 기능은 있지만, 차를 사고 파는 기능은 자동차 객체에게는 필요없는 기능입니다.
이전 소스코드를 떠올려보면, Search함수의 매개변수로 Guitar객체를 사용하고 있습니다. 실제 비교에는 serialNumber와 price는 사용하지 않는데 말이죠.
즉 Search함수에서는 Guitar의 특정 속성만 필요하지만, Guitar객체 전체를 매개변수로 보내고 있기때문에 사용되지 않는 속성이 빈번히 일어나게 됩니다.
이렇게 사용되지 않는 속성이 많다면, 설계의 문제가 있음을 의심해 보아야 합니다.
Guitar객체에서 기타의 속성정보들을 분리하여 캡슐화하도록 하겠습니다.
다음 클래스다이어그램을 한번 보세요.
이전의 기타클래스에 필수적인 serialNumber와 pirce를 제외한 특성들에 해당되는 멤버변수를, GuitarSpec이라는 클래스로 묶어주었습니다.
멤버변수가 이동되었으니, Guitar객체의 해당 멤버변수 접근함수역시 옮겨줍니다.
그리고 Guitar객체 안에 GuitarSpec을 멤버객체로 가지게 하는것입니다.
다음은 변경된 소스코드 입니다.
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 | public class Guitar { private String serialNumber; private double price; GuitarSpec spec; public Guitar(String serialNumber, double price, Builder builder, String model, Type type, Wood backWood, Wood topWood) { this.serialNumber = serialNumber; this.price = price; this.spec = new GuitarSpec(builder, model, type, backWood, topWood); } public String getSerialNumber() { return serialNumber; } public double getPrice() { return price; } public void setPrice(float newPrice) { this.price = newPrice; } public GuitarSpec getSpec() { return spec; } } |
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 | public class GuitarSpec { private Builder builder; private String model; private Type type; private Wood backWood; private Wood topWood; public GuitarSpec(Builder builder, String model, Type type, Wood backWood, Wood topWood) { this.builder = builder; this.model = model; this.type = type; this.backWood = backWood; this.topWood = topWood; } public Builder getBuilder() { return builder; } public String getModel() { return model; } public Type getType() { return type; } public Wood getBackWood() { return backWood; } public Wood getTopWood() { return topWood; } } |
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 | public class Inventory { private List guitars; public Inventory() { guitars = new LinkedList(); } public void addGuitar(String serialNumber, double price, Builder builder, String model, Type type, Wood backWood, Wood topWood) { Guitar guitar = new Guitar(serialNumber, price, builder, model, type, backWood, topWood); guitars.add(guitar); } public Guitar getGuitar(String serialNumber) { for (Iterator i = guitars.iterator(); i.hasNext(); ) { Guitar guitar = (Guitar)i.next(); if (guitar.getSerialNumber().equals(serialNumber)) { return guitar; } } return null; } public List search(GuitarSpec searchSpec) { List matchingGuitars = new LinkedList(); for (Iterator i = guitars.iterator(); i.hasNext(); ) { Guitar guitar = (Guitar)i.next(); GuitarSpec guitarSpec = guitar.getSpec(); if (searchSpec.getBuilder() != guitarSpec.getBuilder()) continue; String model = searchSpec.getModel().toLowerCase(); if ((model != null) && (!model.equals("")) && (!model.equals(guitarSpec.getModel().toLowerCase()))) continue; if (searchSpec.getType() != guitarSpec.getType()) continue; if (searchSpec.getBackWood() != guitarSpec.getBackWood()) continue; if (searchSpec.getTopWood() != guitarSpec.getTopWood()) continue; matchingGuitars.add(guitar); } return matchingGuitars; } } |
자 이렇게 캡슐화를 하고 난 후에는, search()함수에 GuitarSpec객체만 넘겨주어 원하는 기타들을 찾을 수 있게 됩니다.
어떤가요. 앞서말한 말("객체는 자신의 이름에 해당되는 일만 해야 합니다")이 지켜진것 같나요?
이전과 같은 기능을 수행하지만, 프로그램은 더욱 유연해 졌습니다.
'프로그래밍(Programming) > 객체지향(Object-Oriented)' 카테고리의 다른 글
1장. 잘 설계된 프로그램이 세상을 뒤흔든다. - 5 (0) | 2013.10.22 |
---|---|
1장. 잘 설계된 프로그램이 세상을 뒤흔든다. - 3 (0) | 2013.10.21 |
1장. 잘 설계된 프로그램이 세상을 뒤흔든다. - 2 (0) | 2013.10.21 |
1장. 잘 설계된 프로그램이 세상을 뒤흔든다. - 1 (0) | 2013.10.21 |