什么';在Java中创建输入验证方法的良好实践是什么?

什么';在Java中创建输入验证方法的良好实践是什么?,java,coding-style,Java,Coding Style,如果我想验证我的输入,我应该将验证代码作为私有helper方法还是创建一个单独的静态helper类?验证代码是否增加了对象的大小 更多信息 假设我有一节课 import java.util.Vector; public class Place { private final double longitude; private final double latitude; private final String id; private

如果我想验证我的输入,我应该将验证代码作为私有helper方法还是创建一个单独的静态helper类?验证代码是否增加了对象的大小

更多信息

假设我有一节课

import java.util.Vector;


public class Place {
    private final double    longitude;
    private final double    latitude;
    private final String    id;

    private       String           address;
    private       String           name;
    private       String           types;
    private       String           icon;
    private       String           phoneNumber;
    private       String           websiteUrl;
    private       int              rating;
    private       Vector<Integer>  challenges;

    public static class Builder {
        // required parameter
        private final double    longitude;
        private final double    latitude;
        private final String    id;
        // optional parameter
        private       String           address = "n/a";
        private       String           name = "n/a";
        private       String           icon = "n/a";
        private       String           phoneNumber = "n/a";
        private       String           websiteUrl = "n/a";
        private       String           types = "n/a";
        private       Vector<Integer>  challenges = new Vector<Integer>();
        private       int              rating = 0;

        public Builder(double longitude, double latitude, String id) {
            assert(longitude >= -180.0 && longitude <= 180.0);
            assert(latitude >= -90.0 && longitude <= 90.0);
            this.longitude = longitude;
            this.latitude = latitude;
            this.id = id;
        }

        public Builder address(String address) {
            this.address = address;
            return this;
        }

        public Builder types(String types) {
            this.types = types;
            return this;
        }

        public Builder name(String name) {
            this.name = name;
            return this;
        }

        public Builder icon(String icon) {
            this.icon = icon;
            return this;
        }

        public Builder phoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
            return this;
        }

        public Builder websiteUrl(String websiteUrl) {
            this.websiteUrl = websiteUrl;
            return this;
        }

        public Builder builder(int rating) {
            this.rating = rating;
            return this;
        }

        public Place build() {
            return new Place(this);
        }
    }

    public Place(Builder builder) {
        // required parameters
        longitude = builder.longitude;
        latitude = builder.latitude;
        id = builder.id;

        // optional parameters
        address = builder.address;
        types = builder.types;
        name = builder.name;
        icon = builder.icon;
        phoneNumber = builder.phoneNumber;
        websiteUrl = builder.websiteUrl;
        rating = builder.rating;
        challenges = builder.challenges;
    }

    public double getLongitude() {
        return longitude;
    }

    public double getLatitude() {
        return latitude;
    }

    public String getId() {
        return id;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getAddress() {
        return address;
    }

    public String getTypes() {
        return types;
    }

    public void setTypes(String types) {
        this.types = types;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setIconUrl(String icon) {
        this.icon = icon;
    }

    public String getIcon() {
        return icon;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }


    public void setWebsiteUrl(String websiteUrl) {
        this.websiteUrl = websiteUrl;
    }

    public String getWebsiteUrl() {
        return websiteUrl;
    }

    public void setRating(int rating) {
        this.rating = rating;
    }

    public int getRating() {
        return rating;
    }

    @Override
    public String toString() {
        return "(" + Double.toString(longitude) + ", " +  Double.toString(latitude) + ")";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Place other = (Place) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        }
        else if (!id.equals(other.id))
            return false;
        return true;
    }

    public Vector<Integer> getChallenges() {
        return new Vector<Integer>(challenges);
    }

    public void addChallenges(Integer i) {
        this.challenges.add(i);
    }

    public void showChallenges() {
        for (Integer i : challenges) {
            System.out.print(i + ", ");
        }
    }
}
import java.util.Vector;
公共课场所{
私人最终双经度;
私人最终双纬度;
私有最终字符串id;
私有字符串地址;
私有字符串名称;
私有字符串类型;
私有字符串图标;
私有字符串电话号码;
私有字符串网址;
私人内部评级;
私人病媒挑战;
公共静态类生成器{
//必需参数
私人最终双经度;
私人最终双纬度;
私有最终字符串id;
//可选参数
专用字符串地址=“不适用”;
私有字符串name=“不适用”;
私有字符串图标=“不适用”;
专用字符串phoneNumber=“不适用”;
私有字符串websiteUrl=“不适用”;
私有字符串类型=“不适用”;
私有向量挑战=新向量();
私人内部评级=0;
公共生成器(双经度、双纬度、字符串id){
断言(经度>=-180.0和经度=-90.0和经度)
我应该将验证代码作为私有助手方法还是创建一个单独的静态助手类

这完全取决于你的背景。不知道你想实现什么,就不可能说什么是最好的设计

编辑后:IMO,仍然不容易告诉您。如果您只需要在应用程序的一个点(id:setter方法)中验证地址,我会在setter方法中验证地址。如果输入无效,我会抛出一个
IllegalArgumentException


验证代码是否增加了对象的大小

但是,第二个问题的答案是否定的。要理解原因,您必须知道什么是面向对象编程

一些参考资料:

我应该将验证代码作为私有助手方法还是创建一个单独的静态助手类

这完全取决于你的背景。不知道你想实现什么,就不可能说什么是最好的设计

编辑后:IMO,仍然不容易告诉您。如果您只需要在应用程序的一个点(id:setter方法)中验证地址,我会在setter方法中验证地址。如果输入无效,我会抛出一个
IllegalArgumentException


验证代码是否增加了对象的大小

但是,第二个问题的答案是否定的。要理解原因,您必须知道什么是面向对象编程

一些参考资料:

我应该将验证代码作为私有助手方法还是创建 单独的静态助手类

这取决于您是否认为需要在另一个类中为相同的目的(输入验证)重用相同的方法。最好在单独的静态帮助器类中编写该方法,以便可以重用该方法并轻松维护它。 如果每次需要进行更改时都在几个类中编写相同的私有帮助器方法,则必须编辑每个类中的每个方法,使用静态帮助器类只能在一个位置更改代码

我应该将验证代码作为私有助手方法还是创建 单独的静态助手类

这取决于您是否认为需要在另一个类中为相同的目的(输入验证)重用相同的方法。最好在单独的静态帮助器类中编写该方法,以便可以重用该方法并轻松维护它。
如果每次需要更改时在几个类中编写相同的私有帮助器方法,则必须编辑每个类中的每个方法,对于静态帮助器类,您只能在一个位置更改代码…

如果您只是查看输入的字符串格式是否正确或长度是否正确,那么您将使用pri另一方面,如果您要检查地址是否正确(在地图上查找地址)或任何更高级的东西,那么创建AddressValidator接口并从该私有方法调用它是有意义的

私有方法的原因是您可以从构造函数、setter或任何其他可以提供地址的方法调用它。接口的原因是您可能希望有一个在线/离线AddressValidator(MockAddressValidator,或为每个国家调用不同类的方法等)

由于AddressValidator可以在其他类中重用,并且为了保持代码的整洁,我将其创建为顶级接口+OnlineAddressValidator。这也使您的类具有更好的可读性。为了实现完全的可配置性,您可能需要考虑如何提供AddressValidator实例,例如通过构造函数或者定义为静态最终验证器的验证器

public interface AddressValidator {
    static class AddressValidatorResult {
        // some results, you might want to return some useful feedback (if not valid)

        boolean isValid() {
            throw new IllegalStateException("Method not implemented yet");
        }
    }

    public static class AddressValidationException extends Exception {
        private AddressValidationException(AddressValidatorResult result) {
            // add some implementation
        }
    }


    // don't throw ValidateException here, invalid addresses are normal for
    // validators, even if they aren't for the application that uses them
    AddressValidatorResult validateAddress(String address);
        // don't throw ValidateException here, invalid addresses are normal for
        // validators, even if they aren't for the application that uses them
}

public class DefaultAddressValidator implements AddressValidator {

    public static class Params {
        // some parameters for this specific validator
    }

    private final Params params;

    public DefaultAddressValidator(Params params) {
        // creates this validator
        this.params = params;
    }

    @Override
    public AddressValidatorResult validateAddress(String address) {
        // perform your code here

        // I don't like "return null" as it may lead to bugs
        throw new IllegalStateException("Method not implemented yet");
    }
}


// and use it like this
private void validateAddress(String address) throws AddressValidationException {
    // e.g. field AddressValidator set in constructor 
    AddressValidatorResult result = addressValidator.validateAddress(address);
    if (!result.isValid()) {
        throw new AddressValidationException(result);
    }
}

如果你只是想看看输入的字符串格式是否正确或长度是否正确,那么你会使用私有方法。如果你想检查地址是否正确(在地图上查找)或者任何更高级的东西,创建AddressValidator接口并从私有方法调用它是有意义的

私有方法的原因是,您从c调用这两个函数