Hi great Go community. Sorry it's a long question, but i would really 
appreciate some guidance.


--------------------


Let's say i have two different objects, browser and executable that 
implement ScanCleaner interface.

type ScanCleaner interface {
scan()
clean()
}

type browser struct {
Name string
}

type exe struct {
Size int
}

These two objects are different internally but they implement the same scan and 
clean methods. In general i don't need to know their internals. I have this 
instead;

var objects []ScanCleaner

I can iterate through the objects, scan and clean them. So far so good, but 
i want to decouple scan and clean processes. One can scan the system, get a 
report and later clean based on that report file. So that interface slice 
should be stored appropriately in a file and recovered later.

I encode the objects slice, and get a perfectly good json output. 

Here is the working code: https://play.golang.org/p/cYgnhgxkPL0

Output: [{"Name":"chrome"},{"Name":"firefox"},{"Size":1234},{"Size":4321}]

--------------------


The problem arises when i need to decode report file and recover the 
objects interface slice. Object types are completely lost.

My current solution is this; I encapsulate every object with a string that 
specifies it's type,

type detection struct {
Type   string
Object ScanCleaner
}

and encode the slice of detection instead. The Type string is main.exe or 
main.browser obtained by fmt.Sprintf("%T", obj).

Here is a working code: https://play.golang.org/p/KeJjl8IOqRP

Output: 
[{"Type":"main.browser","Object":{"Name":"chrome"}},{"Type":"main.exe","Object":{"Size":1234}}]

Finally, i use a dispatch routine that recognizes objects type by Type string, 
decodes the object with the correct type, and calls it's clean method.

func cleanAll(jsn []byte) {
detects := []struct {
Type   string
Object json.RawMessage
}{}

json.Unmarshal(jsn, &detects)

for _, d := range detects {
var sc ScanCleaner
switch d.Type {
case "main.exe":
var e *exe*
json.Unmarshal(d.Object, &e)
sc = e
case "main.browser":
var b *browser*
json.Unmarshal(d.Object, &b)
sc = b
}
sc.clean()
}
}

Here is the final working code: https://play.golang.org/p/HpHFiHrT2oz

Output: 

browser clean {chrome}
browser clean {firefox}
exe clean {1234}
exe clean {4321}


--------------------


This solution is obviously not good. If i change an objects name, i should 
change the Type string in switch. Also i need to rely on the string 
returned by fmt.Sprintf("%T").

Is there a better solution to accomplish this task?

Thanks.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to