이 책을 몇 문장으로 요약하면 다음과 같다.

 

  • 장인정신을 갖자.
  • 깨끗한 코드는 예술과 같다. 비평을 잘 한다고 훌륭한 예술가가 되는 건 아니다.
  • 깨끗한 코드는 끊임없는 개선에서 나온다. 노력이 필요하다.
  • 깨끗한 코드는 주의 깊게 작성한 코드다.

이 책에서 말하는 깨끗한 코드란 무엇일까?

다양한 유명 프로그래머의 말을 빌려 그 의미를 전달하지만 저자 본인은 한 두 문장으로 정의하지 않는다.

대신 수 많은 원칙을 기준으로 다듬고 다듬어서 깨끗한 코드를 만들 수 있다고 한다.

 

그래도 깨끗한 코드는 무엇인지 이 책에서 언급된 유명 프로그래머의 말을 짧게 요약하면 다음과 같다.

 

  • 한 가지를 제대로 하는 우아하고 효율적인 코드 - 비야네 스트롭스트룹
  • 깨끗한 코드는 잘 쓴 문장처럼 읽힌다 - 그래디 부치
  • 테스트가 존재하며 코드는 문학적으로 표현해야 마땅하다 - 데이브 토마스
  • 깨끗한 코드는 언제나 누군가 주의 깊게 짰다는 느낌을 준다 - 마이클 페더스
  • 중복이 없고 최대한 줄여 간결한 코드 - 론 제프리스
  • 의도한대로 작성되었고 의도한대로 기능하며 읽히는 코드 - 워드 커닝햄

너무 짧게 요약해서 말한 의도가 제대로 정리되었는지는 모르겠다.

어찌됐든 깨끗한 코드에 대한 프로그래머들의 생각은 거의 대부분 다음과 같은 단어로 일반화할 수 있을 것 같다.

 

  • 중복이 없는 간결함, 그로 인해 우아하며 의도가 쉽게 읽히는 가독성, 단위테스트를 통해 오류가 없고 고치기 쉬운 코드

이 책에서는 깨끗한 코드를 작성하는 최선의 실체적인 방법을 다음과 같은 원칙(저자가 말하는 교리)들로 세세하고 구체적으로 다루고 있다. 물론 각 항목별로 더 상세한 원칙들이 존재하며 아래 내용은 임의로 요약했으므로 상세한 내용은 책을 읽어보길 바란다.

 

  • 의미 있는 이름
  • 한 가지만 수행하는 작은 함수
  • 위에서 아래로 읽을 수 있는 코드 작성
  • 나쁜 주석 보단 코드로 의도를 표현하라
  • 형식을 준수하는 코드
  • 객체와 자료구조는 혼용하지 말고 용도에 맞게 사용해라
  • 오류 처리는 프로그램 논리와 분리해서 처리해라
  • 외부 코드를 사용할 때는 Wrapper 클래스나 인터페이스를 사용해서 깨끗한 경계를 유지해라
  • 깨끗한 테스트 코드를 유지해라(TDD 관점에서)
  • 클래스의 캡슐화를 깨지말고 응집도를 높이며 결합도를 낮추도록 작은 클래스를 유지해라(SRP와 OCP)
  • 깨끗한 코드뿐만 아니라 깨끗한 시스템도 중요하다.
  • 창발성(부분을 보면 나타나지 않던 특성이 합쳤을 때 나타나는 것, 하나일 때는 할 수 없는 일을 전체가 되면 할 수 있게 되는 등...) - 단순한 설계 원칙을 준수해라
    • 모든 테스트 실행
    • 중복을 없앤다
    • 프로그래머 의도를 표현한다
    • 클래스와 메서드 수를 최소로 줄인다.
  • 동시성을 구현하는 것은 어렵기 때문에 주의깊게 작성해야 한다.

위에서 정리한 이론적인 내용 이후 실제 코드를 예제로 각 원칙을 적용해 점진적인 개선을 이뤄가는 과정을 설명한다.

해당 내용은 따로 요약할 수 없고 직접 보고 실습을 통해 체화해야 할 것으로 보인다.

 

마지막장인 냄새와 휴리스틱에서는 수많은 냄새를 나열하고 제거하는 방법을 하나씩 차분하게 기술해 놓았다. 저자는 차근차근 읽은 후 필요할때마다 꺼내보길 권장하는데 그 자신만만함이 부럽고 신기하다는 생각이 들었다.

해당 냄새들은 "리팩토링" 저서에서 기술된 다양한 코드 냄새와 대부분 겹치며 저자만의 독특한 냄새를 추가했다고 한다.

 

모두가 유명 예술가가 될 수 없고 오랜 기간 동안 같은 일을 했다고 장인이 될 수도 없다.

그래도 어제보다는 오늘이 더 나은 사람이 될 수 있듯이 프로그래머도 더 나은 프로그래머가 될 수 있다.

 

세세한 원칙을 교리로 삼아 철두철미하게 준수할 필요는 없다고 생각한다.

그저 주의 깊게 코딩하고 끊임없이 개선하려는 노력이 깨끗한 코드를 만드는 깨끗한 프로그래머가 될 수 있게 해 줄 것이다.

 

어제보다는 오늘이 더 나은 프로그래머가 되기를...

 

 

 

 

 

 

 

 

 

 

 

'books' 카테고리의 다른 글

새로운 100년  (0) 2020.07.03

2012년 12월 19일에는 18대 대선이 있었고 이 책은 2012년 5월에 출간되었다.

책에는 새로운 정권에 대한 기대와 바람이 담겨져 있다.

2020년 지금 안타깝게도 법륜스님이 바랬던대로 되지는 못했지만 어쩌면 우리는 그 바램대로 이루어질 시대를 겪어내고 있는지도 모른다.

 

2018년에 있었던 세 차례의 남북정상회담을 지켜보면서 그때는 통일이 금방이라도 현실이 될 것만 같았다.

아니 통일까지는 아니더라도 남북의 새로운 미래가 시작될 것이라는 확신을 했었다.

법륜스님이 그렸던 새로운 100년의 미래가 시작된다면 바로 그 때가 시발점이 될 것이다.

비록 전세계가 코로나19로 힘든 지금 남북 관계도 다시 경색으로 돌아가는 것 같지만, 긴 여정에서 겪는 잠깐의 위기이길 바란다.

 

책의 내용은 전반적으로 매우 좋았다.

대담 형식으로 구성한 덕에 자칫 어렵고 따분할 수 있는 내용이 부드럽게 읽혔다. 

몇몇 논란이 될 만한 이야기도 있지만(환단고기 관련된...) 대체적으로 법륜스님의 확고한 신념과 역사와 나라에 대한 애정, 미래에 대한 통찰에 감탄을 했다. 

불교에 대해선 일천하지만 기회가 된다면 법륜스님의 설법이나 강연을 찾아 보고 싶다는 생각이 들었다.

 

한 번쯤 읽어보면 통일과 우리의 미래에 대한 식견을 넓히는 계기가 될 수 있을 것 같다.

친구나 가족에게 추천할 만한 책이다.

 

 

 

 

 

 

'books' 카테고리의 다른 글

Clean Code  (1) 2020.07.06

Go 블로그에 다음과 같은 글이 올라왔다.

https://blog.golang.org/vscode-go

 

The VS Code Go extension joins the Go project - The Go Blog

The Go team 9 June 2020 When the Go project began, “an overarching goal was that Go do more to help the working programmer by enabling tooling, automating mundane tasks such as code formatting, and removing obstacles to working on large code bases” (Go

blog.golang.org

 

요약하자면 Go를 위한 VS Code Extension이 공식적으로 Go Project에 합류했다는 소식이다.

VS Code 블로그에도 같은 날 같은 내용의 포스트가 등록되었다.

 

2019년 조사에 의하면 Go 개발자 중에서 41% 가량이 VS Code에서 Go Extension을 사용해 개발을 하고 있다고 한다. 비공식적으로 VS Code 팀과 Go 팀이 협업을 통해 VS Code의 Go Extension개발을 지원해 왔지만, Go에 있어 VS Code의 위상이 무시하지 못할 수준으로 상승함에 따라 Go 팀에서 더 적극적인 개입(?)이 필요하다고 판단한 것 같다.

 

나 또한 최근까지 VS Code를 주력으로 사용했지만 유독 Go Extension에서 잦은 hang과 정의로 이동(Go to definition)과 같은 기능은 사용할 수 없을 정도로 너무 느려서 결국 Goland로 옮겨갔다. 언제든 성능이 좋아지면 다시 VS Code로 돌아올 요량으로 관련 소식을 모니터링하고 있었는데 매우 반가운 소식이 아닐 수 없다.

 

Go를 위한 VS Code Extension이 공식 Go Project가 되면 무엇이 바뀔까?

대표적으로 다음의 두 가지가 변경된다.

 

  1. 퍼블리셔가 "Microsoft"에서 "Google의 Go 팀"으로 변경
  2. Extension의 리포지토리가 https://github.com/golang/vscode-go 프로젝트로 이동

6/29일 현재 이미 VS Code Go Extension은 "Go Team at Google"로 퍼블리셔가 변경되었고 리포지토리도 변경되었다.

또한 VS Code를 다시 열어보았는데 "Go to definition" 기능은 초기 인덱싱을 제외하고는 즉시 반응하도록 개선되었다.(이전에 개선되었는지 Go 팀으로 변경되면서 개선되었는지는 자세히 확인하지 못했음)

 

이제 다시 VS Code를 주력 IDE로 사용해도 될 것 같다는 생각이 든다.

 

'programming > golang' 카테고리의 다른 글

Go Generic에 대한 소식  (0) 2020.06.28

이 글을 읽는 분이라면 이미 Generic Programming(일반화 프로그래밍)에 대해 들어보았을 것이다. 대표적으로 C++의 템플릿 프로그래밍이 있고 C#, Java와 같은 오래된 언어뿐만 아니라 Swift, Kotlin등 Modern Language에서도 지원한다.

그러나 아직까지 Go에서는 Generic을 지원하지 않는데, 이유는Go의 탄생 배경과 무관하지 않은 것 같다(C++을 싫어해서 만든 언어인데 Generic을 추가하면 언어가 복잡해지는 것을 피하기 힘들다).

 

그럼에도 불구하고 대부분의 Go 프로그래머는 언젠가 Go에서 Generic을 지원하게 될 것이라 기대하고 있을 것이다. Generic에 대한 논의는 2009년 11월 10일 처음 Go가 발표되었을 때부터 벌써 시작된 것 같다. 그 이후에도 프로그래머들은 계속해서 Generic에 대한 필요성을 요구해왔고, 나 또한 처음 Go 1.11을 접한 이후로 매번 새로운 버전이 릴리즈될 때마다 Generic에 대한 기대를 버리지 않고 있다.

 

그렇다면 Generic은 왜 필요할까? 왜 Go 프로그래머는 간절하게 Generic을 원할까?

 

2019년 7월 31일 Go 블로그에 Ian Lance Tayler(Golang 팀 멤버)의 "Why Generics"란 포스트가 등록되었다. 해당 포스트는 GopherCon 2019 에서 저자가 발표한 "Generics in Go"의 블로그 버전으로, 요약하면 다음과 같은 내용이 담겨 있다.

  • Go에 Generic이 추가된다는 건 어떤 의미인가?
  • 왜 Generic을 추가해야할까?
  • Go에 추가되는 Generic의 초안 디자인

해당 글에서 Ian이 강조하는 것은 Go의 단순함과 명확함을 손상하지 않고 Generic을 가져오는 것이다. 그럼에도 불구하고 해당 글에서 제안한 초안 디자인은 다른 언어의 Generic보다 결코 단순하고 명확하지 않은 모습을 보여 준다. 오히려 Go의 제한적인 문법 특성 때문인지 부가적인 문법(Contract, Ordered...)이 추가되어 해당 디자인이 그대로 확정되지 않기를 바라는 마음이 들 정도이다.

 

다행히도 최근 글인 "The Next Step for Generics"에서 업데이트된 초안 디자인에는 Contract 컨셉이 제외되었다는 언급이 있었다. 또한 간단히 테스트해 볼 수 있도록 실험도구인 translation 도구도 제공하는데 go2goplay 에서도 테스트해 볼 수 있다.

 

go2goplay 예제코드는 다음과 같다.

package main

import (
	"fmt"
)

func Print(type T)(s []T) {
	for _, v := range s {
		fmt.Print(v)
	}
}

func main() {
	Print([]string{"Hello, ", "playground\n"})
}

 

이대로만 나와줘도 좋을 것 같은데, "The Next Step for Generics"에서는 Go 커뮤니티의 피드백을 받아 초안 디자인에 큰 변화가 필요하지 않고 공식 언어 변경 제안도 무사히 통과했을 때를 가정하면, 결국 최대한 낙관적으로 예측해도 2021년 8월 Go 1.17 릴리즈에나 Generic이 정식으로 포함될 것 같다고 한다.

 

아직은 조금 더 기다려야 할 것 같다.

'programming > golang' 카테고리의 다른 글

Go 팀에서 공식적으로 VS Code Go Extension을 지원  (0) 2020.06.29

NOTE!
이 문서는 Flutter.io의 문서를 한글로 번역한 문서입니다. 원문 바로가기

다음 페이지들로부터 Flutter 프레임워크에 대해 더 배워볼 수 있습니다:

Flutter 기본

이미 알고 있는 지식 적용하기

그 외 리소스들

행복한 Flutter 개발하세요!

NOTE!
이 문서는 Flutter.io의 문서를 한글로 번역한 문서입니다. 원문 바로가기

소개

Flutter는 iOS와 Android에서 고 수준의 Native 인터페이스를 만들 수 있는 구글의 모바일 SDK입니다. Flutter는 전 세계의 개발자와 조직에서 사용되는 기존 코드와 함께 작동하고, 무료이며 오픈 소스입니다.

이번 코드 실습에서는, 상호작용 기능이 포함된 기본적인 Flutter App을 확장해 볼 예정입니다. 두 번째 페이지(경로라고 불리는)를 만들고 사용자는 해당 페이지로 이동할 수 있습니다. 마지막으로 App의 컬러 테마를 변경합니다. 이 코드 실습은 part 1을 확장하지만 part 2에서 바로 시작하기를 원하는 사용자를 위해 시작 코드를 제공합니다.

part2에서 배우는 것들

  • iOS와 Android에서 자연스럽게 보이는 Flutter App 만들기
  • 빠른 개발 사이클을 위해 핫 리로드 사용하기
  • 상태 저장 위젯에 상호작용 기능을 추가하는 방법
  • 두 번째 화면을 만들고 이동하는 방법
  • App의 테마를 변경하는 방법

part2에서 만드는 것

스타트업 회사를 위해 끝없이 이름을 생성해 주는 간단한 모바일 앱을 만드는 것으로 시작합니다. 이번 코드 실습 이후에, 사용자는 이름을 선택하거나 선택해제하면서 최상의 이름을 찾아 저장할 수 있습니다. 우측 상단의 리스트 아이콘을 탭하면 즐겨찾기된 이름 리스트가 있는 새로운 페이지로 이동합니다.

아래 GIT는 완성된 App의 작동 방식을 보여줍니다.

이미지1

Flutter 환경 설정

part1을 완료하지 않았다면 part1 문서에 있는 Flutter 환셩 설정 부분을 참고해서 Flutter 개발환경을 설정합니다.

시작 App 구하기

part1을 수행해서 이미 startup_namer이름을 갖는 시작 App을 만든 경우 다음 단계를 수행합니다.
startup_namer App이 없을 경우 다음 안내를 따라 주세요.

  1. 첫 번째 Flutter App 만들기문서를 보고 간단한 Flutter App을 만드세요. 프로젝트 이름은 startup_namer로 합니다.
  2. lib/main.dart 파일의 내용을 모두 삭제하세요. 스타트업 이름을 제안하는 지연된 로딩 기능과 무한 출력 기능을 구현한 이 파일의 내용으로 다시 작성합니다.
  3. English Words 패키지를 추가하기 위해서 pubspec.yaml 파일을 다음과 같이 수정하세요.
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.2
  english_words: ^3.1.0    // Add this line.

English Words 패키지는 랜덤하게 단어 쌍을 생성해서 스타트업 이름을 제안해 줍니다.

  1. Android Studio의 편집 뷰에서 pubspec을 보는 동안 우측 상단의 Packages get을 클릭합니다. 콘솔에서 다음과 같은 내용을 볼 수 있습니다:
flutter packages get
Running "flutter packages get" in startup_namer...
Process finished with exit code 0
  1. app을 실행합니다. 원하는 만큼 스크롤을 하면 스타트업 이름이 계속해서 생성되어 출력되는 것을 볼 수 있습니다.

리스트에 아이콘 추가하기

이번 단계에서, 각 로우에 하트 아이콘을 추가합니다. 그 다음에는 해당 아이콘을 탭해서 즐겨찾기할 수 있는 코드를 작성합니다.

  1. RandomWordsState클래스에 _saved Set을 추가합니다. 이 Set에는 사용자가 즐겨찾기한 단어 쌍을 저장합니다. Set은 중복된 요소를 허용하지 않으므로 List보다 낫습니다.
class RandomWordsState extends State<RandomWords> {
  final List<WordPair> _suggestions = <WordPair>[];
  final Set<WordPair> _saved = Set<WordPair>();   // Add this line.
  final TextStyle _biggerFont = TextStyle(fontSize: 18.0);
  ...
}
  1. _buildRow 함수에서, 단어 쌍이 아직 저장되지 않았는지 검사하기 위해 alreadySaved 변수를 추가합니다.
Widget _buildRow(WordPair pair) {
  final bool alreadySaved = _saved.contains(pair);  // Add this line.
  ...
}

_buildRow 함수에서 즐겨찾기 기능을 추가하기 위해 ListTile 객체에 하트모양의 아이콘을 추가합니다. 다음으로는 하트 아이콘과 상호작용할 수 있는 기능을 추가합니다.

  1. 다음과 같이 아이콘을 추가합니다:
Widget _buildRow(WordPair pair) {
  final bool alreadySaved = _saved.contains(pair);
  return ListTile(
    title: Text(
      pair.asPascalCase,
      style: _biggerFont,
    ),
    trailing: Icon(   // Add the lines from here...
      alreadySaved ? Icons.favorite : Icons.favorite_border,
      color: alreadySaved ? Colors.red : null,
    ),                // ... to here.
  );
}
  1. 핫 리로드를 하면 각 로우에 열린 하트를 확인할 수 있습니다. 아직 상호작용 기능은 동작하지 않습니다.

이미지1이미지2

문제가 있나요?

App이 정확히 동작하지 않을 경우, 다음 링크의 코드와 비교해 볼 수 있습니다.

상호작용 기능 추가

이번 단계에서는, 하트 아이콘을 탭할 수 있도록 만듭니다. 사용자가 리스트의 요소를 탭하면 즐겨찾기 상태가 토글되면서 즐겨찾기 저장소에 저장되거나 리스트에서 삭제됩니다.

이렇게 구현하기 위해, _buildRow 함수를 수정해야 합니다. 단어 쌍이 이미 즐겨찾기 저장소에 추가되어있다면 삭제합니다. 타일(List Tile)을 탭할 때 마다 상태가 변경되었음을 프레임워크에 알리기 위해 setState() 함수가 호출됩니다.

  1. onTap 함수를 다음과 같이 추가합니다:
Widget _buildRow(WordPair pair) {
  final alreadySaved = _saved.contains(pair);
  return ListTile(
    title: Text(
      pair.asPascalCase,
      style: _biggerFont,
    ),
    trailing: Icon(
      alreadySaved ? Icons.favorite : Icons.favorite_border,
      color: alreadySaved ? Colors.red : null,
    ),
    onTap: () {      // Add 9 lines from here...
      setState(() {
        if (alreadySaved) {
          _saved.remove(pair);
        } else {
          _saved.add(pair);
        }
      });
    },               // ... to here.
  );
}

TIP Flutter의 반응형 스타일 프레임워크에서 setState()를 호출하면 State 객체의 build() 메서드가 호출되고 그 결과로 UI를 갱신하게 됩니다.

App을 핫 리로드합니다. 즐겨찾기 표시를 하거나 해제하기 위해 아무 타일이나 탭을 해 봅니다. 타일을 탭하면 해당 지점에서 잉크 번짐 애니메이션이 생성됩니다.

이미지3이미지4

문제가 있나요?

App이 정확히 동작하지 않을 경우, 다음 링크의 코드와 비교해 볼 수 있습니다.

새로운 화면으로 이동하기

이번 단계에서는, 즐겨찾기 표시한 단어 쌍만 출력하는 새로운 페이지(Flutter에서 경로-route-라고 불리우는)를 추가합니다. 이번 단계를 통해 홈 경로와 새로운 경로(route)사이를 이동하는 방법에 대해 배우게 됩니다.

Flutter에서는 Navigator가 App의 경로들이 포함된 스택을 관리합니다. Navigator의 스택에 경로를 추가하면 해당 경로가 출력됩니다. Navigator 스택에서 경로를 빼내면 이전 경로가 출력됩니다.

다음으로, RandomWordsState에 있는 build 메서드에서 AppBar에 리스트 아이콘을 추가합니다. 사용자가 리스트 아이콘을 클릭하면 즐겨찾기 표시한 단어 쌍을 포함한 새로운 경로가 Navigator에 추가되고 아이콘이 출력됩니다.

class RandomWordsState extends State<RandomWords> {
  ...
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
        actions: <Widget>[      // Add 3 lines from here...
          IconButton(icon: Icon(Icons.list), onPressed: _pushSaved),
        ],                      // ... to here.
      ),
      body: _buildSuggestions(),
    );
  }
  ...
}

TIP 단일 자식 위젯(child)을 갖는 위젯도 있고, 여러 자식 위젯(children)을 갖는 위젯도 있습니다. 여러 자식 위젯을 정의할 때는 대괄호([])로 배열을 표현합니다.

  1. RandomWordsState 클래스에 _pushSaved() 함수를 추가합니다.
void _pushSaved() {
}
  1. App을 핫 리로드합니다. App Bar에 리스트 아이콘이 출력됩니다. 이 아이콘을 탭해도 아직은 아무런 동작도 하지 않습니다.

다음에는, Navigator 스택에 경로를 추가합니다. 이 행위에 의해 새로운 화면으로 이동하게 됩니다. 새로운 페이지에 포함된 컨텐츠는 MaterialPageRoute의 익명함수인 builder 속성에서 만들어집니다.

  1. 아래 코드와 같이 Navigator.push를 호출하면, Navigator의 스택에 새로운 경로가 추가됩니다. IDE는 코드에 문제가 있다고 출력하겠지만 곧 작동하는 코드를 추가하게 될 겁니다.
void _pushSaved() {
  Navigator.of(context).push(
  );
}

다음으로, MaterialPageRoute와 builder를 추가해야 합니다. 우선 지금은 ListTile 로우를 생성하는 코드를 작성합니다. ListTile의 divideTiles() 메서드는 ListTile간 수평 여백을 추가합니다. divided 변수는 toList() 함수에 의해 리스트로 변환된 마지막 로우들을 보관합니다.

  1. 아래 코드를 추가하세요:
void _pushSaved() {
  Navigator.of(context).push(
    MaterialPageRoute<void>(   // Add 20 lines from here...
      builder: (BuildContext context) {
        final Iterable<ListTile> tiles = _saved.map(
          (WordPair pair) {
            return ListTile(
              title: Text(
                pair.asPascalCase,
                style: _biggerFont,
              ),
            );
          },
        );
        final List<Widget> divided = ListTile
          .divideTiles(
            context: context,
            tiles: tiles,
          )
          .toList();
      },
    ),                       // ... to here.
  );
}

builder 속성은 새로운 경로에 "Saved Suggestions - 저장된 제안들"이란 이름의 App Bar를 포함하는 Scaffold를 반환합니다. 새로운 경로는 ListTiles 로우를 포함하는 ListView로 구성되며 각 로는 구분선으로 분리됩니다.

  1. 아래 코드와 같이 수평 구분선을 추가합니다:
void _pushSaved() {
  Navigator.of(context).push(
    MaterialPageRoute<void>(
      builder: (BuildContext context) {
        final Iterable<ListTile> tiles = _saved.map(
          (WordPair pair) {
            return ListTile(
              title: Text(
                pair.asPascalCase,
                style: _biggerFont,
              ),
            );
          },
        );
        final List<Widget> divided = ListTile
          .divideTiles(
            context: context,
            tiles: tiles,
          )
              .toList();

        return Scaffold(         // Add 6 lines from here...
          appBar: AppBar(
            title: Text('Saved Suggestions'),
          ),
          body: ListView(children: divided),
        );                       // ... to here.
      },
    ),
  );
}
  1. App을 핫 리로드합니다. 선택한 항목 중 일부를 즐겨찾기하고 App Bar에서 리스트 아이콘을 탭합니다. 즐겨찾기한 항목들이 출력되는 새로운 경로가 출력됩니다. Navigator가 App Bar에 "뒤로가기-Back" 버튼을 추가합니다. 뒤로가기 위해서 명시적으로 Navigator.pop 기능을 구현할 필요가 없습니다. "Back" 버튼을 탭하면 홈 경로로 이동합니다.

이미지5이미지6

문제가 있나요?

App이 정확히 동작하지 않을 경우, 다음 링크의 코드와 비교해 볼 수 있습니다.

테마를 이용해서 UI 변경하기

다음 단계에서는, App의 테마를 변경합니다. 테마는 App의 룩앤필을 제어합니다. 실제 기기나 에뮬레이터에서 제공하는 기본 테마를 사용하거나 브랜딩을 반영하는 사용자정의된 테마를 사용할 수 있습니다.

ThemeData 클래스를 설정하는 것으로 App의 테마를 쉽게 변경할 수 있습니다. 지금 만들고 있는 App은 기본 테마를 사용하고 있지만 App의 주요 색상(primary color)을 흰색으로 변경할 수 있습니다.

  1. MyApp 클래스에서 색상 변경하기:
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      theme: ThemeData(          // Add the 3 lines from here...
        primaryColor: Colors.white,
      ),                         // ... to here.
      home: RandomWords(),
    );
  }
}
  1. App을 핫 리로드합니다. 전체 배경색이 App Bar를 포함해서 이제 모두 흰색으로 변경되었습니다.

또 다른 연습으로 ThemeData를 사용해서 UI의 다른 부분을 변경해 보세요. Material 라이브러리의 Colors 클래스는 사용할 수 있는 많은 색상을 제공하고, 핫 리로드를 사용해서 빠르게 적용해 볼 수 있습니다.

이미지7이미지8

문제가 있나요?

App이 정확히 동작하지 않을 경우, 다음 링크의 코드와 비교해 볼 수 있습니다.

잘 했어요!

iOS와 Android 모두에서 작동하는 상호작용 Flutter App을 만들어 보았습니다. 이번 코드 실습에서 배운 것은 다음과 같습니다:

  • Dart code 작성하기
  • 빠른 개발을 위해 핫 리로드 사용하기
  • App에 상호작용하는 기능을 추가하기 위해 상태 저장 위젯을 구현하는 방법
  • 홈 경로와 새로운 경로 사이를 이동하기 위해 경로를 생성하고 코드를 작성하기
  • 테마를 사용해서 UI의 룩앤필을 변경하는 방법

다음에 배울 것들

Flutter SDK에 대해 더 배우고 싶다면:

그 외의 리소스들:

'programming > flutter' 카테고리의 다른 글

(6) Flutter - 더 배워보기  (0) 2019.11.02
(4) Flutter - 첫 번째 Flutter App 만들기, part1  (0) 2019.10.27
(3) Flutter - 맛보기(Test Drive)  (0) 2019.10.27
(2) Flutter - 편집기 설정  (0) 2019.10.27
(1) Flutter - 설치  (0) 2019.10.27

+ Recent posts