UIデザイナー1年生がコードを書いてみた!コードからGUIを見てみる
はじめに
最近、私は社内の新卒メンバーとReactのTypescriptを用いた、OOUI(オブジェクト指向ユーザーインターフェイス)の学びに焦点を当てた小さな勉強会を開いていました。
そしてこの経験を通して、UIデザイナーがコードを書いてみることの価値を深く感じるようになりました。
勉強会を始めた当初、私は単にエンジニアの仕事や、彼らがどんな世界を見ているのかを理解したいと思っていましたが
実際にコードを書いてみることで、UIデザインの表面だけでなくその奥にある”情報そのもの”に触れることができた感覚があります。
この記事では、デザイナーがUIデザインで表現しているオブジェクトが、コードでどのように記述されているのかについて、簡単に説明したいと思います。
(広い心と温かい目でお読みください😌)
勉強会のきっかけ
この勉強会を行っている私を含めた3人は、入社後のとある研修プロジェクトで、社内求人サービス(Webアプリケーション)の開発を行っていました。
エンジニアとの協業経験はほぼゼロだった私にとって、今後学ぶべき課題を発見できた良い機会になったのですが
プロジェクト期間中、メンバーにワイヤーフレームを提案しながら、「でもこれって実装できるんかな…」みたいな若干の不安感をずっと感じていました。
私の心境
『設計の構造…?みたいなも…の….を理解せずに?作っている気がするだが…?見た目そのまんま本当に実装できるのか…?エンジニアって魔法使いってこと…?』
そう思った私は、プロジェクトページに存在していた謎の図を発見しました!
これを理解しないとUIデザインなんて仕事は務まらないのではないか…?と思った入社1ヶ月の私は、早速エンジニアに無知を披露していました↓
(ゆめみの新卒エンジニアはみんなとっても優しいので丁寧に説明してくれました。私が理解できたというわけではない😊)
この研修プロジェクトが(無事に?)ひと段落した後、フロントエンドエンジニアとデザイナーの一部メンバーで行った振り返りではこんな発話がありました。
『なんか、大事なこと抜け落ちてたくない…??』
その1つが、今私たちが勉強会のテーマとしているOOUIという概念でした。
OOUIについて
この図はJesse James Garrettの「The Elements of User Experience」です。
開発プロセスの中で、UIデザイナーはこの図の主に構造、骨格、表層を担当するかと思います。
そして、この5段階の中でも構造の部分はUIの土台になる部分のため、構造設計が甘いとUX設計の全体がグラグラしてしまいます。
(開発プロセスにおいても手戻りが発生しがちかも?)
私たちが取り組んでいたプロジェクトにおいても、抜け落ちていたのがおそらくここでした。
この構造設計において、モデリングを行う1つの方法として、重要な概念として登場するのがOOUI(オブジェクト指向ユーザーインターフェイス)です。
デザイン関係の書籍を通して、OOUIをなんとなく知っていた私でしたが
ReactのTypescriptで具体的なコードを書いたことで、ビジュアルデザインと情報設計は完全に分離されているということを実感することができました。
書籍「オブジェクト指向UIデザイン」の著者である上野学さんは、
と述べていますが、UIデザイナーがコードを書いてみる試みは、UIデザイナーが「その中が何でできているのか」を問うてみる(見てみる)ようなことだと思っています。
オブジェクトはコードでどう表現されるのか
ここでは簡単に、ProfileCardのUIコンポーネントを定義し、その中でProfile情報を受け取り、ProfileCardのUIが構築される基本的な骨組みを説明します。
※オブジェクトを、具体的にどのような様子・見た目で画面上に表現するのかについての詳しいコードは今回記述していません。
ProfileCardのUIが構築される基本的な骨組み
UIは、Profileオブジェクトを
→ProfileCardに変換する「関数」★として記述されます
★const ProfileCard = ({ profile }) => {
return (
// ここに具体的にどのような様子・見た目で画面上に表現するのか記述します
);
};
「関数」とはなんでしょうか👀
const 関数名 = (引数) => {
return 返り値
}
関数とは、「引数」を入れて「返り値」が返ってくるものです。
中学生の頃に学んだ関数、y=f(x)の構造を思い出します。
例えばy=2xの時、xに4を入れると、yは8になります
この時、xは「引数」でyは「返り値」といえます
こんなイメージ↓
y=f(x)//yはxについての関数
y=2xのとき
8=f(4)
//
const 関数名 = (4) => {
return 8
}
const 関数名 = (引数) => {
return 返り値
}
改めて先ほどのコードに戻ると
ProfileCardという名前の関数は、「profile」という引数を受け取り、返り値として画面上にUIが構築されている、といえます。
つまりUIは、関数が何かしらのデータを引数として受け取った結果です。
★const ProfileCard = ({ profile }) => {
return (
// ここに具体的にどのような様子・見た目で画面上に表現するのか記述します
);
};
☆では、このProfileCardにどんなデータを渡すかのルールを決めています
☆interface ProfileCardProps {
profile: Profile;
}
★const ProfileCard: FC<ProfileCardProps> = ({ profile }) => {
return (
// ここに具体的にどのような様子・見た目で画面上に表現するのか記述します
);
};
☆では、「profileというデータは、Profileオブジェクト(=Profileという型)である」 というようなルールを決めています。
ProfileCard関数が受け取る、データの形式に関するルールを決めている感じ
★では、「ProfileCard関数は、Profileオブジェクト(=Profileという型)のデータを引数として受け取り、それに基づいてUIを構築するFunctional Component(FC)です」と定義してあげているイメージです。
Profileオブジェクト(=Profileという型)とは
type Profile = {
name: string;
role: string | undefined;
catchcopy: string | undefined;
iconUrl: string;
favorits: {
foods: string[];
colors: string[];
artists: string[];
};
};
ここでは、Profileという型を定義しています。
Profile型は、Profileオブジェクトの形式を指定しているような感じです。
例えば、nameはプロフィールの名前を表す文字列型(string)のプロパティですね、みたいなことです。
そして、Profileオブジェクト(抽象)の具体としてprofileデータがあります。
profileOfMeika: Profile = {
name: "Meika KOBAYASHI",
role: "UIデザイナー",
catchcopy: "いつも上機嫌なJKマインドmama",
iconUrl: "Meika.png",
favorits: {
foods: ["餃子", "プリン", "酒"],
colors: ["水色", "ピンク", "黄緑"],
artists: ["MIZ", "ゆうらん船", "CHAI", "KIRINJI"]
}
};
この、具体であるprofileデータを関数★にいれることで、そのデータに対応するUIが立ち上がります。
具体であるprofileデータの型と、ProfileCard関数はそれを受け取る関数コンポーネントである、ということは先ほど説明したように定義してあげてるので、これでOK。
☆interface ProfileCardProps {
profile: Profile;
}
★const ProfileCard: FC<ProfileCardProps> = ({ profile }) => {
return (
// ここに具体的にどのような様子・見た目で画面上に表現するのか記述します
);
};
関数コンポーネントとは、単なる関数である
なんとなく、UIが立ち上がるイメージがつくと、オブジェクトの実体が近づいてくる気がしてくるような…。
コードで書いてみることで、具体的なprofileデータが入ったUIコンポーネントは確かにユーザーの目当てを表現してしますが、特定の誰かの特定の状況下の、ある一瞬の具体的な情報であることもわかるかと思います。
デザイナーがfigmaでささっと作るあの画面の、「誰か」の部分は変わりますし、「一瞬」もどんな状態を切り取るかで変わる、ということを改めて理解できるかと思います。(書いてみると当たり前なのですが)
オブジェクト構造を理解できると何がいいのか
コードを見てみることで、デザイナーは画面を作りながら、「今オブジェクトをここに呼び出している」という感覚を今以上に持てるかもしれません。
こんな状況ってたまにありません…?
例えばですが、デザイナーが良かれと思ったレイアウト変更が、エンジニアにとっては工数がぁぁ…な状況。
エンジニア的には、「そもそも今のオブジェクト構造で、特定のそのデータだけを呼び出すのは難しい」となっていたりするのかも?と想像ができたりします。
そんな時、デザイナーがオブジェクト構造を理解していれば、変更のない範囲でのベストなデザインを考えることは可能かもしれません。
もしエンジニアにとって負荷の高い変更(例えばオブジェクト構造の変更)をしてでも必要なデザイン更新なのであれば、「ユーザーにとってどのように良くなるのか」ということをエンジニアとも共有する必要があるかもしれません。
もちろん、エンジニア・デザイナーともに、めんどくさいだけを理由に実装やデザインに嫌な顔をするのはダメですよね。
でも、めんどくさいけどやる必要があるのか?を判断する基準は、その仕事はユーザーにとって重要なのか?だと思います。
つまり、ユーザーのメンタルモデルである「適切に抽出されたオブジェクト」をデザイナーとエンジニアで共有できていれば、建設的な議論が可能になるかもということです。
(そのためには、ユーザーの活動領域(ドメイン)の把握をし、モデリングを行うところから議論できるともっといいのかも?)
この勉強会を通して、私はしっかりデータ構造を理解するために学び、初期の構造設計からビジュアルデザインまで、エンジニアと一緒に議論に参加できるようになりたいな〜と思うようになりました。
仕事をしていると、これって実装コスト高いんかな〜とか、エンジニアに嫌な顔されんかな〜とか、知識とコミニケーション能力の足りなさゆえに判断に迷ったり、言葉を選ぶことに時間をかけてしまう場面があります。
少し前の私は、デザイナーがエンジニアリングを理解する目的は、エンジニアにできるだけ優しくありたいから、円滑なコミニケーションを取りたいからだと思っていたのですが。
それは、プロジェクトメンバーとして誠実に向き合うべきだという当たり前の姿勢であるかもしれないです。
あるべきUIとしてモデリングされ、それが実装されるためにデザイナーがデータ構造を理解するのは、いたって自然なことかもしれないと思うようになりました。
実際仕事をしていると、いろんな事情で結局目の前のfigmaのデータ作りをがむばるしかにゃい!みたいなこともあるわけで。
でもまずはできるだけ情報は自分で取りに行くことと、
そして今自分はビジュアルデザインを検討しているのか、構造設計から見直しているのか、それらを明示的に述べられるようになりたいなと思いました。
そして、「はじめから言ってくれれば良かった」「もう少し前に知りたかった」と感じるような、すれ違いを減らしていきたいな〜と思っています。
おわりに
色々書きましたが、コードを書いてみるの、めちゃくちゃ楽しい!
というか、できないことやわかっていないことが理解できて、それを学びにいっての繰り返しがとにかくたのしい。
私にとっては学びの過程自体が目当てなんだな〜ということを実感しています。
そして、この勉強会を推進してくれた同期のエンジニアはじめちゃんと、一緒に頑張ったデザイナーおっさむに心からの感謝を伝えたいです😌
今後、はじめちゃんが私よりもわかりやすく丁寧な記事を書いてくれると思うので、興味を持った方はぜひそちらの記事を読むことをお勧めします。
参考記事・書籍
この記事が気に入ったらサポートをしてみませんか?