技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

インターフェースの抽出【リファクタリング】

状況 複数のクライアントが、あるクラスの一部の機能を使っている 対処 共通部分をインターフェースとして抽出する メリット 各クライアント(関数など)がどの機能を必要としているのかが明確になる 別の機能を持たせた異なる種類のクライアントを作成する…

formからfileを読み込む【Go】

Go

http.Requestのポインタをレシーバに持つFormFile()を使います。 次のような階層があるとして、 main.go templates index.gohtml filestore (作成したファイルを格納) formのinputからファイルを読み込み、 filestoreフォルダに新たなファイルを作成、 読み…

.gitkeepで空ファイル

git

空のディレクトリを作成して、その変更をgitに認識させるために 空ファイルを作成したい時には.gitkeepを作成します。 名称が「.」で始まるファイルはGUIからは作成できないので、 コマンドラインツールを使います。 ※Visual Stadio Codeからは作成可能です…

http.NotFoundHandler()【Go】

Go

強制的に404 Not Found Errorを返します。 例えばfavicon.icoを配置していないと、ブラウザによってはアクセスする度にエラーログが吐かれてしまいますが、 http.NotFoundHandler()を使って、"/favicon.ico"に対してHandleを指定すると、 エラーログを出力し…

favicon.icoは配置するか、エラーログを出力しないようにする

favicon.icoは、ブラウザのタブやお気に入り登録時に表示される画像ファイルです。 ブラウザのブランド力を高める目的として、1999年にMicrosoftのIE5から発表されました。 その後はWeb標準として扱われ、HTML5でも標準規格とされています。 HTMLのheadの中…

http.Error()【Go】

Go

ResponseWriterにエラーの内容を書き込むことができ、 クライアント側にエラーを認知させることができます。 func pict(w http.ResponseWriter, req *http.Request) { f, err := os.Open("pict.png") if err != nil { http.Error(w, "file not found", 404) …

http.StripPrefix()でフォルダ階層とURLの指定を分離する【Go】

Go

http.Handle()とhttp.FileServer()を用いた、サーブ方法には問題となる点がありました。 http.FileServer()で階層ごと複数ファイルをサーブする【Go】 - 技術向上 http.Handle("/abc/", http.FileServer(http.Dir("templates"))) 上記の場合、/abc/にアクセ…

http.FileServer()で階層ごと複数ファイルをサーブする【Go】

Go

http.FileServer()関数を使って、階層ごと複数ファイルをサーブすることができます。 返り値の型はHandlerです。 よって、指定されたURLにアクセスされた際にHandlerを実行する、 http.Handle()関数の第2引数に指定することができます。 func http.FileServe…

http.ServeContent()【Go】

Go

ファイルをサーバーにあげる際に利用します。 io.Copyと比較して、各種ヘッダー情報を付加、利用できる点で利があります。 それはContet-Range、MIMEタイプ、ETagを利用したIf-MatchとIf-None-Match、 If-Range、 さらにIf-Unmodified-Sinceなどで、正確に、…

io.Copy【Go】

Go

Reader経由でファイルをコピーして、Writerを通して出力します。 func pict(w http.ResponseWriter, req *http.Request) { // HandlerFunc()の第2引数に指定するため、この形式 f, err := os.Open("pict.png") // ファイルを開き、Readerが使える状態にして…

速くて簡単。サードパーティのServeMux【Go】

Go

packageの紹介 こちらのhttprouter packageは、net/http packageのServeMuxよりもルーティングが高速で、かつ使いやすいと評判です。 GitHub - julienschmidt/httprouter: A high performance HTTP request router that scales well パフォーマンスについて…

http.Request queryパラメータからkeyで値を取得する【Go】

Go

http.RequestのFormValue()メソッドを使用すると、 queryパラメータから、keyを指定した値の取得ができます。 http packageのHandler型へのダックタイピングを、hotdogという型に対して行う例で解説します。 Handler型はinterface型であり、ServeHTTP()メソ…

http.Requestからformの値を取得する【Go】

Go

http.Requestからformの値を取得するには、 http.Requestのメソッド、ParseForm()事前に実行する必要があります。 その上で、formの値が格納されているhttp.Requestのフィールド(url.Values型)にアクセスします。 formの値が格納されるフィールドには、For…

フィールドの引き下げ【リファクタリング】

状況 フィールドがいくつかのサブクラスだけで使われている 対処 対象のフィールドを、サブクラスに移動する メリット クラスの責務が明確になる 手順 対象のフィールドをスーパークラスの全てのサブクラスで宣言する スーパークラスからそのフィールドを削…

メソッドの引き下げ【リファクタリング】

状況 スーパークラスの振る舞いが、いくつかのサブクラスだけに関係している 対処 対象のメソッドをサブクラスに移動する メリット クラスの責務が明確になる 手順 スーパークラスの全てのサブクラスで当該のメソッドを宣言し、そこにメソッドをコピーする …

サブクラスの抽出【リファクタリング】

状況 あるクラスの特定のインスタンスだけに必要な特性がある 対処 その一部の特性を持つサブクラスを作成する メリット クラス内の記述量が減り、可読性が上がる 「クラスの抽出」と比較して容易ではありますが、制約があります。 オブジェクトが生成された…

クラスの抽出【リファクタリング】

状況 クラスの責務が明確であるとは言い難く、複数のクラスに分けてなされるべき作業を一つのクラスで行なっている 例えば、Personというクラスに電話番号に関するフィールドやメソッドが存在する場合です。 対処 クラスを新たに作成し、適切なフィールドと…

TCP Dial【Go】

Go

クライアントサイドの処理を行うプログラムを作成します。 netパッケージのDialメソッドを使用します。 サーバーの役割を担うproject、main.goファイル、 サーバーに対してアクセスする、クライアントの役割を担う別のproject、main.goファイルを用意します…

TCP SetDeadline【Go】

Go

net.ConnのSetDeadline()メソッドを使うと、 接続の有効期限を指定することができます。 func main() { li, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } for { conn, err := li.Accept() if err != nil { log.Fatal(err) } go hand…

TCP scanner【Go】

Go

bufio packageのScannerを使って1行ずつ読み込むことができます。 TCP接続した情報を読み込む例を示します。 main.goです。 func main() { li, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } for { conn, err := li.Accept() if err …

TCP write【Go】

Go

HTTPで動作するサーバーを作成するため、 TCPサーバーを、標準パッケージのnet packageを使って作成します。 TCPはサーバーとクライアント間の接続を事前に確立し、 通信相手ごとに通信の状態を管理します。 それゆえに信頼性は高いですが、コストのかかる通…

case: 長すぎるメソッド【リファクタリング】

処理記述が長いメソッドは、可読性を下げ、適切に部品が共通化されていないことから、 プログラム全体でコードの重複も生まれやすくなります。 「メソッドの抽出」は一番単純で効果のあるアプローチです。 パラメータや一時変数もメソッドを長くする原因です…

ガード節による入れ子条件記述の置き換え【リファクタリング】

状況 メソッド内に、正常ルートが不明確な入れ子の条件付き振る舞いがある double getPayAmount() { double result; if (_isDead) result = deadAmount(); else { if (_isSeparated) result = separatedAmount(); else { if (_isRetired) result = retireAmo…

条件記述の分解【リファクタリング】

状況 if-then-elseによる複雑な条件記述がある 対処 条件記述部とthen部およびelse部から、メソッドを抽出する メリット コードが読みやすくなり、分岐の理由がわかりやすくなる 短い条件記述部は、一見して特にメソッド化する必要がないと思われるかもしれ…

メソッドオブジェクトによるメソッドの置き換え【リファクタリング】

状況 長いメソッドであり、「メソッドの抽出」を適用できないようなローカル変数の使い方がされている 対処 メソッド自身をオブジェクトとし、元のメソッドで定義されていたローカル変数を、そのオブジェクトのフィールドとする メリット 「メソッドの抽出」…

オブジェクトそのものの受け渡し【リファクタリング】

状況 あるオブジェクトから複数の値を取得し、それらの値をメソッド呼び出しのパラメータとして使用している 対処 メソッドのパラメータにはオブジェクトそのものを渡すよう変更する 結果として、ほとんどのパラメータがあるオブジェクトに依存する場合には…

html/templateとtext/template【Go】

Go

html/templateは、text/templateの拡張版です。 text/templateの全ての機能を、html/templateは備えています。 それに加えて、htmlに必要な機能を併せ持っています。 例えば文字エスケープです。XSS対策になります。 main.goです。 text/templateをimportし…

templateに渡したdataに対してメソッドを使用する【Go】

Go

templateファイルの中で、goファイル上で記述したメソッドを使用することができます。 メソッドを定義していないtypeに対して使おうとすると、エラーが発生します。 引数あり main.goです。 var tpl *template.Template type Team struct { Name string Est …

templateに渡すdataの構造化【Go】

Go

goファイルからtemplateへ渡すdataを、structを使って構造化します。 main.goです。 NPBの中にLeagueのポインタ型が2つ、Leagueの中にTeamのポインタ型のスライスがあります。 var tpl *template.Template type Team struct { Name string Est int } type Le…

templateの分離と組み立て【Go】

Go

templateを複数に分割して識別し、組み立てる時に識別名によって呼び出すことができます。 階層は次の通りになっているとします。 main.go templates tpl.gohtml parts.gohtml まずはmain.goです。 var tpl *template.Template func init() { tpl = template…