-
Notifications
You must be signed in to change notification settings - Fork 172
/
survey.go
115 lines (89 loc) · 2.04 KB
/
survey.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package survey
import (
"encoding/json"
"io"
)
type Survey struct {
Title string
Questions []string
}
func (s *Survey) GetTitle() string {
return s.Title
}
func (s *Survey) Validate() bool {
return len(s.Questions) > 0
}
// Repository is an interface that defines the methods that a concrete repository must implement
type Repository interface {
Save(survey *Survey) error
}
type InMemoryRepository struct {
surveys []*Survey
}
func (r *InMemoryRepository) Save(survey *Survey) error {
r.surveys = append(r.surveys, survey)
return nil
}
// Decouple the SaveSurvey function from the concrete Repository implementation
func SaveSurvey(survey *Survey, repo Repository) error {
return repo.Save(survey)
}
type Exporter interface {
Export(survey *Survey) error
}
type S3Exporter struct{}
func (e *S3Exporter) Export(survey *Survey) error {
return nil
}
type GCSExporter struct{}
func (e *GCSExporter) Export(survey *Survey) error {
return nil
}
func ExportSurvey(s *Survey, exporter Exporter) error {
return exporter.Export(s)
}
// Use generic io.Writer instead of a concrete struct/file/etc.
func WriteSurvey(s *Survey, writer io.Writer) (int, error) {
b, err := json.Marshal(s)
if err != nil {
return 0, err
}
return writer.Write(b)
}
// Base interface
type Question interface {
SetTitle()
}
// Has addtional method AddOption
type QuestionWithOptions interface {
Question
AddOption()
}
type TextQuestion struct {
Title string
}
func (q *TextQuestion) SetTitle(title string) {
q.Title = title
}
type DropdownQuestion struct {
Title string
Options []string
}
func (q *DropdownQuestion) SetTitle(title string) {
q.Title = title
}
func (q *DropdownQuestion) AddOption(option string) {
q.Options = append(q.Options, option)
}
type SurveyManager struct {
store Repository
}
// Pass the Repository interface instead of the concrete InMemoryRepository
func NewSurveyManager(store Repository) *SurveyManager {
return &SurveyManager{
store: store,
}
}
func (m *SurveyManager) Save(survey *Survey) error {
return m.store.Save(survey)
}