3

Suppose a function deserializes and validates some object from string and returns the result as Either<string, MyObject>. So an object is either completely deserialized and valid or some kind of error happened. Now suppose if even only some of the fields are valid the deserialization function should return them. How this kind of result could be represented in C# or Java? I was thinking about returning Either<Tuple<int, string, MyObject>, MyObject> with int being a flag telling what fields are actually valid but that doesn't look elegeant. Any ideas?

5

Depending on your desired semantics, you should either make the fields of MyObject have types like Optional<T>, or you should make a new class with fields like that or with type Either<string, T>. You should do the former if it just can be the case that MyObject can be missing some fields. You should do the latter if you want to process the intermediate object to either produce MyObject by, say, substituting in default values for missing fields or combining multiple objects together, or if you want to produce a more detailed description of the deserialization error. Basically, you deserialize into this intermediate object, then either produce a MyObject from it if all fields are available (or values can otherwise be provided for them) or produce an error.

  • This was my thinking too. That set me off down a trail though: what the OP really needs (at least what I'd want in their case) is a way of generating a version of MyObject that has Either<string, T> versions of MyObject's fields. As both Java and C# can generate such types on the fly, this could be an interesting deserialization library to write for someone. – David Arno Jun 30 '17 at 21:23
  • @DavidArno No. MyObject needs to be build with Either'ed properties from the very beginning. So code that uses it is forced to take into account case where property might not be loaded. – Euphoric Jul 1 '17 at 6:26
  • @DavidArno you can't do it automatically in C# or Java, but can in TypeScript with mapped types. Scala also offers some interesting ways to represent such objects. – synapse Jul 4 '17 at 17:45
2

What you really want is a Data Transfer Object. It's basically a property bag that doesn't have any special logic. Then you are free to map that to a business class, and handle the invalid data otherwise.

0

Suppose a function deserializes and validates some object from string and returns the result as Either.

It would be better to encapsulate the deserialization and validation part into a seperate object.

Say, you have a typical web application, where you need to deal with formdata, you could go with something like this:

public class MyForm {
    [...]
    public boolean is_valid(){
        // return validation result
    }

    public List<ValidationError> getValidationErrors(){
        // return validation errors
    }

    public MyObject getCleanData(){
        // gets an object only containing validated data
    }
    [...]
} 

MyForm is an object encapsulating the functionality of (de-)serialisation of data from or to other objects containing further business logic. And getCleanData deseralizes only valid fields into MyObject - in case the form is valid, it results in a completely filled instance.

The question for your application logic is how to deal with a half filled object.

-1

How to represent partially valid object

Don't. It's either valid or not so it's either useful or can be thrown away.

So an object is either completely deserialized and valid or some kind of error happened. Now suppose if even only some of the fields are valid the deserialization function should return them.

But apparently you have different levels of validity. You didn't say what you are going to do with the invalid object but it looks like in some scenarios it is valid after all and you can work with it or otherwise you wouldn't be returning one. Then you want to use it in another scenario and it turns out it won't work anymore.


However, I think what you are trying to achieve is to abuse the object that the deserialization returns to tell if any errors occured during that process based on the properties of the returned object. So now it doesn't only have the purpose of being only a data-object but also a deserialization-result. It has two responsibilities and this violates the S of SOLID.

Instead you should create another object whose purpose is to collect information about the deserialization so that you exactly know what went wrong or which properties could not be deserialized and perhaps for what reason etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.