O problema de se misturar regras de negócio em uma classe Vo

Gostaria de saber qual é o problema possível de se misturar métodos com regras de negócios em classes Vo? se tem algum padrão ou boa prática que esse tipo de coisa pode afetar? Segue um exemplo:

public class RequestHttp {
	private Protocol protocol;
	private String url;
	private String urlParam;
	private String body;
	private Method method;
	private String charset;
	private int connTO;
	private int readTO;
	private List<String[]> headers;
	private String proxy;
	private String connectionBucket;
	private boolean useCircuitBreaker;


/*
.
.
.
*/
	public RequestHttp setHeader(String key, String val) {
		if (key != null) {
			if (val == null) {
				if (this.headers != null) {
					for (int i = 0; i < this.headers.size(); i++) {
						String[] h = this.headers.get(i);
						if (h != null && h.length == 2 && key.equalsIgnoreCase(h[0])) {
							this.headers.remove(i);
							break;
						}
					}
				}
				
			}
			else {
				if (this.headers == null) {
					this.headers = new ArrayList<String[]>();
				}
				this.headers.add(new String[]{key, val});
			}
		}
		return this;
	}
	public List<String[]> getHeaders() {
		return (this.headers == null ? Collections.<String[]>emptyList() : this.headers);
	}
	
	public boolean isSameCall(RequestHttp other) {
		if (other != null && other.getProtocol() == getProtocol() && getFullUrl() != null && getFullUrl().equals(other.getFullUrl()) && getEffectiveMethod() == other.getEffectiveMethod()) {
			if (getEffectiveMethod() == Method.POST) {
				return ((getBody() == null || getBody().isEmpty()) && (other.getBody() == null || other.getBody().isEmpty())) || getBody().equals(other.getBody());
			}
			else {
				return true;
			}
		}
		return false;
	}

	@Override
	public String toString() {
		return "RequestHttp [protocol=" + protocol + ", url=" + url + ", urlParam=" + urlParam + ", body=" + body + ", method=" + method
				+ ", charset=" + charset + ", connTO=" + connTO + ", readTO=" + readTO + ", headers=" + CollectionsUtil.toString(headers, array -> Arrays.toString(array)) + "]";
	}

	public String toStringLine() {
		if (protocol == Protocol.SMS) {
			return protocol + ":" + getUrl();
		}
		else {
			return getEffectiveMethod().name() + " " + getFullUrl() + (getBody() == null ? "" : " body=" + getBody()) + (headers == null || headers.isEmpty()? "" : " headers=" + CollectionsUtil.toString(headers, array -> Arrays.toString(array)));
		}
	}
	
	public static String toStringShort(RequestHttp request) {
		if (request == null) {
			return "null";
		}
		else {
			return request.toStringLine();
		}
	}

	private static String generateField(String param, String value) {
		String fieldToAdd;
		value = (value == null ? "" : value);
		try {
			fieldToAdd = param + "=" + URLEncoder.encode(value, "UTF-8");
		}
		catch (UnsupportedEncodingException e) {
			fieldToAdd = param + "=" + value;
		}
		return fieldToAdd;
	}

	private static String urlEncodeQueryString(String stringToEncode) {
		String ret = null;
		if (stringToEncode != null) {
			String[] fields = stringToEncode.split("&");
			for (String f: fields) {
				String[] params = f.split("=",2);
				String fieldToAdd;
				if (params.length == 2) {
					fieldToAdd = generateField(params[0], params[1]);
				}
				else {
					fieldToAdd = generateField(params[0], "");
				}
				ret = (ret == null? fieldToAdd : ret + "&" + fieldToAdd);
			}
		}
		return ret;
	}
}

Isso não parece ser regra de negócio. Ou explique melhor.

achei a resposta: https://stackoverflow.com/a/2333921

The DTO and VO are supposed to be used to transfer data and don’t embed logic. The business objects on the other hand are supposed to embed some logic. I say some , because there is always a balance to find between what you put in services which coordinate logic involving several business objects and what you put in the business objects themselves. Typical logic in the business objects can be validation, field computation, or other operation that impact only one business object at a time.

Note that I haven’t mentioned the term entity so far. Persistent entities were popularized with ORM and we nowadays try to use persistent entities both as DTO and business object at the same time. That is, the entity themselves flow between layers and tiers, and contain some logic.

Are there any more valid reasons not to move logic into my entities? Or any other concerns to take into account?

As you pointed out, it’s all a matter of dependencies and what you expose. As long as the entities are dumb (close to DTO) they can be isolated in a dedicated jar easily that serves as API of the layer . The more logic you put in the entities, the harder it becomes to do that. Pay attention to what you expose and what you depend on (the load the class, the client will need to have the depend class as well). This applies to exceptions, inheritance hierarchy, etc.

Just to give an example, I had a project where the entities had a method toXml(...) used in the business layer. As a consequence, client of the entities depended on XML.

But if you don’t care too much about layers, and strict separation between API and implementation, I think it’s good to move some logic in the entities.

Há alguns detalhes em classes VO que elas não tem identidade, devem ser imutáveis, e dois objetos VO de instâncias diferentes contendo os mesmos valores devem ser iguais se comparadas com equals, por exemplo.