2012-11-25 28 views
6

Tôi đang làm việc trên Ứng dụng Android (Java) sử dụng API của Trình phát Blu-ray Yamaha qua HTTP POST. Trình phát có lệnh nghiêm ngặt được đặt ở định dạng XML. Các lệnh tuân theo một hệ thống phân cấp: trong khi hầu hết các phần tử XML bên ngoài luôn giống nhau, cấu trúc bên trong thuộc về loại chức năng của trình phát. Ví dụ, các chức năng play/pause/stop có cùng một đường dẫn trong XML, trong khi các hàm bỏ qua có các phần tử cha khác. Bạn có thể thấy những gì tôi có ý nghĩa trong ví dụ mã sau đây.Cách tốt nhất để xác định cấu trúc lớp/đối tượng/enum lồng nhau trong Java là gì?

public enum BD_A1010 implements YamahaCommand 
{ 
    POWER_ON ("<Main_Zone><Power_Control><Power>On</Power></Power_Control></Main_Zone>"), 
    POWER_OFF ("<Main_Zone><Power_Control><Power>Network Standby</Power></Power_Control></Main_Zone>"), 
    TRAY_OPEN ("<Main_Zone><Tray_Control><Tray>Open</Tray></Tray_Control></Main_Zone>"), 
    TRAY_CLOSE ("<Main_Zone><Tray_Control><Tray>Close</Tray></Tray_Control></Main_Zone>"), 
    PLAY ("<Main_Zone><Play_Control><Play>Play</Play></Play_Control></Main_Zone>"), 
    PAUSE ("<Main_Zone><Play_Control><Play>Pause</Play></Play_Control></Main_Zone>"), 
    STOP ("<Main_Zone><Play_Control><Play>Stop</Play></Play_Control></Main_Zone>"), 
    SKIP_REVERSE ("<Main_Zone><Play_Control><Skip>Rev</Skip></Play_Control></Main_Zone>"), 
    SKIP_FORWARD ("<Main_Zone><Play_Control><Skip>Fwd</Skip></Play_Control></Main_Zone>"); 

    private String command; 

    private BD_A1010 (String command) 
    { 
     this.command = command; 
    } 

    public String toXml() 
    { 
     return "<?xml version=\"1.0\" encoding=\"utf-8\"?><YAMAHA_AV cmd=\"PUT\">" + this.command + "</YAMAHA_AV>"; 
    } 
} 

Như bạn có thể thấy, tôi đã thử cách enum phẳng, hoạt động tốt. Tôi có thể sử dụng các enums với lớp RemoteControl của tôi giống như vậy:

remoteControl.execute(BD_A1010.PLAY); 

Phương thức .toXml() của enum trả về mã XML đầy đủ cần thiết để gửi cho trình phát. Bây giờ đây là vấn đề của tôi: Tôi cần một cách tốt hơn để xây dựng hệ thống phân cấp hàm trong các lớp Java. Tôi muốn sử dụng nó như thế:

remoteControl.execute(BD_A1010.Main_Zone.Power_Control.Power.On); 

Giống như lồng ghép hoặc lớp học. Mỗi cấp của lệnh phải xác định phần tử XML của nó bên trong chính nó. Ngoài ra, mỗi lệnh trên một đường dẫn chỉ có thể xác định các lệnh phụ có thể: ví dụ, sau Main_Zone.Play_Control tôi chỉ có thể sử dụng .Play hoặc .Skip, không phải .Tray hoặc bất kỳ thứ gì khác. Vào cuối chuỗi, tôi muốn gọi .toXml() để nhận được lệnh XML đầy đủ.

Cách tốt nhất trong Java để xác định lớp học này là lớp lồng nhau (lồng nhau) là gì? Nên dễ xác định - càng ít mã càng tốt.

Sau đó, bạn có thể hợp nhất hai hoặc nhiều lệnh để có được một XML kết hợp như sau - nhưng điều đó không quan trọng đối với lần thử đầu tiên.

remoteControl.execute(
    BD_A1010.Main_Zone.Power_Control.Power.On, 
    BD_A1010.Main_Zone.Play_Control.Skip.Rev, 
    BD_A1010.Main_Zone.Play_Control.Play.Pause 
); 

<Main_Zone> 
    <Power_Control> 
     <Power>On</Power> 
    </Power_Control> 
    <Play_Control> 
     <Skip>Rev</Skip> 
     <Play>Pause</Play> 
    </Play_Control> 
</Main_Zone> 
+0

vấn đề là gì khi bạn mô tả, tôi muốn lồng ghép enum vào một enum khác? – maks

+0

Ngoài ra, giao diện YmanaCommand có định nghĩa phương thức toXml không? – maks

+0

Theo như tôi biết, các enums lồng nhau là không thể trong Java, phải không? –

Trả lời

6

Tại sao nó phải được enum? Builder pattern để giải cứu. Hãy xem xét hương vị này: http://www.drdobbs.com/jvm/creating-and-destroying-java-objects-par/208403883?pgno=2 thay vì vanilla một. Việc cải thiện cốt lõi là cú pháp rất dễ đọc:

builder.withProperty(...).withFeature(...).finallyWith(...) 
+0

Tôi đồng ý, một ví dụ tốt bạn có thể tìm thấy trong Kerievsky của "Refactoring to Patterns" - "Encapsulate Composite with Builder" (p. 96 - 113) – s106mo

+0

@ s106mo cảm ơn vì liên kết đến cuốn sách –

+0

Không tệ, tôi sẽ xem xét nó. Cảm ơn! –

Các vấn đề liên quan