4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

僕が「宣言的」について納得感を得るまでの道のり。

Last updated at Posted at 2022-03-21

はじめに

Declarative(宣言的)とImperative(命令的)についてはすでに秀逸な情報源がたくさんあります。おかげさまで僕も、この二つの概念についてわかった気がしないでもないです(本当にわかってるのかは自信ないですが悪しからず)。この記事では、僕がどんな道のりでこれらの概念に納得感を得たのかを具体的に綴ります。参考になれば幸いです。

※JavaScript、Reactを題材にしています。
※記事の中にいくつかコードが出てきますが、コード自体が大事なわけではないので、さらっと目を通す程度で大丈夫です。
※あくまで僕なりの理解なので、「そういう理解の仕方もありかもねー」くらいに読んでいただけると。

僕と「宣言的」の出会い。

Reactの勉強で、僕は初めて「宣言的」という言葉に触れました。Reactの公式doc・いくつかの記事を拝見しましたが、納得感は得られず。「UIの結果を宣言的に記述する」とは、、?
確かに、

const app = document.getElementById('app')
const header = document.createElement('h1')
const headerContent = document.createTextNode('Hello, World!')
header.appendChild(headerContent)
app.appendChild(header)

のような「命令的」なるものよりも、

const app = document.getElementById("app")
ReactDOM.render(<h1>Hello, World!</h1>, app)

のような「宣言的」なるものの方がスッキリしていてわかりやすいです。ただ、「この宣言的なコードがUIの結果を表している」と言われても、僕にはピンと来ませんでした。

少し理解が進んだ気がする。

nextの勉強の中で、僕の「宣言的」「命令的」に対する理解が進みました。
「nextの勉強をしたから理解が進んだ!」というわけではなく、Reactを通じて「宣言的」「命令的」について少しずつ慣れてきたんだと思います。
nextの公式docを読んでいるときに、「あ、ちょっとわかったかも」となったので、以下、nextの公式docにある宣言的・命令的についての記述を恣意的に抜粋しつつ説明します。また、"UI"と言うとちょっといかめしいので、ここでは柔らかく「見た目」と表現します。

nextの公式docでは以下のコードを例に説明がなされています。

<!-- index.html -->
<script type="text/javascript">
      // Select the div element with 'app' id
      const app = document.getElementById('app')

      // Create a new H1 element
      const header = document.createElement('h1')

      // Create a new text node for the H1 element
      const headerContent = document.createTextNode(
        'Hello, world!'
      )

      // Append the text to the H1 element
      header.appendChild(headerContent)

      // Place the H1 element inside the div
      app.appendChild(header)
    </script>

上記のコードは「命令的」の典型らしいです。上記のコードについて、nextの公式docでは次のように記されています。

You’re writing the steps for how the user interface should be updated.

「このコードは、見た目がどのように更新されるかを記述しているね」といったところ。もっと平たく言えば、「見た目が変わる『過程』を記述してるね」といったところでしょうか。

ふむ。

この命令的コードでは見た目が変化する「過程」が記述されていて、「結果的にどんな見た目になるか」にはあまり関心がないということですね。

nextの公式docはこう続きます。

But when it comes to building user interfaces, a declarative approach is often preferred because it can speed up the development process.Instead of having to write DOM methods, it would be helpful if developers were able to declare what they want to show (in this case, an h1 tag with some text).

このお気持ちを僕なりに代弁してみると(和訳ではない)、「でも、見た目が変化する『過程』よりも『結果的にどんな見た目になるか』の方が、コード書くときはありがたみがあるよね?」といったところでしょうか。そして、「だから命令的よりも宣言的の方がありがたいよね!」となるでしょう。

ふむふむ。なんとなく「宣言的」「命令的」がわかってきた気がします。ここまでの理解をまとめてみると、

  • 見た目が変化する過程を記述 → 命令的
    • 「こんな過程で見た目を作りなさいね!」とコードで命令している。
  • 結果的にどんな見た目になるかを元にして記述 → 宣言的
    • 見た目が変化する過程は置いといて、「こんな見た目になります」ということをコードで宣言しているイメージ。

のようになるでしょうか。ちょっとわかってきた気がする。

が、依然としてもやもや感は残ります。だって、上記の命令的コードを宣言的コードに書き換えたのが以下のコードらしいんですが、

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('id')
);

これのどこが「結果的にどんな見た目になるか」なんだ、、?

別な例を示します。以下はReactでカウントボタンを実装したコードですが、このコードから「見た目」を想像することはできるのだろうか、、?

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

僕なりの納得感を得ました。

色々あって、「宣言的」について僕なりの納得感を得るに至りました。それは、「ここでいう"UI"(見た目)は、そもそも何を意味しているんだろう?」という問いがきっかけだったように思います。
ここでも、"UI"だといかめしいので基本的に「見た目」と書きます。

そもそも、「宣言的」について考える際の「見た目」は何を意味しているのか。

この問いに対して僕は、「ここにこんな大きさのボタンがあって、ここにこんなフォントでこんな大きさでこんな色の文字が表示されて、、、」というような具体的なものを想定していました。そのため、「宣言的なコードを読んでも、別に『見た目』なんて想像できないぞ、、?」ともやもやしていたんですね。

そこで、「ここで言う『見た目』って、もっと抽象的なものなんじゃないのか?」 と考えたのが、僕なりの納得感のきっかけです。あくまで、僕なりの納得感。

「見た目」がもっと抽象的なもの、というのは、以下の図を見ていただければ伝わるかと。
image.png

この図はnextの公式docにあるものです。DOMについては置いといて、この図を見ると、「"UI"(見た目)が、一定の『構造』をもとにして作られている」ということがわかります。要は、「見た目」を、「このような『構造』を反映したもの」として捉えてみるといいかも 、ということです。

このように「見た目」を捉え直してみると、「宣言的なコードは『結果的にどんな見た目になるか』を表現している」ということにも納得感を得られないでしょうか?

例えば、先程のカウントボタンのコードを再掲します。

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}

このコードからは、「ここにこんな大きさのボタンがあって、ここにカウント数が表示されて、、、」といった具体的なことはわかりません。でも、「このコードが表す『見た目』として、divタグの中にpタグによる文字列と、ボタンが1つあるんだな」という構造はわかります。この、「抽象的に捉えた『見た目』」が、「宣言的」を語る際の"UI"なのではないかと僕は思ったわけです。

終わりに

あくまで僕なりの納得感で、「こんな捉え方をしてみると、もやもや感が軽減されるかも」という一つの提案に過ぎません。もし、記事の中に誤り・不適切な点などがありましたらお気軽にお伝えください!

最後までお読みいただきありがとうございました。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?