ソフトウェア工学はプログラミングとは異なります

すべてのソフトウェアエンジニアがプログラミングできますが、すべてのプログラマーがソフトウェアをエンジニアできるわけではありません

jsComplete.com/pro-programmer
更新:この記事は現在、私の著書「The Professional Programmer」の一部です。
このコンテンツの更新版、およびjscomplete.com/pro-programmerでのプログラミングのアドバイスをお読みください。

エンジニアリングの比phorのために、ソフトウェアエンジニアという用語を好まない人もいます。この記事はその用語についてではありません。気に入らない場合は、ソフトウェア作成者、ソフトウェア職人、またはソフトウェアアーティストに置き換えることができます。

ソフトウェアエンジニアとは、高品質のソフトウェアを自分の職業として書くことを検討している人のことです。科学と統計をその職業に適用し、それを単なるお金を稼ぐ仕事と見なさない人。

プログラム方法を知っていても、ソフトウェアエンジニアになるわけではありません。

誰でもプログラミングを学ぶことができます。それは簡単です。誰でも自分のマシンで動作する簡単なプログラムを作成できますが、同じプログラムが他の人でも動作することを保証するものではありません。

これについての私の好きな例えは、誰もが歌いながらシャワーを浴びることができるということですが、パーティーの時は自分の歌の録音を再生しません。あなたはプロと一緒に行きます。

もっと類似?確かに:

  • 私たちは学校で数学とライティングを学びましたが、それは数学者や著者にはなりませんでした。
  • 私たちのほとんどは簡単に料理を学ぶことができますが、多くの人に食事を提供するときはシェフを雇います。
  • 一から家を建てるために近所の便利屋を呼ぶことはありません。

この記事で共有したい主なメッセージは、単純なプログラムは工学的プログラムとは大きく異なるということです。

プログラミングの行為は、その最も単純な定義では、何らかの出力を生成するために何らかの入力で何かをするようコンピューターに指示を与えることです。

エンジニアリングソフトウェアの行為は、多くのユーザーの問題を解決することを目的としたコンピュータープログラムの設計、作成、テスト、および保守です。それは、時の試練に耐え、元の明白な問題の周りのいくつかの未知の問題に対して機能する堅牢で安全なソリューションを作成することです。

ソフトウェアエンジニアは、解決する問題、提供するソリューション、それらのソリューションの制限、プライバシーへの影響、およびセキュリティへの影響に関するすべてを理解しています。

誰かが問題を理解していない場合、その解決策をプログラムすることは許可されません。

ソリューションの精神

ソフトウェアエンジニアは、自分のキャリアを単なるプログラムの作成とは考えていません。彼らはニーズを満たし、問題を解決するという観点から考えています。すべての問題がプログラムを必要とするわけではないため、これは重要です。一部の問題は、既存のプログラムまたは複数のプログラムをまとめることで解決できます。一部の問題は、早期に行動することで完全に防ぐことができます。優れたプログラムの設計には、多くの場合、将来の問題を防ぐための計画が含まれます。

「知的は問題を解決し、天才はそれを防ぎます。 「
- アルバート・アインシュタイン

複雑な問題には通常、複数のプログラムを書く必要があります。並行して実行するプログラムが必要な問題もあれば、順次実行するプログラムが必要な問題もあります。一部の問題は、ユーザーを教育することで解決できます。

プログラムを作成する前に、ソフトウェアエンジニアが質問をします。

  • どのような問題を解決しようとしていますか?
  • それらを解決するためにコードを書く以外にできることは何ですか?
  • これらの問題をコードで解決しやすくするために何ができますか?

コード品質

優れたプログラムは明確で読みやすく、簡単に拡張でき、他のプログラムと連携して機能します。また、それらを維持することは悪夢ではありません。コードの品質は交渉可能なものではありません。締め切りや感情のためにずさんなショートカットを使用することは決して許されません。

エンジニアリングソフトウェアの最も重要な側面の1つは、拡張可能な状態で何でもゼロから設計することです。ソフトウェアの変更は現実です。ユーザーは、より多くの機能とソフトウェアのより簡単な使用方法を求めます。

通常、ソフトウェアはそれ自体ではあまり有用ではありません。有用なソフトウェア機能は、複数のソフトウェアが相互に通信し、データを交換し、データとインターフェイスをユーザーに提示するタスクで共同作業を行うことから始まります。

プログラムはそれを念頭に置いて設計する必要があります。彼らはどんなメッセージを受け入れますか?どのイベントが監視されますか?どのメッセージが出力されますか?通信を認証および承認するにはどうすればよいですか?

優れたプログラムのもう1つの重要な側面は、テストの数やテストカバレッジレポートの数ではなく、コードの明瞭さです。これは、このコードが他の誰かに読めるという単純な質問ですか?それとも、今日のコードの筆者である私は、このコードを数週間後に理解できるでしょうか?

「コンピューターサイエンスには、キャッシュの無効化と名前付けという2つの難しいことしかありません。」
—フィル・カールトン

コードの読みやすさは、あなたが思っている以上に重要です。残念ながら、コードを明確にするための適切なメトリックはありません。優れたソフトウェアパターンと実践を覚えることは役立つかもしれませんが、多くの場合十分ではありません。優れたソフトウェアエンジニアは、経験と直感でコードを明確にする目を養います。ここで書くメタファーは完璧です。単語の大きなリストを知っているだけでは、簡潔で明確なコンテンツを書くのに役立ちません。

「短い手紙を書く時間がなかったので、代わりに長い手紙を書きました。」
- マーク・トウェイン

プログラムでは問題が発生します。簡単に修正できることは、優れたソフトウェアの重要な属性です。プログラムで発生するエラーには明確なメッセージがあり、監視対象のどこかに集中的に記録される必要があります。新しいエラーが報告された場合、それを修正する必要がある人はそのエラーをデバッグできるはずです。システムにフックして、いつでも実行コンテキストに関する情報を読み取ることができる必要があります。システムのあらゆる部分に関する期待を簡単に検証できる必要があります。

環境とテスト

ソフトウェアエンジニアは、プログラムを作成するときに、プログラムが多くの異なる環境、異なるリソースのマシン、異なるタイムゾーンで動作することを確認します。ソフトウェアは、さまざまな画面サイズと向きで動作する必要があります。また、限られたメモリまたは処理能力の使用を強制されることに対処する必要があります。

たとえば、Webブラウザー用のソフトウェアを作成する場合、さまざまな主要なブラウザーすべてで動作する必要があります。デスクトップソフトウェアを作成する場合、ほとんどの場合、MacおよびWindowsユーザー向けに動作する必要があります。データに依存するアプリケーションを作成する場合、そのデータを取得するための接続が遅いか、しばらくの間完全にオフになっている場合にソフトウェアが機能する必要があります。

ソフトウェアを作成するために、ソフトウェアエンジニアは、考えられるあらゆるシナリオを考え、これらのシナリオをテストすることを計画しています。これは、予期しないことが起こらないハッピーパスと呼ばれるものから始まりますが、さらに重要なことは、起こりそうなすべての問題を文書化し、そのためのテストを計画することです。一部のソフトウェアエンジニアは、これらのシナリオをシミュレートするテストケースと呼ばれるコードを記述することから始めます。次に、これらすべてのテストケースに合格する目的のコードを記述します。

ソフトウェアエンジニアは、通常曖昧で不完全なソフトウェア要件を理解しています。才能のあるソフトウェアエンジニアのユニークなスキルは、ソリューションの作成方法ではなく、ソリューションの内容を特定することです。

コストと効率

ほとんどの場合、ソフトウェアエンジニアは問題を迅速に解決できます。経験豊富なプログラマーを雇うとコストが高くなると思う場合は、もう一度考えてください。プログラマーが経験を積むほど、堅牢で、正確で、信頼性が高く、保守可能なソリューションを迅速に提供できます。これは、長期的に全体的にコストを削減することを意味します。

プログラムの実行コストも考慮する必要があります。すべてのプログラムはコンピューターリソースを使用し、それらは無料ではありません。ソフトウェアエンジニアは、コンピューターリソースを不必要に使用しない効率的なプログラムを作成します。たとえば、頻繁に使用されるデータのキャッシュはここで適用される戦略の1つですが、プログラムをより高速かつ効率的にすることができる数千のツールやバリエーションの1つにすぎません。

初心者のプログラマーは安価なソリューションを提供するかもしれませんが、そのソリューションを実行すると、経験豊富なプログラマーが最初に効率的なソリューションを作成していた場合よりも、あなたとクライアントに多大なコストがかかる可能性があります。

使いやすさ

優れたプログラムは、ユーザーエクスペリエンス(UX)を念頭に置いて設計されています。人間とコンピューターの相互作用は、無数の調査研究と調査結果を伴う大きなトピックです。これらの発見がより多く受け入れられるほど、ソフトウェアはより良くなります。

この大きなドメインの味をつかむために、ここでいくつか例を挙げてみましょう。

  • ユーザーが電子メールアドレスなどのデータを入力することが予想される入力フォームを設計する場合、適切な受信者プログラムは、電子メールアドレスに使用される大文字小文字を無視します。また、その周囲の余分なスペースもトリミングされます。 CAPSLOCKキーがオンになっているため、ユーザーに苦労を与えないでください。電子メールは小文字形式で一意です。プログラムが新しい電子メールアドレスを受け入れている場合は、それを早期に検証して、ユーザーに間違ったアドレスを使用した可能性が高いという明確なメッセージを伝えます。これには、@記号がないなどの明らかな検証の問題が含まれますが、スペルミスの「gmail.ocm」を使用するなどのそれほど明白ではない検証の問題も含める必要があります。
  • ユーザーを何かにリダイレクトする場合、優れたプログラムは元の場所を記憶し、完了したらその場所にリダイレクトします。また、優れたプログラムは、ユーザーに求められる将来の手順に関連付ける必要がある定義済みのデータと対話を記憶します。たとえば、Expediaでゲストとしてフライトを検索しているとします。次に、アカウントを作成することにしました。以前の検索はすべて新しいアカウントに保存され、まったく異なるマシンからアクセスできます。
  • 優れたプログラムは、ユーザーシナリオを考慮して設計されています。ユーザーの立場になってください。機能を追加するだけではありません!先日、マイレージ番号を忘れてユナイテッドのフライトを予約しました。確認を得た後、私はユナイテッドのウェブサイトに行ってFF#をフライトに追加しました。それを理解するのに10分かかりました。明確なパスがなかったため、その機能につながる可能性のあるすべてのリンクを調査する必要がありました。この機能が利用可能なページにアクセスしましたが、大きな形で深く埋まっているため、初めて見ることができませんでした。旅行者情報を編集し、そのフォームで約20の入力要素をスクロールし、使用するFF#のタイプを選択し、必要な電話番号を入力してフォーム全体を送信する必要があることが判明しました。これは、ユーザーの観点から考えて設計されていないプログラムの例です。

信頼性、セキュリティ、安全性

これらはおそらく、ソフトウェアの専門家をアマチュアと区別する最も重要なポイントです。彼らは、安全で安全なソリューションを作成する責任があることを知っています。

ソフトウェアの一部は、悪い入力、悪い状態、悪い相互作用に対して回復力がなければなりません。これを達成するのは非常に難しく、ソフトウェアのミスが原因で死ぬ人々の話を聞く主な理由です。

ユーザーは、悪いまたは間違った入力でソフトウェアを使用します。ソフトウェアを破壊し、そのソフトウェアが表すリソースにハッキングしようと意図的に行う人もいます。最近のEquifaxの大失敗の責任者とされる人物は、公にさらされているすべてのソフトウェアの悪い入力や悪意のある入力に対する回復力を設計するという仕事をしていないと非難されました。

セキュリティストーリーは、悪意のある悪意のある入力だけでなく、通常の入力についても説明します。ユーザーがパスワードを忘れた場合、何回まで試せますか?後でロックアウトしますか?他の誰かがそれらをロックアウトしようとしている場合はどうなりますか?ユーザーが暗号化されていない接続でパスワードを送信できるようにしますか?アカウントへのログイン試行が異常な場所から来た場合はどうなりますか?ログインが自動化されたと思われる場合はどうしますか?

クロスサイトスクリプティングとリクエストフォージェリ、中間者攻撃、単純なソーシャルフィッシングからユーザーを保護するために何をしますか?サーバーでDDoS攻撃を受けた場合のバックアップ戦略はありますか?これらの質問は、計画すべき多くの懸念事項のほんの一部にすぎません。

安全なプログラムは、機密情報をクリアテキストとしてではなく、非常に壊れにくいアルゴリズムを使用した一方向の暗号化されたデータとして保存します。これは、プログラムとデータが危険にさらされた場合のバックアップ戦略です。ハッカーは、ほとんど役に立たない暗号化されたデータを見つけるでしょう。

ソフトウェアは悪い状態になり、修正する必要があります。予期しない問題は、最善のプログラムで発生します。あなたがそのことに気づいておらず、それを計画していないなら、あなたはソフトウェアの専門家ではなく、あなたはただ安全でないプログラムの作者です。

ソフトウェアの欠陥は目に見えません。既知の欠陥を予測および防止する知的能力は限られています。これが、ソフトウェアエンジニアが正しい安全なソフトウェアを作成するのに役立つ優れたツールの価値を理解する理由です。

抱擁ツール

より多くのより良いツールが必要であることは間違いありません。ツールは大きな違いを生み、それらはしばしば過小評価されています。

展開するためにファイルをFTPで送信する必要がある場合を想像してください! Chrome DevToolsなしでネットワークとパフォーマンスの問題をデバッグすることを想像してください! ESLintとPrettierを使用せずにJavaScriptを記述するのが今日ではどれほど非効率的か想像してみてください

JavaScript開発者であり、何らかの理由でコードエディター用のプラグインを1つだけ選択する必要がある場合は、ESLintを選択する必要があります。

コードの作成中にフィードバックループを短縮するツールは、歓迎すべき追加機能です。私たちが作成したものを即座に視覚的に表現することについてのBret Victorの議論は、私にとって目を見張るものでした。ツールを採用し、改善することは、その明るい未来に私たちを導く1つの方法です。今までに見たことがないなら、今すぐBretの話を見てください。

すばらしい新しいツールを見つけたとき、後悔しているのはそのツールを以前に使用していなかったことです。優れたツールは、優れたプログラマーになるのに役立ちます。それらを見つけ、使用し、感謝し、可能であれば改善してください。

言語の選択は重要です。型安全性が重要です。 JavaScriptに起こった最高のことは、TypeScript(およびFlow)です。コードの静的分析は、あなたが考えるよりも大きな問題です。あなたがそれをしていないなら、あなたは基本的に自分自身を将来の未知のものに対して脆弱にしていることになります。静的型付けシステムなしでコーディングしないでください。選択した言語に静的型付けがない場合は、言語を変更するか、その言語のトランスパイラーを見つけてください。今日のトランスパイラーは、コード内のコメントを読むだけで十分に機能します。これは、ネイティブでサポートしていない言語の型チェックの未来だと思います。

ソフトウェア工学の進化

2か月、6か月、1年でソフトウェアエンジニアリングを学ぶことはできません。ブートキャンプでソフトウェアエンジニアになることを学びません。私は過去20年以上学習してきましたが、現在も学習しています。約10年の学習を経て、数千人のユーザーが使用するアプリケーションを設計、構築、および保守した後、私は自分を経験豊富なプログラマーと呼ぶに十分な自信になりました。

ソフトウェアエンジニアリングは万人向けではありませんが、誰もがコンピューターに関する問題を解決することを学ぶ必要があります。簡単なプログラムを書くことを学べるなら、すべきです。一般的なソフトウェアサービスの使用方法を学習できる場合は、そうする必要があります。オープンソースソフトウェアの使用方法を学ぶことができれば、多くの力が得られます。

問題が発生するため、ソフトウェアエンジニアリングも進化する必要があります。この職業の将来は、通常のコンピューターユーザーがコンピューターを使用できるようにすることであり、そのために5年間勉強する必要はありません。ユーザーが使いやすいツールを使用して、簡単な問題を自分で解決できるようにします。その後、ソフトウェアエンジニアは、より優れたツールを作成し、より大きな既知の問題を解決し、未知の問題を防ぐために最善を尽くします。

読んでくれてありがとう。