简体   繁体   中英

When is the right time to use generic classes in Java

I'm building a rest interface in an existing project. The project has a class that defines about 4 different types of operations. Each operation takes a different type of object to define the query parameters. Each operation returns a different type of object, all of which are XML jaxb encoded objects and end up getting marshalled to an OutputStream.

I am parsing parameters out of the URL and building the query objects required for the various operations. Currently, I have an abstract Query parent class, a QueryFactory class that switches between query types and returns a child Query class specific to the type of request in the URL. All the child query classes implement an abstract "buildQueryParameters" method and get the result as an Object type.

Is that as good as it gets? Is there some fancy way to use parameterized types or generic classes to build my query parameters objects? I find myself building these switch statements all over my code to differentiate between the request types and I'm not sure if that's the best way...

Edit:

I'm subclasses because my servlet code looks like this:

Query query = QueryFactory.getInstance(parameterMap, requestEnum);
query.buildQueryParams();
Object queryParams = query.getQueryParams();

Query factory is pretty straight forward:

 public static Query getInstance(Map<String, String> parameterMap, RequestEnum requestEnum) {
        switch (requestEnum) {
            case GETSTATUS: {
                return new GetStatusQuery(parameterMap);
            }
            case DESCRIBEOPS: {
                return new DescribeOpsQuery(parameterMap);
            }
            case GETSTATUSBYID: {
                return new GetStatusByIdQuery(parameterMap);
            }
            case GETEVENTS: {
                return new GetEventsQuery(parameterMap);
            }
            default:
                break;
        }
        return null;
    }

The abstract Query class is also boring:

public abstract class Query {

    protected Map<String, String> validatedMap;
    private Object queryParams;

    public SOSQuery(Map<String, String> parameterMap) {
            this.parameterMap = parameterMap;
        }

        public Object getQueryParams() {
            return this.queryParams;
        }

        public abstract void buildQueryParams();

        protected void setQueryParams(Object queryParams) {
            this.queryParams = queryParams;
        }

        protected Map<String, String> getParameterMap() {
            return this.parameterMap;
        }

Each child class implements the buildQueryParams() method and creates the specific objects required for each different type of request/operation and returns them as objects, which the marshaller has no problem handling, so I don't necessarily need to be more specific with the return types.

you can declare public abstract class SOSQuery<T> { and then private T queryParams;

public T getQueryParams() {
    return this.queryParams;
}

and so on ...

for the subclasses you would declare

public class GetStatusQuery extends SOSquery<GetStatusParticularType> {

is this what you need?

I wouldn't recommend parsing URLs yourself. All the binding can be automatic using JAXB and JAX-RS.

Example:

Define the services:

@Path("/app")
@Produces("application/xml")
public interface TestService {      
    @POST
    @Consumes("text/xml")
    @Path("/addType")
    public Policy setTypePolicy(Policy p);

    @GET
    @Path("/server/{server}/service")
    public Services getTypesOnServer(@PathParam("server") String serverName);
}

Define the model:

<element name="policy">
    <complexType>
    <sequence>
            <element name="name" type="string" />
            ...
        </sequence>
   </complexType>
</element>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM