經過上一篇咱們得到到了通過認證的OSClient
,經過這個接口,咱們就使用openstack4j的全部功能了。但openstack4j是一個用來便於咱們更方便調用openstack的sdk,也就是說主要是進行資源請求的處理。在對資源進行操做以前,首先須要生成資源的對象,下面來看看openstack4j中的model設計。(以server
來講明)spring
在接口調用時,爲了方便業務處理時的代碼編寫,咱們都會用DTO的類來處理咱們的請求參數。在openstack4j中,請求model就在org.openstack4j.model.compute
這個包下。但在這裏只是接口,具體的實現則是在org.openstack4j.openstack.compute.domain
下。json
server model的最主要接口是org.openstack4j.model.compute.server
,這個接口中包含了server的全部信息。api
public interface Server extends ModelEntity { public enum Status {} String getId(); String getName(); Addresses getAddresses(); Image getImage(); }
使用接口而不是直接使用一個DTO類,能夠更好兼容因openstack版本變動形成的server property變化。須要注意的是,在Server接口中,getIMage()
方法獲取到的IMage
接口,並非鏡像model的接口org.openstack4j.model.image.Image
,而是屬於server包下的model.compute.Image
。也就是說,server封裝了一個本身的image對象,而不是和與他平級的image共享。表面看起來是有兩個image接口,顯得代碼冗餘。但model.compute.server
和org.openstack4j.model.image.Image
需求的鏡像顆粒度不一樣,這樣作的好處是耦合度低,代碼更加分離。dom
Server接口的具體實現類是org.openstack4j.openstack.compute.domain.NovaServer
。ui
建立Server的model對象時,使用Builder模式。他的好處是不直接生成想要的對象,而由調用者利用全部必要的參數來調用構造器。server的model有兩個頂部接口,一個是model.compute.server
,一個是model.compute.sverCreate
,分別對於server資源的查詢和建立。spa
ServerCreate server = Builders.server() .name("Ubuntu 2") .flavor("large") .image("imageId") .build();
serverCreate對應的類關係圖:設計
其中Builders位於org.openstack4j.api包下,Builders中能夠獲取到全部資源的對象構建器。由此資源構建器(ServerCreateBuilder)能夠構造具體的資源。
這兒設計比較好的是這個構建器,使用了多態的方式來設計構建器,能夠作到很好的可替換性和可擴充性,在程序處理中,也會更加簡化和靈活。code
model.compute.server
的實現比較簡單,只是用於承接openstack server資源查詢的返回值。
有一點能夠注意下,NovaServer的內部類Servers,他的惟一方法就是value(),用於返回一個列表類型的NovaServer。這種設計能夠在不少好的開源系統裏面看獲得。對於經常使用的model類的封裝,能夠在其內部類完成,減小代碼冗餘,在閱讀上效果也更好。server
在model.compute.server
接口中,有個枚舉類Status,是server的狀態枚舉。提這一點是由於我常常在項目中看到同事定義枚舉類時會專門定義個enums包,而後將全部的枚舉類都提出來放到這個包下。其實更好的設計是相似openstack4j這樣,對於某個資源的枚舉,最好是做爲資源的內部類存在,而不是再單獨定義一個ServerStatus的枚舉類。這樣代碼的可讀性和可維護性會更高。xml
openstack4j的json處理和spring同樣,使用了fasterxml.jackson來進行json的轉換。
@JsonRootName("server") @JsonIgnoreProperties(ignoreUnknown=true) public class NovaServer implements Server { public String id; @JsonProperty("tenant_id") public String tenantId; @JsonProperty("user_id") public String userId; }