Monday, August 14, 2006

Hivemind #2

ลองดูเรื่อง Configuration บ้าง
concept ของ Configuration ใน Hivemind ก็คือ
เวลาเรานำ service ไปใช้, service ย่อมต้องการ parameter บางอย่าง
เพื่อที่จะได้กำหนดพฤติกรรมให้เหมาะกับสภาพแวดล้อมที่ service run อยู่

ใน Hivemind เราแบ่งส่วนของ configuration ออกเป็น 2 ส่วนคือ
  • ส่วนที่ difine นิยาม และการนำไปใช้
    เรียกตรงนี้ว่า Configuration Point
  • ส่วนที่ provide configuration data
    มีศัพท์เรียกว่า Contribution


ดูตัวอย่างดีกว่า
สมมติเรามี service ตัวหนึ่งชื่อ FooService
public interface FooService {

public void connect();

}


public class FooServiceImpl implements FooService {

private List<ServerInfo> serverInfos;

/**
*
@param serverInfo the serverInfo to set
*/

public void setServerInfos(List<ServerInfo> infos) {
this.serverInfos = infos;
}

/* (non-Javadoc)
* @see test.FooService#connect()
*/

public void connect() {
System.out.println("connect to " + serverInfos.get(0).getHost());
}
}


public class ServerInfo {
private String host;
private String port;
private String uri;

// setter & getter ..
}

ในตัวอย่างข้างบนนี้ serverInfos ก็คือ configuration point
ที่เราอยากให้สามารถปรับเปลี่ยนได้ตามบริบทที่ service นี้ไป run อยู่
ดังนั้นใน descriptor file ของเรา เราก็จะกำหนดดังนี้

เริ่มด้วยการกำหนด configuration point ก่อน
<configuration-point id="serverInfo" >
<schema>
<element name="serverInfo">
<attribute name="host" required="true"/>
<attribute name="port" required="false"/>
<attribute name="uri" required="true"/>
<conversion class="test.ServerInfo"/>
</element>
</schema>
</configuration-point>

ให้สังเกตว่าเรามีการ define schema ของรูปแบบของข้อมูลด้วย

จากนั้นก็กำหนดบอกว่า FooService เราต้องการ information จาก configuration-point นี้นะ
<service-point id="foo" interface="FooService">
<invoke-factory>
<construct class="impl.FooServiceImpl">
<set-configuration property="serverInfos" configuration-id="serverInfo"/>
</construct>
</invoke-factory>
</service-point>

สุดท้าย เวลาที่เราต้องการ customize กำหนดค่า serverInfo
เราจะทำผ่าน contribution
โดยรูปแบบข้อมูล ต้องตรงตามที่กำหนดเป็น schema ไว้ใน configuration-point
<contribution configuration-id="serverInfo">
<serverInfo host="128.1.1.10" uri="/app/service"/>
</contribution>


ลองเปรียบเทียบกับ spring บ้าง
ตามตัวอย่างข้างบนนี้ spring จะเขียนเป็นแบบนี้
<bean id="fooService" class="test.impl.FooServiceImpl">
<property name="serverInfos">
<list>
<bean class="test.ServerInfo">
<property name="host" value="128.1.1.10"/>
<property name="uri" value="/app/service"/>
</bean>
</list>
</property>
</bean>


ดูแค่นี้ ก็จะเห็นว่า spring มี configuration ที่ดูเข้าใจง่ายกว่า (จริงๆแล้วขึ้นกับว่า ผู้ดูเป็นใคร?)

แต่ hivemind มีข้อได้เปรียบกว่า spring ตรงที่
contribution ของ hivemind มัน auto-discovery ได้
คือเราสามารถแยก component ออกเป็น module ย่อยๆ
โดยแต่ละ module ก็มี descriptor file ของตัวเอง
ดังนั้นเราอาจจะ package service ไว้ใน module หนึ่ง
แล้วอาจจะ pack contribution ไว้ในอีก module หนึ่ง
เมื่อ registry ของ hivemind load ขึ้นมา มันจะมองหา
descriptor file ที่อยู่ใน classpath ทั้งหมด แล้วประกอบขึ้นมาเป็น registry ให้โดยอัติโนมัติ

Related link from Roti

No comments: