불변성 수용(프로그래밍 및 인프라)
가변성 🚨
프로그래머이고 Java, Python 및 Go와 같은 언어에 대한 경험이 있는 경우 가변성의 이점과 단점을 알고 있을 것입니다.
가변성의 문제는 주로 다음과 같습니다.
복잡성 증가: 어떤 함수가 값을 변경합니까? 이 속성이 null인 이유는 무엇입니까?
동시성: 동일한 변수를 수정하는 스레드
불변 데이터 구조를 사용하면 스레드와 함수 간에 걱정 없이 데이터를 공유할 수 있습니다.
인프라 세계에서도 우리는 서버를 배포하고 지속적으로 업데이트하고 수정하여 모든 변경 사항을 추적하고 처음부터 새로운 환경을 만드는 것이 매우 어려웠습니다.
불변 인프라는 서버가 수정되지 않는 또 다른 인프라 패러다임입니다. 업데이트가 필요한 경우 이전 서버를 대체하기 위해 새 서버를 구축하고 프로비저닝합니다.
Effective Java라는 책에서 저자는 메서드와 클래스에서 final 키워드를 사용하는 것을 옹호합니다. 왜요?
The final keyword is a non-access modifier used for classes, attributes, and methods, which makes them non-changeable (impossible to inherit or override).
The final keyword is useful when you want a variable to always store the same value, like PI
Java와 같은 언어에서 Go 및 Python 객체는 기본적으로 변경 가능합니다. 이로 인해 당면한 문제에 대해 추론하기가 훨씬 더 어려워집니다.
Chef, Puppet 및 Ansible과 같이 일반적으로 기본적으로 변경 가능한 인프라 패러다임을 사용하는 구성 관리 도구를 사용하는 인프라 세계에서도 동일한 일이 발생합니다.
구조에 대한 불변성 ⛑
이 아이디어는 변수가 불변이므로 변수를 값으로 설정한 후에는 값을 변경할 수 없는 함수형 프로그래밍에서 영감을 받았습니다. 무언가를 업데이트해야 하는 경우 새 변수를 만듭니다.
값은 절대 변경되지 않으므로 코드에 대해 추론하기가 더 쉽습니다.
Code example (Go/Clojure)
좋은 소식은 이 문제를 극복할 수 있다는 것입니다! 😎
이동 포인터
package main
import (
"fmt"
"math/rand"
"strconv"
"strings"
)
type Book struct {
Author string
Title string
Pages int
}
func (book Book) GetPagesWithCode() string {
var n = rand.Intn(200)
book.Pages -= n
return "The " + strings.ToUpper(book.Title) + " book has " + strconv.Itoa(book.Pages) + " pages"
}
func main() {
var book = Book{Author: "Rich Hickey", Title: "Clojure for the Brave & True", Pages: 232}
fmt.Printf("1) %+v\n", book)
changeAuthor(&book, "Daniel Higginbotham")
fmt.Printf("2) %+v\n", book)
fmt.Println(book.GetPagesWithCode())
fmt.Printf("3) %+v\n", book)
}
func changeAuthor(book *Book, author string) {
book.Author = author
}
산출:
메서드에서 페이지를 업데이트해도 데이터는 동일하게 유지됩니다.
1) {Author:Rich Hickey Title:Clojure for the Brave & True Pages:232}
2) {Author:Daniel Higginbotham Title:Clojure for the Brave & True Pages:232}
The CLOJURE FOR THE BRAVE & TRUE book has 151 pages
3) {Author:Daniel Higginbotham Title:Clojure for the Brave & True Pages:232}
클로저
(ns main.core
(:require [clojure.string :as s])
(:gen-class)
)
(defn get-pages-with-code [book]
(str "The " (s/upper-case (:title book)) " book has " (:pages book) " pages")
)
(defn change-author [book author]
(assoc book :author author))
(defn -main
[& args]
(let [book {:author "Rich Hickey", :title "Clojure for the Brave & True", :pages 232}
new-book (change-author book "Daniel Higginbotham")]
(println "1)" book)
(println "2)" new-book)
(println "3)" (get-pages-with-code book))
)
)
산출:
데이터는 절대 변경되지 않으며 새로운 값을 생성할 뿐입니다.
1) {:author Rich Hickey, :title Clojure for the Brave & True, :pages 232}
2) {:author Daniel Higginbotham, :title Clojure for the Brave & True, :pages 232}
3) The CLOJURE FOR THE BRAVE & TRUE book has 232 pages
테라포밍
resource "aws_instance" "george_server" {
ami = "ami-0fb653ca2d3203ac1"
instance_type = "t2.micro"
}
완전히 새로운 서버
resource "aws_instance" "george_server" {
ami = "ami-0CCC3ca2d32CCC1"
instance_type = "t2.micro"
}
서버는 절대 변경되지 않기 때문에 배포된 항목에 대해 추론하기가 훨씬 쉽습니다.
결론
변수와 개체를 변경할 수 있는 프로그램 부분을 제어하면 보다 강력하고 예측 가능한 소프트웨어를 작성할 수 있습니다.
불변성을 수용하세요 🔥
severity = :mild
error_message = "OH GOD! IT'S A DISASTER! WE'RE "
if severity == :mild
error_message = error_message + "MILDLY INCONVENIENCED!"
else
error_message = error_message + "DOOOOOOOMED!"
end
You might be tempted to do something similar in Clojure:
(def severity :mild)
(def error-message "OH GOD! IT'S A DISASTER! WE'RE ")
(if (= severity :mild)
(def error-message (str error-message "MILDLY INCONVENIENCED!"))
(def error-message (str error-message "DOOOOOOOMED!")))
Reference
이 문제에 관하여(불변성 수용(프로그래밍 및 인프라)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jorgetovar/the-problem-with-mutability-and-how-to-overcome-it-597h텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)