jasu's blog
블로그 메뉴
2007. 8. 24. 18:43
글
[AS3] Head First - OOAD AS3로 변환
Programming/ActionScript 3.0
2007. 8. 24. 18:43
Head First 시리즈 중에 설계를 위한 객체지향 방법론에 관한 내용을 담고 있는 『Head First Object-Oriented Analysis&Design』 이라는 책이 있다. 책에서 사용한 언어는 Java언어인데 내용 중 기타 판매점의 기타검색 프로그램을 AS3로 수정하였다. 비교적 간단한 구조를 가지고 있지만 막상 하나의 문제를 해결하기 위해 필요한 기능을 구현하고 재사용성이 용이한 구조로 설계하려고 하면 어려움이 많이 발생하는 것 같다. AS3로 변환 과정에서 Java의 enum(열거형 타입 Builder, Type, Wood)는 각 클래스의 static const속성으로 변환하였다.
이 구조는 책의 2장까지 나와 있는 내용 중에서 final 버전이다. 책에서는 이 프로그램을 객체지향의 원리
(변하는 것을 캡슐화하라,
구현에 의존하기 보다는 인터페이스에 의존하도록 코딩하라,
각 클래스는 변경 요인이 오직 하나이어야 한다.)
에 입각해서 다시 5장에서 리펙토링하게 되는데 그 버전은 다음에 바꿔볼 생각이다. 어떤 문제를 풀 때 역행으로 분석해 보는 것도 상당히 도움이 된다.
// FindGuitarTester .as
// Guitar.as
// Builder.as
이 구조는 책의 2장까지 나와 있는 내용 중에서 final 버전이다. 책에서는 이 프로그램을 객체지향의 원리
(변하는 것을 캡슐화하라,
구현에 의존하기 보다는 인터페이스에 의존하도록 코딩하라,
각 클래스는 변경 요인이 오직 하나이어야 한다.)
에 입각해서 다시 5장에서 리펙토링하게 되는데 그 버전은 다음에 바꿔볼 생각이다. 어떤 문제를 풀 때 역행으로 분석해 보는 것도 상당히 도움이 된다.
// FindGuitarTester .as
package{
import flash.display.Sprite;
public class FindGuitarTester extends Sprite{
private var inventory:Inventory;
private var whatErinLikes:GuitarSpec;
private var matchingGuitars:Array;
public function FindGuitarTester():void{
inventory = new Inventory();
initialize();
}
private function initialize():void{
initializeInventory(inventory);
whatErinLikes = new GuitarSpec(Builder.FENDER, "Stratocastor", Type.ELECTRIC, 6, Wood.ALDER, Wood.ALDER);
matchingGuitars = inventory.search(whatErinLikes);
if (matchingGuitars != null) {
trace("Erin, you might like these guitars:");
var len:int = matchingGuitars.length;
for (var i:int=0;i<len;i++) {
var guitar:Guitar = matchingGuitars[i];
var spec:GuitarSpec = guitar.getSpec();
trace(" We have a " +
spec.getBuilder() + " " + spec.getModel() + " " +
spec.getType() + " guitar:\n " +
spec.getBackWood() + " back and sides,\n " +
spec.getTopWood() + " top.\n You can have it for only $" +
guitar.getPrice() + "!\n ----");
}
} else {
trace("Sorry, Erin, we have nothing for you.");
}
}
private function initializeInventory(inventory:Inventory):void {
inventory.addGuitar("11277", 3999.95, new GuitarSpec(Builder.COLLINGS, "CJ", Type.ACOUSTIC, 6, Wood.INDIAN_ROSEWOOD, Wood.SITKA));
inventory.addGuitar("V95693", 1499.95, new GuitarSpec(Builder.FENDER, "Stratocastor", Type.ELECTRIC, 6, Wood.ALDER, Wood.ALDER));
inventory.addGuitar("V9512", 1549.95, new GuitarSpec(Builder.FENDER, "Stratocastor", Type.ELECTRIC, 6, Wood.ALDER, Wood.ALDER));
inventory.addGuitar("122784", 5495.95, new GuitarSpec(Builder.MARTIN, "D-18", Type.ACOUSTIC, 6, Wood.MAHOGANY, Wood.ADIRONDACK));
inventory.addGuitar("76531", 6295.95, new GuitarSpec(Builder.MARTIN, "OM-28", Type.ACOUSTIC, 6, Wood.BRAZILIAN_ROSEWOOD, Wood.ADIRONDACK));
inventory.addGuitar("70108276", 2295.95, new GuitarSpec(Builder.GIBSON, "Les Paul", Type.ELECTRIC, 6, Wood.MAHOGANY, Wood.MAHOGANY));
inventory.addGuitar("82765501", 1890.95, new GuitarSpec(Builder.GIBSON, "SG '61 Reissue", Type.ELECTRIC, 6, Wood.MAHOGANY, Wood.MAHOGANY));
inventory.addGuitar("77023", 6275.95, new GuitarSpec(Builder.MARTIN, "D-28", Type.ACOUSTIC, 6, Wood.BRAZILIAN_ROSEWOOD, Wood.ADIRONDACK));
inventory.addGuitar("1092", 12995.95, new GuitarSpec(Builder.OLSON, "SJ", Type.ACOUSTIC, 12, Wood.INDIAN_ROSEWOOD, Wood.CEDAR));
inventory.addGuitar("566-62", 8999.95, new GuitarSpec(Builder.RYAN, "Cathedral", Type.ACOUSTIC, 12, Wood.COCOBOLO, Wood.CEDAR));
inventory.addGuitar("6 29584", 2100.95, new GuitarSpec(Builder.PRS, "Dave Navarro Signature", Type.ELECTRIC, 6, Wood.MAHOGANY, Wood.MAPLE));
}
}
}
// Inventory.as
package{ public class Inventory{ private var guitars:Array; public function Inventory():void{ guitars = new Array(); } public function addGuitar(serialNumber:String, price:Number, spec:GuitarSpec):void{ var guitar:Guitar = new Guitar(serialNumber, price, spec); guitars.push(guitar); } public function getGuitar(serialNumber:String):Guitar{ var len:int = guitars.length; for(var i:int=0;i<len;i++){ if(guitars[i].getSerialNumber() == serialNumber){ return guitars[i]; } } return null; } public function search(searchSpec:GuitarSpec):Array{ var matchingGuitars = new Array(); var len:int = guitars.length; for(var i:int=0;i<len;i++){ if(guitars[i].getSpec().matches(searchSpec)){ matchingGuitars.push(guitars[i]); } } return matchingGuitars; } } }
// GuitarSpec.as
package { public class GuitarSpec { private var builder:String; private var model:String; private var type:String; private var numStrings:int; private var backWood:String; private var topWood:String; public function GuitarSpec(builder:String, model:String, type:String, numStrings:int, backWood:String, topWood:String) { this.builder = builder; this.model = model; this.type = type; this.numStrings = numStrings; this.backWood = backWood; this.topWood = topWood; } public function getBuilder():String { return builder; } public function getModel():String { return model; } public function getType():String { return type; } public function getNumStrings():int { return numStrings; } public function getBackWood():String { return backWood; } public function getTopWood():String { return topWood; } public function matches(otherSpec:GuitarSpec):Boolean { if (builder != otherSpec.getBuilder()) { return false; } if ((model != null) && (model !="") && (model.toLowerCase() != (otherSpec.getModel().toLowerCase()))) { return false; } if (type != otherSpec.getType()) { return false; } if (numStrings != otherSpec.getNumStrings()) { return false; } if (backWood != otherSpec.getBackWood()) { return false; } if (topWood != otherSpec.getTopWood()) { return false; } return true; } } }
// Guitar.as
package{ public class Guitar{ private var serialNumber:String; private var price:Number; private var spec:GuitarSpec; public function Guitar(serialNumber:String, price:Number, spec:GuitarSpec):void{ this.serialNumber = serialNumber; this.price = price; this.spec = spec; } public function getSerialNumber():String{ return serialNumber; } public function getPrice():Number{ return price; } public function setPrice(newPrice:Number):void{ price = newPrice; } public function getSpec():GuitarSpec{ return spec; } } }
// Builder.as
package{ public class Builder{ public static const FENDER = "Fender"; public static const MARTIN = "Martin"; public static const GIBSON = "Gibson"; public static const COLLINGS = "Collings"; public static const OLSON = "Olson"; public static const RYAN = "Ryan"; public static const PRS = "PRS"; } }// Wood.as
package{ public class Wood{ public static const INDIAN_ROSEWOOD = "Indian Rosewood"; public static const BRAZILIAN_ROSEWOOD = "Brazilian Rosewood"; public static const MAHOGANY = "Mahogany"; public static const MAPLE = "Maple"; public static const COCOBOLO = "Cocobolo"; public static const CEDAR = "Cedar"; public static const ADIRONDACK = "Adirondack"; public static const ALDER = "Alder"; public static const SITKA = "Sitka"; } }// Type.as
package{ public class Type{ public static const ACOUSTIC = "acoustic"; public static const ELECTRIC = "Belectric"; } }