Thursday, August 02, 2007

Daily thoughts - 4



Enum as dispatcher
   Днес доработвах един код и ми хрумна идея. Какво ще стане ако се наложи да се направят две различни операции по даден критерий? В моя случай критерия е дали обекта е получен от XML или HTML файл. В зависимост се тръгва по две отделни "пътеки" да ги наречем (някъде навътре в бизнес логиката). Естественно първото нещо, което хрумва е да се приложи Factory pattern. Идеята не е никак лоша ако "пътеките" са дълги, резултатните обекти са много различни и се очаква критериите да набъбват. Тогава много лесно може да се добави трети обект в йерархията. Картинката е:


+-------------+
| |
| BaseObject |
+-------------+
^ ^ ^
+---| | |------+
| | |
| | |
XMLObject HTMLObject NextObject

Имайки тази йерархия следва и да имам дипечер, който да казва какво да се истанцира. Нещо такова:

public class ObjectFactory {
.........
public static ObjectReader getObjectReader( InputStream is ) {
int objectType = figureOutObjectType( is );

switch( objectType ) {
case ObjectReaderFactory.XML:
return new XMLReader( is );
case ObjectReaderFactory.HTML:
return new HTMLReader( is );
..........
// etc.
}
}
}

Да ама при мен ситуацията се различава - двата обекта са почти идентични. Те се различават само по едно единственно действие - операцията diff. Ако е XML се пуска някъде в "пътеката" xmldiff.py ако не, htmldiff.py. Ще имам само на едно място if. Не мога ли да сложа действието в типа. Така измествам фокуса. Естественно щом имам изброим брой действия най-добре да си ползвам enum. Хехе там лесно мога да дефинирам и операцията в зависимост от типа:

public enum DiffType {

XML {

String diffProgram()
{
return FileConstants.PYTHON_XMLDIFF_PROGRAM;
}
},

HTML {

String diffProgram()
{
return FileConstants.PYTHON_HTMLDIFF_PROGRAM;
}
};

// declare the methods defined by this enum
public abstract String diffProgram();
}

Ееее от тук нататък е лесно.


private void diffFilePrepare(final MobileOperator operator) throws IOException
{
.........
// dispach by type
diffMaker.madeDiffDisplay(operator.getDiffType());
.........
}


public void madeDiffDisplay(DiffType type) throws IOException
{
.........
try {
pythonLine[0] = "python";
pythonLine[1] = type.diffProgram();

.........
} catch (InterruptedException e) {
log.error("External program was interupted.");
}

}


Така хем си знам типа, хем и операцията за този тип. По-четимо го намирам. Е, разбира се то това е частен случай. Иначе Factory pattern rulez!

No comments:

algorithms (1) cpp (3) cv (1) daily (4) emacs (2) freebsd (4) java (3) javascript (1) JSON (1) linux (2) Lisp (7) misc (8) programming (16) Python (4) SICP (1) source control (4) sql (1) думи (8)