I'd say there are 3 options.
OPTION 1. Create a custom value accessor
This is basically hard-coding the value accessor to know how to deal with a specific facet value. I don't recommend this approach, but there are cases when it's appropriate.
Disadvantages: custom code, maintenance
Best for: prototyping/testing/learning, or unusually complex values, or when you don't have time to do it "the right way".
OPTION 2. Use the built-in components to configure a compound value accessor
This is a completely configuration-based option. In the future this will be a more viable option (when we have a configuration UI).
Advantages: doesn't require custom code
Disadvantages: configuration can be very complex, requires strong understanding of framework components
Best for: simple-to-mildly complex values
OPTION 3. Hybrid value accessor
This is the approach we use for the more complex value readers and writers (like the ones used to interact with contact facets). We try to avoid creating new readers/writers. The base ones tend to support most of what is needed - if you know what they are and how to use them.
If you look at the provider for Dynamics CRM, you can see examples of this in the value accessors used to interact with CRM entities.
Advantages: good balance of complexity and usability
Disadvantages: requires small amount of custom code for converters, requires strong understanding of framework components
Best for: mildly-to-highly complex values