Job-初心者と経験豊富なGoプログラマーのためのデザインパターン

かなり長い期間PHPでプログラミングした後、Goでプログラミングを開始しました。最新のトレンドから判断すると、私のケースは孤立したものとはほど遠いものだと思います。一般的に、GoはWeb開発者の間で人気を集めています。





だから、私はゴーファーの世界にいます。そして、コアに焼き付けられたPHPプログラマーは、そこで一度何をしますか?そうです、彼はプロの変形のために「パフ」を続けていますが、すでにGoに参加しており、その後のすべての結果をもたらします。





, Go , , SOLID, Dependency Injection . , ( ), , - PHP, ++ Java.





, , . context.Context, ? , PHP . - ! , , PHP , , Go. . , . , proof of concept. Go, .





, , , , : ", , . , ". — . Reddit Go , … . "? ? over-engineering" - . : " . , README.md - ".





プログラマーがソリューションをどのように見るか

, , , .





? - . :





  1. Job - , (task).





  2. -, L4; , backend ; backend , . Job. Github.





Job - Command pattern, . :





Parallel Processing Where the commands are written as tasks to a shared resource and executed by many threads in parallel (possibly on remote machines; this variant is often referred to as the Master/Worker pattern)





, - — . , , context.Context, , . task.Assert



if err != nil { panic(err) }.







ping/pong . , — Github .





// Saves resized image to the output dir
func (s *ImageResizer) SaveResizedImageTask(j job.Job) (job.Init, job.Run, job.Finalize) {
	// Do some initialization here
	init := func(t job.Task) {
		if _, err := os.Stat(s.inputDir); os.IsNotExist(err) {
			t.Assert(err)
		}
		if _, err := os.Stat(s.outputDir); os.IsNotExist(err) {
			err := os.Mkdir(s.outputDir, 755)
			t.Assert(err)
		}
	}
	run := func(task job.Task) {
		stream := j.GetValue().(netmanager.Stream)
		select {
		case finishedTask := <- j.TaskDoneNotify(): // Wait for the scanner task to be done
			if finishedTask.GetIndex() == s.scanneridx {
				s.scandone = true
			}
			task.Tick()
		case frame := <-stream.RecvDataFrame(): // Process response from the backend server
			task.AssertNotNil(frame)
			res := &imgresize.Response{}
			err := frame.Decode(res)
			task.Assert(err)

			baseName := fmt.Sprintf("%s-%dx%d%s",
				res.OriginalName, res.ResizedWidth, res.ResizedHeight, res.Typ.ToFileExt())
			filename := s.outputDir + string(os.PathSeparator) + baseName
			if ! s.dryRun {
				ioutil.WriteFile(filename, res.ImgData, 0775)
			}

			j.Log(1) <- fmt.Sprintf("file %s has been saved", filename)
			stream.RecvDataFrameSync() // Tell netmanager.ReadTask that we are done processing the frame
			s.recvx++
			task.Tick()
		default:
			switch {
			case s.scandone && s.recvx == s.sentx: // Check if all found images were processed
				task.FinishJob()
			default:
				task.Idle() // Do nothing
			}
		}
	}
	return init, run, nil
}
      
      







これはクライアントのタスクの1つであり、サーバーからの着信応答を処理し、結果のイメージを保存します。タスクは、ファイルスキャンを実行するタスクを使用して、前述のping / pong同期手法を使用して実行を調整します。また、サーバーからの最後の応答がいつ来たか、すべての作業(ジョブ)の実行をいつ完了するかを決定します。





このソリューションがどの程度過剰に設計されており、コンテキストの代わりにどの程度使用されているか。コンテキストは正当化されます。読者に判断してもらい、上の画像に皮肉の形で意見を述べました。





みなさん、素晴らしい週末をお過ごしください。ゴーファーの世界で、pehapeの力が私たちと共にありますように。








All Articles