当前位置: 首页 > 知识库问答 >
问题:

java - 求一个最佳实践?

冯曾笑
2024-11-29

有个案例我不知道是否对应哪个设计模式,求一个最佳实践。下面4个类存在继承和包含关系

public class QrScene {
    private String remark;
}
public class QrSceneInteger extends QrScene {
    private Integer scene_id;
}
public class QrSceneString extends QrScene {
    private String scene_str;
}
public class QrSceneWrapper implements Serializable {
    private static final long serialVersionUID = 1L;
    private QrScene scene;
}

// 通过传入参数创建不同数据类型的对象并返回
    private <T> QrSceneWrapper getQrSceneWrapper(T data){
        QrSceneWrapper qrSceneWrapper = null;
        if(data instanceof String){
            qrSceneWrapper = new QrSceneWrapper();
            QrSceneString qrSceneString = new QrSceneString();
            qrSceneString.setScene_str((String) data);
            qrSceneWrapper.setScene(qrSceneString);
        }else if(data instanceof Integer){
            qrSceneWrapper = new QrSceneWrapper();
            QrSceneInteger qrSceneInteger = new QrSceneInteger();
            qrSceneInteger.setScene_id((Integer) data);
            qrSceneWrapper.setScene(qrSceneInteger);
        }
        if(qrSceneWrapper != null) return qrSceneWrapper;
        throw new BusinessException("用于兑换二维码的场景值的ticket只支持两个类型:Integer,String");
    }

有个要求是不可让一个对象中同时出现属性 scene_id 和 scene_str
求方法 getQrSceneWrapper 的最佳实践。

共有3个答案

柯奕
2024-11-29
import java.io.Serializable;

class QrScene {
    private final String remark;

    public QrScene(String remark) {
        this.remark = remark;
    }
}

class QrSceneInteger extends QrScene {
    private final Integer scene_id;

    public QrSceneInteger(String remark, Integer scene_id) {
        super(remark);
        this.scene_id = scene_id;
    }
}

class QrSceneString extends QrScene {
    private final String scene_str;

    public QrSceneString(String remark, String scene_str) {
        super(remark);
        this.scene_str = scene_str;
    }
}

class QrSceneWrapper implements Serializable {
    private static final long serialVersionUID = 1L;
    private final QrScene scene;

    public QrSceneWrapper(QrScene scene) {
        this.scene = scene;
    }
}

public class Main {
    public static QrSceneWrapper createQrSceneWrapper(String data) {
        return new QrSceneWrapper(new QrSceneString("remark", data));
    }

    public static QrSceneWrapper createQrSceneWrapper(Integer data) {
        return new QrSceneWrapper(new QrSceneInteger("remark", data));
    }

    public static void main(String[] args) {
    }
}
戴品
2024-11-29

用策略模式加工厂模式

// 基础类
public class QrScene {
    private String remark;
}

// 子类
public class QrSceneInteger extends QrScene {
    private Integer scene_id;
}

public class QrSceneString extends QrScene {
    private String scene_str;
}

// 包装类
public class QrSceneWrapper implements Serializable {
    private static final long serialVersionUID = 1L;
    private QrScene scene;

    public QrScene getScene() {
        return scene;
    }

    public void setScene(QrScene scene) {
        this.scene = scene;
    }
}

// 策略接口
public interface QrSceneStrategy<T> {
    QrScene createQrScene(T data);
}

// String策略实现
public class QrSceneStringStrategy implements QrSceneStrategy<String> {
    @Override
    public QrScene createQrScene(String data) {
        QrSceneString qrSceneString = new QrSceneString();
        qrSceneString.setScene_str(data);
        return qrSceneString;
    }
}

// Integer策略实现
public class QrSceneIntegerStrategy implements QrSceneStrategy<Integer> {
    @Override
    public QrScene createQrScene(Integer data) {
        QrSceneInteger qrSceneInteger = new QrSceneInteger();
        qrSceneInteger.setScene_id(data);
        return qrSceneInteger;
    }
}

// 工厂类
public class QrSceneFactory {
    private final Map<Class<?>, QrSceneStrategy<?>> strategies = new HashMap<>();

    public QrSceneFactory() {
        strategies.put(String.class, new QrSceneStringStrategy());
        strategies.put(Integer.class, new QrSceneIntegerStrategy());
    }

    @SuppressWarnings("unchecked")
    public <T> QrSceneWrapper createQrSceneWrapper(T data) {
        QrSceneStrategy<T> strategy = (QrSceneStrategy<T>) strategies.get(data.getClass());
        if (strategy == null) {
            throw new BusinessException("用于兑换二维码的场景值的ticket只支持两个类型:Integer,String");
        }
        QrSceneWrapper qrSceneWrapper = new QrSceneWrapper();
        qrSceneWrapper.setScene(strategy.createQrScene(data));
        return qrSceneWrapper;
    }
}

程俊誉
2024-11-29
### 最佳实践

在你的案例中,你已经通过继承的方式区分了不同类型的二维码场景(`QrSceneInteger` 和 `QrSceneString`),并使用了一个包装类 `QrSceneWrapper` 来统一处理这些不同类型的场景。然而,你的 `getQrSceneWrapper` 方法中使用了类型检查和强制转换,这通常不是最佳实践,因为它违反了开闭原则(对扩展开放,对修改关闭)。

#### 推荐的最佳实践:

1. **使用工厂模式**:
   创建一个工厂类来根据输入参数生成相应的 `QrScene` 子类实例。这样可以避免在 `getQrSceneWrapper` 方法中进行类型检查和强制转换。

2. **使用多态**:
   让 `QrScene` 类或其子类具有一个统一的方法来获取场景值(无论是 `Integer` 还是 `String`),这样 `QrSceneWrapper` 就不需要关心具体是哪种类型的 `QrScene`。

#### 示例代码:

// 工厂类
public class QrSceneFactory {

public static QrScene createQrScene(Object data) {
    if (data instanceof String) {
        QrSceneString qrSceneString = new QrSceneString();
        qrSceneString.setScene_str((String) data);
        return qrSceneString;
    } else if (data instanceof Integer) {
        QrSceneInteger qrSceneInteger = new QrSceneInteger();
        qrSceneInteger.setScene_id((Integer) data);
        return qrSceneInteger;
    } else {
        throw new BusinessException("用于兑换二维码的场景值的ticket只支持两个类型:Integer,String");
    }
}

}

// 修改后的 getQrSceneWrapper 方法
private QrSceneWrapper getQrSceneWrapper(Object data) {

QrScene scene = QrSceneFactory.createQrScene(data);
QrSceneWrapper qrSceneWrapper = new QrSceneWrapper();
qrSceneWrapper.setScene(scene);
return qrSceneWrapper;

}


通过这种方式,你可以将类型检查和对象创建的逻辑封装在工厂类中,使 `getQrSceneWrapper` 方法更加简洁和易于维护。同时,这也使得未来添加新的 `QrScene` 子类变得更加容易,只需在工厂类中添加相应的逻辑即可,无需修改 `getQrSceneWrapper` 方法。
 类似资料:
  • 问题内容: 在厌倦了c3p0的恒定锁定之后,我将转向BoneCP作为数据库的备用连接池。我有一个服务器应用程序,每分钟处理大约7,000个项目,需要将这些项目记录到我们的MySQL数据库中。我目前有100个工作线程,并按如下方式设置了我的池: 这些应用程序是否接受这些设置?我问是因为运行一两分钟后,在尝试调用池时出现BoneCP异常。谢谢您的帮助。 这是我在工作线程中用于db调用的代码,它不会在网

  • 问题内容: 有时,当我看到自己的日志记录代码时,我想知道自己是否做对了。可能没有确切的答案,但是我有以下担忧: 图书馆课 我有几个库类可能记录一些消息。致命错误被报告为例外。当前,我的类中有一个静态记录器实例,其类名称为记录名称。(Log4j的:) 这是正确的方法吗?也许该库类的用户不需要我的实现中的任何消息,或者想要将它们重定向到应用程序特定的日志。我是否应该允许用户从“外部世界”设置记录器?您

  • 这里有些给使用和编写 Ansible playbook 的贴士. 你能在我们的 ansible-example repository.找到展示这些最佳实践的 playbook 样例.(注意: 这些示例用的也许不是最新版的中所有特性,但它们仍旧是极佳的参考.) Topics 最佳实践 接下来的章节将向你展示一种组织 playbook 内容方式. 你对 Ansible 的使用应该符合你的需求而不是我们

  • 处理后台任务与常规调用方法有很大的不同。本指南旨在帮助让您的后台任务平稳有效地运行。本文基于 这篇博客文章。 使任务参数小而简单 方法(任务)在调用之前会被序列化。使用 TypeConverter 类将参数转换为 JSON 字符串。如果您有复杂的实体和 / 或大对象; 包括数组,最好将它们放入数据库,然后只将其标识 (id) 传递给后台任务。 错误例子: public void Method(En

  • VR设计 VR设计不同于平面体验设计。作为一种新的媒介,有新的最佳实践需要遵循,特别是保持用户的舒适性和存在性。这在如下指南中已经写得很透彻了: Oculus VR最佳实践 Leap Motion VR最佳实践指南 一些值得注意的事情: 公共的金科玉律是永远不要意外地把相机控制权从用户手中剥夺。 单位(比如对于位置)应该考虑使用米(m)。这是因为WebVR API以米为单位返回姿势数据,进而传送给

  • 本章文档将阐述一些使用herosphp开发一些常用模块的一些比较好的实践。 未完待续。。。

  • 适当的使用vuex 能不用就不用。 能用就用。 不要为了使用而使用,一个小方法里面有5个设计模式。 不要过度使用CSS框架 因为CSS框架一般会大幅度增加文件体积。 例如 bootstrap, ele.me前端框架。 这个在低端安卓机上影响显著。 使用CDN来存放js, css, 和图片文件。 灵活使用第三方Vue 插件 例如: 轮播图, 表单验证等等。这些轮子都是现成的。 前端逻辑务必简单 能在

  • 这是 Martin Zinkevich (Google) 在 NIPS 2016 Workshop 分享的谷歌机器学习最佳实践翻译版,PDF 全文见 Rules of Machine Learning: Best Practices for ML Engineering。 机器学习产品所要面对的难题是工程问题(而不是 ML 算法),所以在做机器学习时要遵循跟其他产品类似的工程原则。 术语 实例(