Это серия историй для программистов, которые хотят начать моделирование объектов и поведения с помощью Go. Желаю вам удачного путешествия.
Почему речь идет о мытье посуды ???
Моя девушка действительно хорошо готовит, а я, напротив, умею только мыть посуду и, конечно же, мыть руки. Я расслабляюсь после того, как трачу время после еды на мытье посуды, сковородок и мисок.
Это не только работа рук, но и мой мозг пытается найти наиболее эффективное средство для стирки.
Хотя вы можете не согласиться с этим утверждением, проследите за моей историей, чтобы увидеть, как я превращаю мытье посуды в модели объекта и поведения с помощью моего любимого языка. , Вперед.
Предварительные требования
К сожалению, эта история потребует от вас базовых знаний Go:
- Пакет https://golang.org/doc/effective_go.html#package-names
- Для цикла https://golang.org/doc/effective_go.html#for
- Фрагменты https://golang.org/doc/effective_go.html#slices
На изучение этих концепций у вас не уйдет больше 5 минут, что равно времени, которое я отдыхаю на обеденном столе перед тем, как мыть посуду.
Самая простая модель
- Объекты и поведение
- Объект Блюдо: инкапсулирует атрибуты блюда:
- Состояние загрязнения блюда.
Блюдо должно иметь следующие характеристики:
- Убери себя. - Объект Губка: содержит атрибуты губки (без губки нельзя стирать !!):
- Цвет губки.
- Сколько раз мы можем использовать губку для стирки. пока не закончится жидкость.
Губка должна иметь следующие свойства:
- Вымойте посуду.
- Долейте жидкость. - Объект LiquidDispenser: один из моих соседей по дому не хочет использовать жидкость для мытья посуды, и я сказал ему держаться подальше от раковины. У него есть атрибуты:
- количество жидкости, которое он хранит.
LiquidDispenser должен иметь поведение:
- показывает количество оставшейся жидкости.
- Выдает некоторое количество жидкости.
2. Реализация с использованием Go
готовое блюдо
sponge.go
liquiddispenser.go
Для людей, которые не знакомы с Go, позвольте мне объяснить синтаксис.
Постоянная
Губка имеет максимальное количество раз, когда ее можно использовать для стирки с добавлением жидкости. И естественно сохранить его как константу.
Структура
В Go мы используем struct
как class
для объекта, который мы хотим смоделировать.
struct
может иметь поля (атрибуты) или методы (функции-члены)
В Go есть концепция экспортируемых и неэкспортированных идентификаторов, которая в чем-то похожа на частные и общедоступные. .
From https://golang.org/ref/spec#Exported_identifiers An identifier may be exported to permit access to it from another package. An identifier is exported if both: - the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu") - the identifier is declared in the package block or it is a field name or method name. All other identifiers are not exported.
Пример из нашего кода для мытья посуды:
- Не заглавная буква
amount
указывает, чтоamount
является неэкспортируемым атрибутом. - Заглавная буква
Color
указывает, чтоColor
является экспортируемым атрибутом. - Не заглавная буква
clean
указывает, чтоclean()
является неэкспортируемым методом. - Заглавная буква
IsClean
указывает, чтоIsClean()
является методом экспорта. - Не заглавная буква
spongeMaxLiquid
указывает, чтоspongeMaxLiquid
является неэкспортируемой константой. - Заглавная буква
Yellow
указывает, чтоYellow
является экспортированной константой.
Указатель и приемники значения, методы указателя и значения
Чтобы описать поведение модели или типа в Go, мы используем методы.
Из dish.go
примера мы видим, что есть два типа получателей: Dish
(получатель значения) и *Dish
(получатель указателя).
- Методы, которые мы можем вызывать с помощью приемника
Dish
, являются методами, объявленными с типомDish
(IsClean()
) - Методы, которые мы можем вызывать с помощью приемника
*Dish
, - это методы, объявленные с типомDish
и типом*Dish
(IsClean()
иclean()
)
Чем отличается указатель от получателя значения?
- Методы значений можно вызывать на приемниках указателя и значения, но методы указателя можно вызывать только на приемниках указателя.
- Методы указателя могут изменить получатель, в то время как вызов методов значения приведет к тому, что метод получит копию значения. , поэтому любые изменения будут отменены.
Поэтому мы будем использовать методы значений для поведения только для чтения или без изменения и будем использовать методы указателя для поведения изменения.
IsClean()
отображает только чистое состояние блюда.clean()
изменяет внутреннее состояниеdirty
блюда.
Следовательно, при разработке модели (типа), которая потребует модификации внутреннего состояния, мы обычно создаем и используем приемник указателя даже для методов значения. Это помогает указать пользователю нашей модели не создавать объект типа значения.
Основная функция
Точкой входа в программу Go является функция main()
Теперь мы можем запустить программу
// in the package dishwashing_part1/ $ go build -o main $ ./main Before wash, is dish 1 clean? = false After wash, is dish 1 clean? = true Before wash, is dish 2 clean? = false After wash, is dish 2 clean? = true Before wash, is dish 3 clean? = false After wash, is dish 3 clean? = true Before wash, is dish 4 clean? = false After wash, is dish 4 clean? = true Before wash, is dish 5 clean? = false After wash, is dish 5 clean? = true Before wash, is dish 6 clean? = false After wash, is dish 6 clean? = true Before wash, is dish 7 clean? = false After wash, is dish 7 clean? = true Before wash, is dish 8 clean? = false After wash, is dish 8 clean? = true Before wash, is dish 9 clean? = false After wash, is dish 9 clean? = true Before wash, is dish 10 clean? = false After wash, is dish 10 clean? = true
Итак, простая программа Go, моделирующая операцию мытья посуды.
Вы можете найти исходный код здесь
Напомним нашу цель: моделирование объектов и поведения! И эта модель - это простейшая модель, о которой мы можем думать.
Хотя программа, кажется, работает хорошо, можно сделать много улучшений в моделях и их поведении. Мы обсудим больше в части 2 этой серии.
Спасибо за прочтение!