经过上一篇咱们得到到了通过认证的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; }