Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kadai2 simady #16

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Kadai2 simady #16

wants to merge 4 commits into from

Conversation

simady
Copy link

@simady simady commented Jul 29, 2019

1回目の宿題のテストを作ってみて下さい

$ go test -cover imgconv/...
ok      imgconv 0.434s  coverage: 88.2% of statements
ok      imgconv/converter       0.430s  coverage: 100.0% of statements

テーブル駆動テストを導入しました。
テストヘルパーの作成はまだできていません。

io.Readerとio.Writerについて調べてみよう

type Reader interface {
        Read(p []byte) (n int, err error)
}

byte型のスライスを引数に取り、pに値を読み込む。
読み込んだバイト数とエラーを返す。

type Writer interface {
        Write(p []byte) (n int, err error)
}

byte型のスライスを引数に取り、pから値を書き込む。
書き込んだバイト数とエラーを返す。

  • 標準パッケージでどのように使われているか
    • tarやzip等のアーカイブ形式
    • bzip2やlzw等の圧縮形式
    • ECDSAやtls等の暗号化形式
    • base64や16進数等のフォーマット
    • gifやpng等の画像形式
    • 標準入出力や標準エラー出力
    • http通信でのリクレス等
    • MIMEマルチパートやQuoted-printable等の方式
    • ファイル
    • 文字列やバイトバッファ
    • ログ

上記のように様々な箇所での読み書きに使用されていた。
また、以下のようなerrorの戻り値を利用するような使い方も見られた。

type errorReader struct {
	error
}
func (r errorReader) Read(p []byte) (n int, err error) {
	return 0, r.error
}
type eofReader struct{}
func (eofReader) Read([]byte) (int, error) {
	return 0, EOF
}
  • io.Readerとio.Writerがあることでどういう利点があるのか具体例を挙げて考えてみる
    • io.Readerやio.Writerを実装したインスタンスをインターフェースを介して利用することで、使用する側は実体が何かを意識せずに扱うことができる。
    • シンプルなインターフェースなので実装が容易。何に対して読み書きを行うかは定義されていないので、入出力先に応じて適宜実装すれば良い。
    • テストやデバッグ時に、実際の処理とは別の処理に置き換えるといった差し替えが容易に行える。
    • ioパッケージのpipeやio/ioutilパッケージで定義された既存の便利メソッドを利用できる。

@simady simady added the kadai2 label Jul 29, 2019
)

// IConverter コンバーターインターフェース
type IConverter interface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Goでは先頭にIとつける習慣はない。


// IConverter コンバーターインターフェース
type IConverter interface {
convert(file *os.File, img image.Image) error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

型名がexportされているのにメソッド名がexportされていない理由は?

)

// Validate フィールドのバリデーション処理を行う.
func (c converter) validate() bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

構造体の場合、特に理由がない場合はレシーバにはポインタを使う。
https://qiita.com/knsh14/items/8b73b31822c109d4c497#receiver-type

return validate(c.src) && validate(c.dst)
}

func validate(ext string) bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なぜメソッドでやらずに関数で行う?

}

func validate(ext string) bool {
for _, e := range convertibleExts {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapを使えば関数不要そう。
https://play.golang.org/p/11bEbuN1BLW


src, err := os.Open(path)
if err != nil {
log.Fatalf("Faild to open file. err = %v\n", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log.Fatalは中でos.Exitを呼び出すので基本的にmain関数以外では使わない。
errorを返す。
main関数であってもox.Exitに渡す終了コードを指定することができないため、基本的には使わない。

if err != nil {
log.Fatalf("Faild to create file. err = %v\n", err)
}
defer dst.Close()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

書き込み用のファイルは閉じる際にエラー処理をする。

switch dst {
case "png":
return pngConverter{c}
case "jpeg":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jpgも扱えるようにしたほうが良さそう。

}

// GetConverter 拡張子に対応したコンバーターを取得する.
func GetConverter(src, dst string) IConverter {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GoではGetという単語はあんまり使わない。

"testing"
)

func TestGetConverter(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

テーブル駆動テストをする

func TestGetConverter(t *testing.T) {
var c IConverter
c = GetConverter("jpeg", "png")
if _, ok := c.(pngConverter); !ok {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

せっかくインタフェースにしているのに、テストが具体的な実装に依存しているのはあまりよくない。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants