重用Java对象以避免重复工作?

时间:2014-01-03 16:03:29

标签: java design-patterns

每次,在向HTTP服务器发送请求之前,我需要创建一个java bean并设置其成员的值,然后将其转换为XML,因为该服务器只接受格式化为XML的数据。这个java bean有一些常见的成员值,我不想为每个请求创建一个新实例。

起初,我想到了 Prototype 设计模式,但在阅读“Effective java”后,我认为它不起作用。

还有其他建议吗?

谢谢,并且有一些代码可以说清楚:

    /**  
 * @Title: SSOManager.java
 * @Prject: TIJDemo
 * @Package: com.common
 * @Description: TODO
 * @author: Administrator  
 * @date: 2014-1-4 上午7:58:32
 * @version: V1.0  
 */
package com.common;

import java.io.Serializable;

/**
 * @author Administrator
 *
 */
public class SSOManager {

    private static String serverUrl = "http://localhost:8080/SSO/";

    public SSOEntity getUserNameById(SSOEntity entity) {
        return requestSSO(entity, "GetUserNameById");
    }

    public SSOEntity modifyUserName(SSOEntity entity) {
        return requestSSO(entity, "ModifyUserName");
    }

    public SSOEntity register(SSOEntity entity) {
        return requestSSO(entity, "Register");
    }

    private SSOEntity requestSSO(SSOEntity entity, String url) {

        String requestXml = getXmlFromEntity(entity);
        String requestUrl = serverUrl + url;
        String result = httpRequest(requestXml, requestUrl);
        return getEntityFromXml(result);
    }

    /**
     * 
     * @param entity
     * @return
     */
    private String getXmlFromEntity(SSOEntity entity) {
        String result = "";
        /**
         * generate xml from this entity, and sign data
         */
        return result;
    }

    private SSOEntity getEntityFromXml(String xml) {

        /**
         * transform xml to java bean
         */

        return null;
    }

    private String httpRequest(String xml, String url) {

        String result = "";
        /**
         * request another web server, get xml
         */
        return result;
    }

    public static void main(String[] args) {

        // this property is for md5 sign, each server has a different key
        String applicationKey = "hellokitty";   

        SSOManager sm = new SSOManager();
        SSOEntity response = null;

        // one servlet, get user info, need an object of SSOEntity
        SSOEntity entity = new SSOEntity();
        entity.setApplicationKey(applicationKey);
        entity.setUserId("124");

        response = sm.getUserNameById(entity);

        // another servlet, modify user name, need an object of SSOEntity too
        entity.setApplicationKey(applicationKey);
        entity.setUserId("456");
        entity.setUserName("I want you");
        response = sm.modifyUserName(entity);

        // there are some many servlet for me with this creation ...
        /**
         * ...
         */
    }
}



 class SSOEntity implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String userName;
    private String userId;
    private String email;
    private String passwd;
    private String mobile;

    private String applicationKey;
    /**
     * @return the applicationKey
     */
    public String getApplicationKey() {
        return applicationKey;
    }
    /**
     * @param applicationKey the applicationKey to set
     */
    public void setApplicationKey(String applicationKey) {
        this.applicationKey = applicationKey;
    }
    /**
     * @return the userName
     */
    public String getUserName() {
        return userName;
    }
    /**
     * @param userName the userName to set
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }
    /**
     * @return the userId
     */
    public String getUserId() {
        return userId;
    }
    /**
     * @param userId the userId to set
     */
    public void setUserId(String userId) {
        this.userId = userId;
    }
    /**
     * @return the email
     */
    public String getEmail() {
        return email;
    }
    /**
     * @param email the email to set
     */
    public void setEmail(String email) {
        this.email = email;
    }
    /**
     * @return the passwd
     */
    public String getPasswd() {
        return passwd;
    }
    /**
     * @param passwd the passwd to set
     */
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }
    /**
     * @return the mobile
     */
    public String getMobile() {
        return mobile;
    }
    /**
     * @param mobile the mobile to set
     */
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
}

3 个答案:

答案 0 :(得分:0)

使用简单的oops概念。使用父类具有公共属性,然后子类将具有更改的属性。尝试使用构建器模式来构建子类或每个请求,如 Effective Java中所述。

答案 1 :(得分:0)

当然,这最好是作为Prototype完成的。

有效的Java让你觉得你不应该这样做的原因可能是Bloch在Java中失败的克隆实现非常失败。我亲自和他谈过这个问题。他在准确说明如何制作的书中做得很好。出了问题,而且b。由于Sun的愚蠢政治,修复它的努力被挫败了。

但实际情况是,您不必使用SDK提供的克隆。事实上,克隆不一定是做Prototype的最佳方式。

任何时候你需要制作一些已经建立的常见状态的对象,你就是在做原型。整个DI世界是Singletons和Prototype。

使用Builder的另一个建议是没有意义的,除非您要在Builder上设置某些值,然后继续使用它来创建新实例,例如:

A.Builder a = new A.Builder().x(blah).y(blah);

b = builder.z(blah).build();
c = builder.z(otherBlah).build();

除非在编译时知道公共状态,否则你应该只是子类的想法也没有意义。

制作您自己的克隆或重复使用Builder。

答案 2 :(得分:0)

您尝试创建的对象SSOEntity 请求范围 的对象,因此必须根据请求创建它。对于需要发送到HTTP服务器的每个新请求,都是一个完全不同的状态,必须存储在一个新对象中才能表示该状态。因此,它是一对一的映射。

不必担心每个请求创建新对象,因为除非您的应用程序负担过重,否则完全不用担心。

我致力于为每个请求创建RequestResponse个对象的应用程序,相信你我并不重要。你唯一需要担心的是堆内存分配和垃圾收集算法,你很高兴。

可靠来源的引用,甚至Apache tomcat都做同样的事情。所以你必须在必要时创建对象。

同样正如@BenThurley的评论所暗示的那样,Request有不可变的意见,我也应该遵循这些意见。它提供了如此简单的功能。

最后:创建对象很便宜,所以不要担心开销