技術向上

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

2018-12-01から1ヶ月間の記事一覧

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

状況 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…

templateにコメントを書く【Go】

Go

下記のように、「{{ }}」で囲まれたコメント専用スペースを作り、 「/ /」の中にコメントを書きます。 {{ /* This is a Name list. */ }} <ul> {{ range . }} <li>{{ .Name }}</li> {{ end }} </ul>

パラメータの追加【リファクタリング】

状況 あるメソッドが、呼び出し元からより多くの情報を必要としている 対処 引数を追加する メリット 新たな情報を受け取ることができる ただし、無闇にパラメータを追加することはコードの可読性、保守性を悪くします。 本当に追加する必要があるのか、新た…

パラメータオブジェクトの導入【リファクタリング】

状況 本来まとめて扱うべきひとまとまりのパラメータがある。 例えば、いくつかのメソッドに対して「開始日」と「終了日」をセットで渡している場合です。 対処 まとめられるパラメータをオブジェクトに置き換える 例えば、「開始日」と「終了日」は「日付の…

templateと組み込み関数【Go】

Go

templateでは、組み込み関数(ビルドイン関数)を、自作のgoファイルに定義せずに使用することができます。 templateファイルに直接記入することができるのです。 main.goが次のようになっているとします。 type user struct { Name string Admin bool } fun…

case: コードの重複【リファクタリング】

同一クラス内の複数メソッドでの重複 「メソッドの抽出」を適用し、各メソッドの内部で抽出したメソッドを呼ぶようにします。 メソッドの抽出【リファクタリング】 - 技術向上 兄弟クラス間の複数メソッドでの重複 両方のクラスで「メソッドの抽出」を行い、…

Template Methodの形成【リファクタリング】

状況 異なるサブクラスの二つのメソッドが、類似の処理を同じ順序で実行しているが、各処理の内容は異なっている 例えば、処理順序や算出対象は同じでも、掛け合わせるレートが異なるなどです。 対処 同じメソッドをオーバーライドできるよう、各処理を同じ…

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

状況 同じ結果をもたらすメソッドが複数のサブクラスに存在する。 対処 メソッドをスーパークラスに移動する メリット メソッドの修正もれリスクを下げる事ができる 手順 対象とする複数メソッドの内容が同じである事を確認する メソッド間でシグニチャ(引…

template.FuncMap【Go】

Go

template.FuncMapとFuncs()を用いることで、 templateに対して関数を登録する事ができます。 階層が次のようになっているとします。 main.go templates blabla.gohtml tpl1.gohtml tpl2.gohtml main.goの内容です。 var tpl *template.Template var fm = tem…

templateへのデータ渡し【Go】

Go

templateへのデータ渡しを、goファイル上で指定する事ができます。 intやstring 階層が次のようになっているとします。 main.go templates blabla.gohtml tpl1.gohtml tpl2.gohtml main.goの内容です。 var tpl *template.Template func init() { tpl = temp…

template.ParseGlob()【Go】

Go

"Glob"は「掴む」を意味する通り、 引数に指定した「パターンに合致する」複数のファイルを templateとして取り込む事ができます。 階層が次のようになっているとします。 main.go templates blabla.gohtml tpl1.gohtml tpl2.gohtml main関数が次のように書…

template.ParseFiles()【Go】

Go

templateとして外部ファイルを取り込むメソッドです。 tpl, err := template.ParseFiles("tpl.gohtml") // tpl.gohtmlというファイルを取り込む if err != nil { log.Fatal(err) } err = tpl.Execute(os.Stdout, nil) // 画面出力する。適用するdataはないの…

ターミナルからtemplateに出力する内容を指定する【Go】

Go

index.htmlを作成し、ターミナルでの実行時に、 出力される変数に代入する内容を指定します。 name := os.Args[1] // ターミナルで実行した時の第2引数を代入 fmt.Println(os.Args[0]) // 実行対象のファイル(第1引数) fmt.Println(os.Args[1]) // 実行時…

Singleton【Go】

Go

オブジェクト指向のデザインパターンである、Singletonを実装する例です。 type Menu struct { name string price int } var mymenu *Menu = newMenu("未定", 0) // 定義時に func newMenu(name string, price int) *Menu { // コンストラクタのように初期化…

htmlに出力する際のループ処理【Go】

Go

SQL(sqlite3)によってDBから取得した内容をhtmlに出力します。 テーブルから取得できる件数は、事前にはわからないため、 テンプレートとして使用するhtml側でループ処理を施す必要があります。 まずはgoファイルのSQL取得処理です。 type Candle struct {…

rangeの無限ループとgoroutine【Go】

Go

for rangeの対象が、無限ループによって生成(更新)される場合、 for rangeの処理も終わらないため、下に記述された処理が行われません。 c := make(chan int) go func() { defer close(c) var i int for { // 無限ループ c <- i time.Sleep(1 * time.Secon…

APIを扱うメソッド・関数の返り値【Go】

Go

APIを扱うメソッド・関数の返り値について、 structの場合はポインタ渡し、 スライスの場合は値渡しとすることが一般的です。 スライスは配列に対するエイリアスですので、ポインタとする必要性がなく、 structの場合は、コピーが作成されてしまうので ポイ…

時間の切り捨て【Go】

Go

Time.Truncate(d duration)を使って、表示時間の切り捨てを行います。 fmt.Println(time.Now().Truncate(time.Minute)) // 2018-12-14 11:34:00 +0900 JST durationに指定した期間より後の内容は切り捨てられます。

JSONからstructに変換するツール【Go】

Go

便利なサイトです。 JSONのエンコーディングも付記されます。 JSON-to-Go: Convert JSON to Go instantly

ポリモーフィズムによる条件記述の置き換え【リファクタリング】

状況 オブジェクトのタイプによって異なる振る舞いを選択する条件記述がある タイプコードに対して必要な継承構造が用意されていることが前提。つまり「サブクラスによるタイプコードの置き換え」もしくは「Stateによるタイプコードの置き換え」が適用されて…

Stateによるタイプコードの置き換え【リファクタリング】

状況 クラスの振る舞いに影響するタイプコードがあるが、サブクラス化はできない if文やcase文を削減する「ポリモーフィズムによる条件記述の置き換え」を適用するための土台づくりに使われます。 土台づくりには他に「サブクラスによるタイプコードの置き換…

自己カプセル化フィールド【リファクタリング】

状況 フィールドに直接アクセスしている _a = _a * 2 対処 そのフィールドに対するgetおよびsetメソッドを定義し、それらのメソッドを使用する メリット サブクラスがその情報の取り出しに際し、メソッドによってオーバーライドできる 遅延初期化を試みるこ…

os.Exit【Go】

Go

プログラムを強制終了させます。 os.Exitが実行されると、defer指定された関数も実行されません。 引数にはstatus codeを指定しますが、0を指定すると正常終了を意味し、1を指定すると異常終了を意味します。 func() { defer someFunc() // 実行されない os.…

httpのhandlerに引数を指定する方法【Go】

Go

htmlのtemplate【Go】 - 技術向上などで紹介した方法ですと、 各handlerで共通した、titleを取得する処理が行われています。 引数にtitleを渡すことで効率化できそうです。 ... func viewHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.…