通过上一篇我们获得到了经过认证的OSClient,通过这个接口,我们就使用openstack4j的所有功能了。但openstack4j是一个用来便于我们更方便调用openstack的sdk,也就是说主要是进行资源请求的处理。在对资源进行操作之前,首先需要生成资源的对象,下面来看看openstack4j中的model设计。(以server来说明)

model对象接口

在接口调用时,为了方便业务处理时的代码编写,我们都会用DTO的类来处理我们的请求参数。在openstack4j中,请求model就在org.openstack4j.model.compute这个包下。但在这里只是接口,具体的实现则是在org.openstack4j.openstack.compute.domain下。

server model的最主要接口是org.openstack4j.model.compute.server,这个接口中包含了server的所有信息。

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.serverorg.openstack4j.model.image.Image需求的镜像颗粒度不同,这样做的好处是耦合度低,代码更加分离。

Server接口的具体实现类是org.openstack4j.openstack.compute.domain.NovaServer

model对象生成

创建Server的model对象时,使用Builder模式。他的好处是不直接生成想要的对象,而由调用者利用所有必要的参数来调用构造器。server的model有两个顶部接口,一个是model.compute.server,一个是model.compute.sverCreate,分别对于server资源的查询和创建。

  1. serverCreate
ServerCreate server = Builders.server()
                        .name("Ubuntu 2")
                        .flavor("large")
                        .image("imageId")
                        .build();

serverCreate对应的类关系图:
此处输入图片的描述

其中Builders位于org.openstack4j.api包下,Builders中可以获取到所有资源的对象构建器。由此资源构建器(ServerCreateBuilder)可以构造具体的资源。
这儿设计比较好的是这个构建器,使用了多态的方式来设计构建器,可以做到很好的可替换性和可扩充性,在程序处理中,也会更加简化和灵活。

  1. server

model.compute.server的实现比较简单,只是用于承接openstack server资源查询的返回值。
此处输入图片的描述
有一点可以注意下,NovaServer的内部类Servers,他的唯一方法就是value(),用于返回一个列表类型的NovaServer。这种设计可以在很多好的开源系统里面看得到。对于常用的model类的封装,可以在其内部类完成,减少代码冗余,在阅读上效果也更好。

model.compute.server接口中,有个枚举类Status,是server的状态枚举。提这一点是因为我经常在项目中看到同事定义枚举类时会专门定义个enums包,然后将所有的枚举类都提出来放到这个包下。其实更好的设计是类似openstack4j这样,对于某个资源的枚举,最好是作为资源的内部类存在,而不是再单独定义一个ServerStatus的枚举类。这样代码的可读性和可维护性会更高。

json处理

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;
}

ithaka
29 声望4 粉丝

我带着蝉壳,逢初八,去往三月的庙会