20201121のJavaに関する記事は6件です。

Java SE の基礎を IT 講師ががんばって親切に解説する連載の目次

皆さんはじめまして。ひろきです。ふだんは SIer 向けの新人研修講師をしたり、教材開発をしたり、ときどき開発をしたり講師育成をしたりしています。

このたび Qiita で、Java SE 基礎の解説を連載形式で掲載します。ぜひご活用ください!!!

ひとことで

最短路を、一歩ずつ進む ことを目標に作った、 Java SE 基礎の無料オンライン教材です。

想定している利用者&利用シーン

この連載は、学習の副教材として使われることを念頭に作っています。具体的な連載の対象者&利用シーンは、以下の2者です。

対象者 利用シーン
Java初学者 〇〇で Java を学び始めたもののなかなかしっくりこなくて悩んでいる
担当者(講師・メンター) 質問対応等で紹介できる、解説の厚いサイトを探している

※ 著作権は放棄していませんので、ご注意願います。

ゴール・ゴールじゃないこと

この連載では 最短路を、一歩ずつ進む ことを念頭に学習を進めます。学習した結果、何を目指し、何は目指さないのかを明確にしておきます。

ゴール

この連載のゴールは、「ふだんの学習に自信を持って取り組めるようになること」です。週明けからまた元気に研修なりスクールなりで学習を始めよう、という前向きな気持ちになってもらうことです。

具体的には、以下2点の状況を目指します:

  • Java SE の基礎的な内容について一貫して腹落ちした状態になること
  • 「オブジェクト指向とは何か?」的な沼から抜け出した状態になること

ゴールでないこと

この連載では、あくまでも副教材であるとの立場から、以下2点をゴールとしません。

  • Java SE の範囲外の内容(Java EE、フレームワーク等)
  • Java SE の詳細な文法説明
  • Java SE の網羅的な API 解説

まず Java SE の範囲外については、学習者の環境によって求められる内容が変わるため連載対象外とします。
また、詳細な文法や網羅的な API の解説については、基礎の連載に含めると消化不良を招くため連載対象外とします。基礎さえ分かっていれば、細かな内容は後からいくらでも学習できますので。

この教材の良いところ・悪いところ

良いところ

この教材は、作成者が、研修現場で感じた課題意識をもとに、明確な目的と想いを持って作っています。具体的には、以下4点がウリです:

  • がんばって書いている
  • スモールステップ
  • ターゲットを絞り込んでいる
  • 動画化を前提に作っている

がんばり

がんばって書いています。

スモールステップ

スモールステップで学習していきます。学習していて「分からなくなったのかが分からない」と感じたことがあるんじゃないでしょうか。不明点を特定できないのは、一度にたくさんのことを理解しようとするからです。十分にステップが小さければ、「あ、ココから分からない!」が明確になります。「ココ!」と言えることで質問がスムーズに行えるでしょう。

ターゲッティング

ターゲットを Java を学び始めたもののなかなかしっくりこなくて悩んでいる初学者 に絞り込んでいるので、ターゲット層のひとに狭く深く刺さります。この連載は書籍やスクールのような万能性を最初から捨てています。説明はくどいし、学習対象も広くありません。でも、だからこそ副教材として自学用に利用したい諸学者にはとてもフィットする内容だと思います。

動画化

この連載は著者による動画解説を前提に作成しています。特に悩める初学者の場合、音や動きがあったほうが直感的に理解しやすかったり、感情的に受け入れやすかったりするでしょう。

悪いところ

この教材は、「補助教材」として使うことを想定しているため、「主教材」にはなりません。具体的には、以下3点ご容赦ください。

  • API の網羅性が低い
  • 実務寄りな話が無い
  • 構成が一般的な教材と異なる

ぜひ、主教材を脇に置いて進めてくださいね。

また、 初稿の完成度は低い です。これは ひとまず通しで完成させ、その途中でいただいた質問やフィードバックを反映させて徐々に完成度を上げる 方針を取っているためです。ご容赦くださいm(_ _)m

背景

なぜこの連載を始めようと思ったかについてです。本筋と関係のないところなので、興味のないかたは読み捨てください。

私は自分の仕事をずっと続けていたいと思っています。しかし、世の中の状況を考えるとこのままではジリ貧感があり、新しいことをやってみようと思ってこの連載を書き始めました。

いまの仕事が大好き

私はいまの仕事が大好きです。

私の20代は迷走の時代でした。新卒で入った公務員を半年で辞めたり、塾講師をしたり、フリーターをしたり、司法書士試験を受けたりしていました。一度は「おれの人生詰んだかも」という恐怖と戦うところまで追い詰められた人生でした。

そんななか色々あって、 2017 年 1 月から IT 教育業界に入りました。それからというもの、とても楽しく働いています。少しずつ担当範囲を増やし、現在 SIer 向け新人研修で教える内容についてはそれなりに広い担当領域を持てるようになりました。いろいろと運に恵まれて、教材を作ったり、講師を育成したり、研修を企画したり、仕事の幅も広がりました。

この仕事に就いて2年目あたりからずっと、「一生 IT 講師として働きたい。同じことを続けるために変化を続けたい」と思っています。 IT のことを調べまくって、調べた内容を伝えることは、本当に楽しい仕事です。貢献実感を得られるし、目の前の人と IT の話を通じて分かり合えるのも嬉しいです。この仕事をずっと続けていきたいと思います。

この仕事が無くなる予感

しかし今年(2020年)、例の病によってリモートワークが本格化し、講師業もまた消えるのではという危機感を持っています。「画面越しに喋るなら、人間いらないんじゃね?」というのは、多くの講師が現場で薄々感じ始めていることだと思います。数年内に、講義は動画講義になるでしょう。 QA (質問対応)もチャットボットになるでしょう。遠からず、私が楽しいと感じている「いまの IT 研修」は無くなる気がしています。

どうせ無くなるなら、いっそ新しいものの雛形を作ってしまいたい。そう思ってこの連載を作りました。

次の時代につなげたい

今年の研修を終えてみて、私は「いまのままではこの仕事の範囲が最大かもしれない」と感じ、その限界を超えたいという思いがあります。

私は「エンジニア→講師」とキャリアチェンジしてきたのではなく、むしろ「講師業」の範囲を IT まで広げて現在に至ります。開発はちょっとだけです。 IT 講師業界では実務経験が重視される傾向があり、今後講師業の幅を広げようとすると、正規ルートでは「一度開発経験を数年間積んで、講師に戻ってくる」になります。

理論的にはその通りなんですが、いまの仕事、楽しいんですよね……というわけで、なんとか既存の枠組みの IT 講師とは違うポジションを取りたいという思いもあってこの連載を書こうと思いました。

それからもう一つ、受託的な働きかたの限界を超えたいという想いもあります。何か新しいことをしようにも、いまのままでは結局、仕事をしている教育ベンダーの名を名乗るわけにもいかないし、所属会社の社員というわけでもない。だったらもう、自分にやれることをあるていど開示しておこうという想いもあります。それをきっかけに新しいことに繋がったら幸せです。

お願い

ご覧になったみなさま

ぜひ温かい励ましのお言葉をお待ちしています(切実)。

過去にも似たようなこと(Java ではなくネットワーク)をやろうとして始めたのですが、WordPress の閉じたところでやってしまったためコメントがつかず、モチベーションがあっという間に燃え尽きてしまいました。ポジティブなフィードバックこそモチベーションの源泉です。私と未来の初学者のために、ぜひお願いします。

学習者のかたへ

1件でもいいので質問をしてくれると嬉しいです。

私は結構、自分のなかにオレオレ理論を組み上げて、周りが見えなくなってしまう癖があります。質問をいただくことでハッと目覚めて道を正せますので、なんでもお気軽に聞いてください。

学習者以外のかたへ

教材の改善提案や、誤情報の指摘をいただけますと幸いです。

この連載は私が個人として(?)作っているので、レビュー体制がありません。また、予算・納期の関係上あまり調査をせず手なりに作っている部分があります。

なんでもお気軽に温かいご意見いただけますとたいへん励みになります(とはいえ、私も想いを持って作っているので、すべてのご意見を反映できるものではありません。ご容赦ください)。

今後の野望

動画化

一通り書き終えたら、なるはやで動画化していきたいと思います。記事だけでなく QA も動画化していきます!

難しい内容

これまで何社かの Java SE のテキストを作ってきて、正直飽きました……。次は SpringBoot + テスト自動化 + CI + Rest API + … みたいな、今風のテキストを作りたいです。

システム化

この記事は Qiita 上に掲載していますが、元データはちゃんととってあります。 コンテンツが揃ってきたら Qiita API なんかと組み合わせて、システム化したいです。チャットボットも作りたい!質問ください!!

オンラインサロン化

結局、教材と QA が無料化されるので、コミュニティが欲しいですね。私は講師のくせにコミュニケーションが苦手というか雑談が苦手なんですが、IT の話をしあえるクローズドな場があれば楽しいなと思います。ただ、金が絡むので面倒そう……ちょっと及び腰です。

リアル化

どうにかこうにかリアルな場に繋げられたらいいですね。これは目標というより夢です。

私の人生の究極の目標は、「田舎の廃校を買い取って寺子屋を開くこと」です。これは塾講師だったころから一貫してもっている夢のようなもので、本当に実現に向けて動いているわけではないのですが、言っておけば何か起きるかもしれないので言っておきます。

塾講師をしていたころは本当に生徒とのコミュニケーションが日々楽しく、どうすれば生徒がもっと喜ぶかばかりを考えていた4年間でした。それは IT 講師になってからの4年間も同じです。仕事を通じて何かを成したいわけではなく、仕事をすること自体が目的として仕事をしています。たとえいまの IT 研修が無くなるとしても、新しい IT 研修で楽しくやっていきたいです。

全記事目次

全記事目次を掲載します。

概要

intro.png

記事リスト

  1. JShell でプログラミングへの第一歩を始めよう!(JShell, REPL)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JShell でプログラミングへの第一歩を始めよう!(JShell, REPL)

(この記事は連載の一部です)

この項目では、何がなんだか分からなりに、ひとまず Java プログラムを実行 してみます。

これから私たちは Java プログラムを書いては動かし、書いては動かしして学んでいきます。
ゆくゆくは何千行何万行という巨大なプログラムを書くことになり、そのころには「プログラムとはこういうもの」というおおよそのイメージが付いているでしょう。

しかし学び始めたいまの時点では、「そもそもプログラムを動かすってなんやねん」という状態かと思います。そこでまずは、いくつか例を挙げながら「プログラムを動かすってなんやねん」に答えたいと思います。そして、もっとも簡単な方法として JShell でのプログラム実行をやってみます。

はじめに

  • 必要な前提知識
    • キーボード入力
    • ブラウザ操作
  • これを読んで分かること
    • プログラムとは何か?
    • コンピュータ・プログラムとは何か?
    • Java とは何か?
    • Java プログラムはどのように動くのか?
    • REPL とは何か?
    • JShell とは何か?

体験編?

まずは JShell で Java プログラミングへの第一歩を始めて見ましょう!

1. JShell にアクセス

https://tryjshell.org にアクセスして、適当な数値を入力してみましょう。

num_input.gif

2. 文字の入力

数値だけでなく文字も入力してみましょう。 Error は気にしなくて OK です。 'a'"abc" なども試します。

string_input.gif

3. JShell の終了

/exit と入力すると JShell が終了します。画面に Goodbye が表示されたら、ブラウザを閉じましょう。

exit.gif

理解編?

ハンズオンではひとまず JShell で Java プログラムを実行してみました。でも、JShell で Java プログラムを実行する とはどういうことでしょうか。その疑問に答えるために、いくつか用語を理解していきましょう。

1. プログラム/コンピュータ・プログラム/ Java プログラム

jshell.png

プログラム とは、一般的な用語で やることが順番に並べてあるもの です。コンピュータプログラム以外にも、例えば運動会のプログラムやコンサートのプログラムをイメージしてください。まずこれをして、次にあれをして……というのが書かれていますよね。

コンピュータ・プログラム とは、そこから一歩進んで コンピュータにさせることを順番に並べたもの です。そして Java プログラム とは Java言語 で書かれたコンピュータ・プログラム です。ここは、今後例がいくらでも出てきますから、「ふーん」という程度で OK です。

2. Java プログラムが動くまで

人間に何かを頼む場合、「やっといて」と言えばいい感じにやっておいてくれます。しかし、プログラミングの場合はそうはいきません。人間とコンピュータはなかなか分かり合えない存在なのです。では、人間とコンピュータが分かり合い、人間がやってほしいことをコンピュータにやってもらうためには、どんな手順が必要でしょうか。

2-1. ソースコード・実行コード・プロセス

jshell-1.png

私たち人間が書くプログラムを ソースコード といいます。Java 言語では、ソースコードは .java という拡張子を持ちます。ソースコードは人間に読みやすい反面、コンピュータが直接読んで実行できません。

コンピュータがソースコードを読んで実行するためには、ソースコードをコンピュータの読めるコードに変換します。この変換のことを コンパイル(compile) といいます。また、コンパイルを行うアプリケーションのことを コンパイラ(compiler) といいます。コンパイルする人(er)というわけです。コンピュータが直接読み取ることのできるコードを 実行コード といいます。

実行コードを読み込んで、コンピュータは人間のやって欲しい処理を実行することができます。たくさんの命令の書かれたファイルとしてのプログラムと対比して、いままさに実行しているプログラムのことを プロセス といいます。

2-2. 中間コード

jshell-2.png

Java言語では、ソースコードをコンパイルすると、実行コードではなく 中間コード が生成されます。なぜ 中間 なのかというと、実行時に更に変換されるためです。ソースコードと実行コードの中間なので、中間コードです。

Java プログラムは実行時、 Java 実行環境(JRE: Java Runtime Environment) によって解釈され、実行されます。 JRE が中間コードを読み取り、実行する環境ごとに命令を解釈して実行します。そのため、中間コードはひとつであっても、異なる実行環境でプロセスを起動できます。言い換えると、一度コンパイルしたコードは、異なる実行環境であっても(理論的には)そのまま動作します。この性質を指して、Java が出た当時はよく Write Once, Run Anywhere(一度書いたコードが、あらゆる場所で実行できる) と言われていました。

3. プログラムの実行方法

Java プログラムの実行方法にはいくつかあります。以下はその代表的な例です:

jshell-3.png

まずはより一般的な ソースコードをコンパイルしてから実行 を例に、プログラム実行の流れを確認しましょう。その後に、 JShell を使った対話的な実行 についても説明します。

3-1. コンパイルしてから実行

コンパイルされたコードは、いくつかの方法で実行できます。以下は代表的な例です:

  1. 実行可能ファイルをダブルクリックして実行する
  2. サーバー上にプログラムを配置して実行し、Web ブラウザごしに利用する
  3. java コマンドで実行する
  4. 統合開発環境で実行する

これらを順番に見ていきましょう!

3-1-1. ダブルクリックで実行

jshell-4.png

1つ目が、 実行可能ファイルをダブルクリックで動かす 方法です。これはいまのみなさんにとって一番身近だと思います。

Windows でも Mac でも、ファイルをカチカチッとダブルクリックするとアプリが動きますよね。Java でもこれができます。しかし、このためにはいくつかの段階を経る必要があります。

しかしいま私たちがやりたいのは「プログラムを実行して目の前の作業に役立てる」ことではありません。そうではなくて、目的は 作業に役立つプログラムを作るための方法や仕組みを学ぶ ことです。そうなると、プログラムをカチカチッとダブルクリックして実行できる必要はなく、むしろ変換が一手間です。そこでこの連載では、この方法で実行することはありません。

3-1-2. サーバー上にプログラムを配置して、Web ブラウザごしに動かす

2つ目が、 サーバー上にプログラムを配置して、Web ブラウザごしに動かす 方法です。近い未来、みなさんにとって身近になるのがこれです。

多くの研修やスクールではここを目指してカリキュラムが組まれています。Web アプリはある程度の技術を網羅的に使用するため、「ひとまずこれをやっておこう!」の一式に含まれやすいからです。

そうはいっても、それはまだもうちょっと先の話です。この連載で目指すのは「プログラムを活用する」というよりは、原理原則を丁寧に一歩ずつ、かつ最短路で学ぶことです。連載後の次の目標として、この方法を考えると良いでしょう。

3-1-3. java コマンドで実行する

3つ目が、 java コマンドで実行する 方法です。

コマンドプロンプト(or ターミナル)で java 何何 と実行したいファイルを指定します。これは、多くのスクールや研修、書籍でよく使われている実行方法です。しかし、エラーの発見が何かと難しく、「Java学習」という意味ではやや非効率なため、この連載では扱いません。

3-1-4. 統合開発環境で実行する

4つ目が、 統合開発環境上で実行する 方法です。

統合開発環境(IDE Integrated Development Environment)とは、プログラムを開発するうえで必要な機能をひとまとめにしたものです。コンパイルや実行だけでなく、プログラムの誤りを分かりやすく表示したり、プログラムを1行ずつ実行したりできます。

この方法もまた、多くのスクールや研修、書籍でもっとも使われている実行方法です。この連載でも、後半はこの実行方法を用いる予定です。

3-2. JShell を使って対話的に実行する

jshell-5.png

5つ目が、 JShell を使用して対話的に実行する 方法です。

ここまで見てきた4つの方法は、ソースコードをコンパイルして中間コードに変換してから実行するものでした。しかし、この方法ではコンパイルを経ずにソースコードを実行します。この連載で最初に使うのがこの方法です。

「対話的」という言葉に身構えないでください。大丈夫、怖くありません。「対話的」の意味は後ほど詳しくしますが、要するに Java を 電卓のように、結果を目で見て確認しながら使うというものです。この 電卓のように、結果を目で見て確認しながら使う 方法を、REPL: Read Eval Print Loop と言います。

4. REPL: Read Eval Print Loop とは

jshell-6.png

繰り返しになりますが、 REPL: Read Eval Print Loop とは、 電卓のように、結果を目で見て確認しながらプログラミングをする方法 です。

日本語で補って言うと

  1. Read : プログラムを機械が読み込み、
  2. Eval : 評価(= 計算)して、
  3. Print : 結果を出力する。
  4. Loop : 1. ~ 3. の繰り返しによってプログラムを実行する

ということです。

例えば、30 と 50 の平均 を電卓で求める方法を考えてみます。以下のようにするのではないでしょうか。

jshell-7.png

Read・Eval・Print が Loop していますね。これが REPL です。

5. JShell とは

スクリーンショット 2020-11-21 185516.png

JShell は、Java 言語を使った REPL ツールです。

いまは便利な世の中ですね、Webブラウザから JShell を利用できます。下記リンクから JShell を利用しましょう(ローカルに環境が用意されているかたはもちろんそちらを使ってください。なお、リンク先の安全性は検証していないので、心配なかたはローカルに環境を用意しましょう)。

https://tryjshell.org

JShell 内では Java プログラムが書けるほか、JShell を操作するコマンドも使用できます。取り急ぎ、以下の 2 つを理解しておきましょう:

コマンド 説明
/exit JShell を終了する
/reset JShell を初期状態に戻す

jshell-8.png

自身のローカル環境に Java 環境のあるかたは、コマンドプロンプト( or ターミナル)上で jshell と入力すれば JShell を実行できます。 JShell 実行中に /exit と入力すると JShell が終了し、コマンドプロンプトの操作に戻ります。

jshell-9.png

次回予告

今回は Java プログラムの門をくぐりました。次回からは JShell を使ったプログラミングの中身に入りたいと思います。プログラミングと言ってもやることは電卓と同じです。気構えずに楽しんで行いましょう!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java】ファイルを削除する(Fileクラスのdeleteメソッドで消えないときの解決策)

プログラミング勉強日記

2020年11月21日
Javaでコードを書いているときに、ファイルの削除がうまくできなかったのでその解決策とFileクラスのdeleteメソッドの使い方をまとめる。

deleteメソッドの使い方

 Fileクラスのdeleteメソッドは指定したファイルを削除うすることができ、Boolean型の値を返す。※一度実行すると取り消しができないので注意する。
 Fileクラスを使用するためにはjava.io.Fileをインポートする。

ファイルの削除
import java.io.File;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        File file = new File("text.txt");

        // deleteメソッドを使用してファイルを削除
        file.delete();        
    }

}

ファイル削除ができない場合

 ファイルを削除できない理由は2つ考えられる。

  • 書かれていないメソッドの中でファイルを使用している場合
  • 他のプログラムでファイルを開いている場合

 私の場合は他のプログラムでファイルを開いていたため、ファイルの削除ができなかった。

ファイルが削除できたか確認する方法

 最初に述べたように、deleteメソッドはBoolean型で返されるので、if文を記述することでファイルの削除ができたかどうか確かめることができる。

ファイル削除の確認
import java.io.File;

public class Main {
    public static void main(String[] args) {
        File file = new File("text.txt");

        // existsメソッドを使用してファイルの存在を確認する
        if (file.exists()) {
            // deleteメソッドを使用してファイルを削除する
            if (file.delete()) {
                System.out.println("ファイル削除成功");
            } else {
                System.out.println("ファイル削除失敗");
            }
        } else {
            System.out.println("ファイルが存在しません");
        }
    }

}

参考文献

【Java入門】file・directoryの削除で失敗しない方法(delete)
Javaでファイルの削除が上手く出来ません。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ブルジョワが考えたドメイン駆動設計をソ連が考案した作戦術で☆粉砕☆

今回の記事では、以下の記事に掲載されている5層アーキテクチャモデルを下地として、ソ連が考案した作戦術の概念を再現できるアーキテクチャモデルを目的としています。

記事タイトル:ドメイン駆動設計における5層アーキテクチャの全体図とソースの実装例
記事URL:https://qiita.com/aLtrh3IpQEnXKN7/items/33b0a748dec34a301b37

作戦術

作戦術とは

ソ連軍人スヴェーチンが提唱した概念です。
ロシアの広大な領土で軍隊を効率的に運用する術です。
作戦術は、時間、空間、手段、目的という4つの重要な要素で構成されています。
作戦術は、抽象的な戦略的ゴールを、作戦次元で目的別に分類し、戦術的次元で具体的な手段を定義します。

作戦術の思考スタイル

1.基礎となるドメインの洗い出し
2.ドメインを使用する戦術の考案
3.戦術の体系化
4.戦術を使用するユニットの編成
5.戦術を使用する空間の特定
6.戦術を組み合わせて作戦を実行し、中間ゴールとなる目的を達成
7.目的を組み合わせて最終的なゴールである目標を達成

なぜ作戦術が必要なのか?

ドメイン駆動設計を実現するクリーンアーキテクチャの構造には以下の欠点があります。
・ドメイン層をユースケース層で呼び出しているため、ドメイン層を使用する目的が定義されていない。
・ユースケース層のビジネスロジックの変更がドメイン層へ与える影響が大きい。
・ユースケース層とドメイン層の境界線が明確でない。

これらの問題は解決する方法として、クリーンアーキテクチャに作戦術の概念を再現する以下の階層の追加を提案します。
・戦術層・・・ドメイン層を使用する目的と手段を定義する階層
・作戦層・・・ユースケース層の中間ゴールである目的の定義、力を投射する時間と空間を特定し、戦術層のメソッドを組み合わせて中間ゴールとなる目的を達成する階層

作戦術を再現するアーキテクチャの概念と構造

全体像

image.png

ドメイン層

概要

事業活動の原子(アトム)からなる共通したビジネスロジックを定義するための階層。
エリックエヴァンスが特定した戦術的設計によって構成されています。

構造

ドメイン層はエリックエヴァンスが特定した以下の戦術的設計によって構成されています。
・値オブジェクト(Value object)
・エンティティ(Entity)
・サービス(Service)
・集計(Aggregate)
・仕様(Specification)
・工場(Factory)
・倉庫(Repository)

作戦術内で刷新される内容

エリックエヴァンスが特定した設計パターンは、オブジェクトの構造や機能を実現するハードウェアとして機能します。
しかし、ハードウェアの種類を区別するにはハードウェア内で動作するソフトウェアの定義が非常に重要です。
ドメイン層のハードウェアをカテゴライズ化するソフトウェアとしてアリストテレス形而上学で考案した以下の概念を使用することを提案します。
・物質
・関係
・品質
・量
・場所
・時間
・状態
・所持
・能動
・受動
デュナミス(可能態)
エネルゲイア(現実態)
エンテレケイア(完成体)

ブラッシュアップ

アリストテレス形而上学の概念を使用して、各戦術的設計をコンテンツを以下のように分類します。

・値オブジェクト(Value object)
・物質・・・DBのテーブル情報を格納する通常のオブジェクト
・関係・・・全体と部分からなるデータ構造を格納するオブジェクト。DBの親子関係にあるデータなどを格納する。
・量・・・現象、物体または物質の属性であり、その属性は大きさを持ち、その大きさを数値および計量参照として表せる
・場所・・・位置、空間、場所、土地。
・時間・・・時の流れを特定する時間の単位

・仕様(Specification)
・品質・・・使用目的を満たしているかどうかを決定するための評価の対象となる固有の性質・性能の全体
・状態・・・オブジェクトの現在置かれている状況、状態を表す
・所持・・・オブジェクトを所有する権利、契約を表す

・倉庫(Repository)
・デュナミス(可能態)・・・事物の生成<例>組織のリソース情報の登録
・エネルゲイア(現実態)・・・デュナミスが可能性を実現させた段階をエネルゲイア<例>顧客情報の登録
・エンテレケイア(完成体)・・・完成された事象<例>商品を購入

・サービス(Service)・・・ユーザーが主導的に行動するアクションを定義します。

・集計(Aggregate)・・・サービス(Service)の効果によって発生する副作用的なアクションを定義します。

戦術層

概要

ドメイン層のメソッドを使用する目的と手段を定義する階層です。
アリストテレスが自著『自然学』の中で論じた、四原因説によって構成されています。
目的因・・・物事の終り、すなわち物事がそれのためにでもあるそれ(目的)をも原因と言う。
作用因・・・新たな結果・成果を産出する意味での作用因。力のスタート地点を表す。
質料因・・・存在するものの物質的な原因。DBの情報をこと
形相因・・・形相または原型。ドメイン層の値オブジェクト(Value object)などが該当
目的因==>作用因==>質料因==>形相因の順番でロジックが実行されます。

構造

・作用因(Agent)・・・DCI Architectureの相互作用(Interction)の内のインターフェースメソッドをImplementする実クラスです。作用因(Agent)を通して戦術層から作戦層へのアクセスを提供します。

・技術(Techniques)・・・戦術層で使用される技術を定義します<例>SMTPによるメール送信、SMTPによるファイルアップロードなど。依存関係逆転の原則(DIP)に基づいてインフラ層に実装ロジックを戦術層にインターフェースを定義します。

・戦術(Tactics)・・・DCI Architectureの相互作用(Interction)を実現するためにインターフェースクラスです。ドメイン層のメソッド、技術(Techniques)クラスを呼び出して、手段を目的に奉仕させる手続きを実現します。

実行ロジックの順番

1.接近・・・ドメイン層のメソッドを実行し、値オブジェクト(Value object)を取得する。
2.コントロールの確立・・・値オブジェクト(Value object)のデータのフィルタリングと入力値チェック、戦術層の技術(Techniques)クラスの実行準備などロック操作を実行する
3.操作の実行・・・ドメイン層のサービス(Service)と戦術層の技術(Techniques)を組み合わせて操作を実行
4.操作の解除・・・ドメイン層のサービス(Service)と戦術層の技術(Techniques)のロック操作を解除する
5.撤退・・・生成したインスタンスの削除、一時的な保存データを削除する。

作戦層

概要

作戦層は中間ゴールとなる目的を特定し、戦術層の力と手段を実行するタイミング、テンポを調整します。
作戦層ユースケース層を構成する文脈(Context)です。
ユースケース層を構成する文脈(Context)の名称は共通していますが、ユースケース層を構成する時間と空間の差異によって、ユースケース層ごとに実行されるロジックは異なります。
作戦層を巨大なキャンバスとして捉えることがポイントです。
キャンバスの中では、登場人物が役割を演じ、特定のシーンが切り取られ作品として完成します。
キャンバスは以下の要素によって構成されます。
・主題・・・キャンパス内で描かれている状況
・目的・・・伝えたいメッセージ
・俳優・・・登場人物
・俳優が演じる役割・・・登場人物が演じる役割
・俳優が使用する道具・・・登場人物が使用する道具

構造

作戦(Opration)・・・DCI Architectureの文脈(Context)を実装するクラスです。ユースケース層の中間ゴールとなる目的をメソッドとして定義し、ユースケース層からBeanクラスを引数として受け取り、形態 (Form)クラスのメソッドを組み合わせることでユースケース層の中間ゴールとなる目的を達成します。

・形態 (Form)・・・力の形態や思考の方向性を定義し、戦術層作用因(Agent)を介して戦術層のメソッドへアクセスし、戦術層のメソッドの組み合わせることで特定のタスクを達成します。力の形態や思考の方向性には以下のように分類されます。
・機動(Mobility)・・・素早い動作。
・詭道(Masking)・・・対象を欺くステルス(迷彩)動作。
・反射(Reflection)・・・顧客 or ユーザーなどからの要求に対する反射動作。

・事前条件 (Precondition)・・・作戦(Opration)メソッド開始時に保証すべき性質。

・事後条件 (Postcondition)・・・作戦(Opration)メソッド終了時に保証すべき性質。

・不変条件 (Invariant)・・・作戦(Opration)メソッドの開始時と終了時に保証されるべき共通した性質。

実行ロジックの順番

1.目標の設定・・・ユースケース層から中間ゴールとなる作戦層のメソッドを実行
2.方法の選択・・・状況に適した形態 (Form)クラスを選択
3.手段の選択・・・形態 (Form)クラス->作用因(Agent)クラスから該当する戦術(Tactics)クラスを選択し、インスタンス生成を行い、メソッドを実行。

ユースケース層

概要

バックエンドにおける要求と最終的なゴールである目標を定義するための階層です。
中間ゴールとなる目的となる作戦層のメソッドを順番に呼び出し、最終的なゴールである目標を達成します。
ユースケース層場所、時間、意図の3要素の組み合わせによって、中間ゴールとなる目的の構成、実行順番が変化します。

概要

・意図(Intention)・・・ユースケース層を実行する狙いを定義します。以下のカテゴリに分類されます。
偵察(Search)・・・検索したデータを画面に表示する
順次(Regular)・・・ビジネスのワークフローを次状態に進める
解除(Cancel)・・・約束事を解除する
突発的(Guerrilla)・・・ランダムで発生するイベントを実行
監視(Monitoring)・・・ルールに違反していないか監視を行う
抑止(Escalation)・・・ルール違反を行っているターゲットに通知を行い、強制的に従わせる
緊急(Emergency)・・・緊急事態に対応する

・場所(Place)・・・ユースケース層を実行する地域です。国家、地形、地域、緯度、経度などによって構成されます。

・時間(Time)・・・ユースケース層を実行する時刻です。午前、午後、日、祝日、休日、平日などによって構成されます。

・記録(Bean)・・・コントローラー層から取得した情報を格納し、作戦層のメソッドへ引数として引き渡します。最終的にユースケース層の実行結果をコントローラー層へ返却します。

コントローラー層

概要

アプリ外からアクセスの出入り口となるアダプタを主にRestApiで提供します。
アプリ外からのアクセスがWeb、iOS、Androidと増加するたびにアダプタを追加する必要があります。
アダプタ以外の機能として、コントローラー層からユースケース層へのデータを受け渡す際のデータ変換、コントローラー層からアクセス元へのデータ変換(JSON化)を行います。

構造

・操作デバイス(Controller)・・・REST APIの提供、Convetクラスのメソッドの呼び出し、ユースケース層のメソッドの呼び出し、Web用、Andoroid、iOSへ引数を返却する際の値変換(JSON化)などを一覧の手続き操作を実行。

・変換(Coverter)・・・REST APIから取得した画面の入力値の値をユースケース層へ引き渡す際の値の変換、ユースケース層からコントローラー層への値を返却する際の変換処理を担当します。

インフラ層

概要

外部ライブラリを使用したロジックを記述し、全レイヤーに外部ライブラリの機能を提供します。例としてメールの送信、ログの出力などが該当します。
ライブラリはバージョンアップや使用するライブラリ変更されるなど、頻繁に発生する箇所します。そのため、DIP(依存関係逆転の原則)に従って、
ドメイン層にインターフェースを配置し、実際のロジックはインフラ層に記述します。

メリット、デメリット

作戦術を再現するアーキテクチャを適用する際のメリット、デメリットは以下になります。

メリット

・ドメイン層を使用する目的が明確に定義されるため、ドメイン層のソースの保守性、可読性が向上します
・作戦層でユースケース層ごとのロジックの差異が吸収されるため、ユースケース層のロジックの変更が容易になります
・戦術層でドメイン層のメソッドを組み合わせて目的を達成するロジックを定義することができます

デメリット

・レイヤー数とクラス数が増加するため、小規模なプロジェクトには不向きです
・DCIアーキテクチャを実現することができるプログラミング言語でしか採用できません

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Doma入門 - ログライブラリにSLF4Jを使う

はじめに

DomaはJavaの標準ライブラリ以外に依存しないことをコンセプトに謳っているので、デフォルトのログライブラリとしてJUL(java.util.logging)を使っています。ただ残念なことにJULは使いにくいということでとても不人気ですね。

この記事では、ログライブラリをJULからSLF4Jに切り替える方法を説明します。

Domaのバージョンは現時点で最新の2.44.3を想定して説明します。
Domaの他の機能については、Doma入門もお読みください。

Domaのログの仕組み

Domaの実行時のログ出力は、org.seasar.doma.jdbc.JdbcLoggerインタフェースを介して行われます。

doma-core.jarには、org.seasar.doma.jdbc.UtilLoggingJdbcLoggerというJULを利用する実装クラスが含まれており、Domaを単体で利用する場合はこのUtilLoggingJdbcLoggerが使われます。

他のログライブラリを使うには、別の既存実装を利用するか自前で独自実装を作成する必要があります。

DomaのSLF4J対応

doma-slf4j.jarに、SLF4Jを使うorg.seasar.doma.jdbc.Slf4jJdbcLoggerという実装クラスがあります。JULからSLF4Jに切り替えるにはUtilLoggingJdbcLoggerの代わりにSlf4jJdbcLoggerを使うようにすればOKです。

これら2つの実装クラスの違いですが、利用するログライブラリが異なることに加えてデフォルトのログレベルが異なります。UtilLoggingJdbcLogger経由で出力されるデフォルトのログレベルはINFOですが、Slf4jJdbcLoggerのデフォルトのログレベルはDEBUGとなっています。

Slf4jJdbcLoggerを使うにはMavenやGradleではdoma-core.jarと同じバージョンのdoma-slf4j.jarへの依存が必要です。SLF4Jにバインディングさせて他のログライブラリ(logbackなど)を使う場合は、そちらの依存設定も忘れずに。

利用例はgetting-startedを参照ください。

Spring Bootを使う場合

Spring Bootを使っている場合でも、Slf4jJdbcLoggerを使えさえすればログライブラリをSLF4Jに切り替えられます。

doma-spring-boot 1.5.0以上使っている場合、この切り替えはとても簡単でapplication.propertiesに下記のように記載するだけです。

application.prpoperties
doma.jdbc-logger=SLF4J

なお、ログが出力されるようにするには、doma-spring-bootの利用の有無にかかわらず、Spring Bootのお作法にしたがって下記のようにログカテゴリの指定をしてください。

application.prpoperties
logging.level.org.seasar.doma=DEBUG

Quarkusを使う場合

Doma向けのQuarkusのExtensionであるquarkiverse-domaを使うのが簡単です。
このライブラリはデフォルトでSLF4Jを使います。

ログ出力をするには、Quarkusのお作法にしたがって次のように記載するだけです。

application.prpoperties
quarkus.log.category."org.seasar.doma".level=DEBUG

おわりに

DomaでログライブラリをSLF4Jに切り替える方法を説明しました。

SLF4J向けの実装を作ったのはつい最近(Doma 2.43.0から)ですが、もっと前から対応してもよかったですね。

ところで、最近ZulipというチャットサービスにDoma専用のルームを開設しました。もしDomaに関して質問などあればこのチャットルームでお気軽にどうぞ。

参考情報

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Java】コンストラクタ・getter・setter

コンストラクタ

この記事は私のJavaの学習なメモです。
Javaのコンストラクタ、getter、setterについて学んだ内容を書いています。

コンストラクタとは

コンストラクタ は、インスタンスを生成するタイミングで呼び出される、 特別なメソッドです。
普通のメソッドとそっくりですが、名前には「クラス名と同じ名前」をつかい、戻り地がないので戻り地の型を指定しないところが違います。

コンストラクタは 引数 を持ことができ、呼び出されたコンストラクタ内では、それを用いた処理などさまざまなことを行うことができます。

通常はコンストラクタ内で、フィールド変数などに 初期化処理 を記述 することが多いです。

また、クラスを使用する際に 習慣化したい処理がある場合 などにも利用します。

使用例

引数なしの場合

//ConstructorPractice.java(引数なし)
public class ConstructorPractice {
    String str = "引数なしの場合こちらの表示がでます。";

    // コンストラクタ
    public ConstructorPractice() {
        System.out.println(str);
    }
}

//Main.java(引数なし)
public class Main {

    public static void main(String[] args) {
            // インスタンスの生成
        ConstructorPractice cp = new ConstructorPractice();

    }
}

実行結果

引数なしの場合こちらの表示がでます。

引数ありの場合

ConstructorPractice.java

//引数ありの場合
public class ConstructorPractice {
    String str = "引数ありの場合";

    // コンストラクタ
    public ConstructorPractice(String str) {
        System.out.println(str);
    }

}

Main.java

public class Main {

    public static void main(String[] args) {
        //インスタンスの生成
        ConstructorPractice cp = new ConstructorPractice("引数ありの場合こちらの表示がでます。");
    }

}

実行結果

引数ありの場合こちらの表示がでます

コンストラクタの記述のしかた

コンストラクタの記述は、こちらのような順序で行います。

  1. アクセス修飾子(省略可)
  2. コンストラクタ名
  3. 丸括弧内に引数の型
  4. 引数名
アクセス修飾子 コンストラクタ名(引数の型 引数名) {
    //処理
}

以下のコードは ポケモンのデータをを扱うようなクラス のコンストラクタの例です。

//①     ②       ③      ④   
public Pokemon(String name){
    //処理
}

コード内の順で記述し、 ブロック( { } )で囲むようにして 実際の処理を記述します。
コンストラクタ名に関しては、【Java】クラス・フィールド変数 でも触れましたが、コンストラクタはクラスと同じ名前を付ける決まりになっています。

コンストラクタ ありの場合の値のセット方法

また、通常のメソッドと異なり、 コンストラクタには戻り値がありません。

クラスに コンストラクタ を実装することで、
そのクラス内に存在するフィールド変数への値の設定を一括で行うことができるため、
インスタンス生成後は持つべき情報が詰まったクラスが使用可能となります。

先ほど作成したクラスには、例えば以下のような情報を持つとします。

  • ボケモンナンバー
  • ぶんるい
  • 名前
  • タイプ
  • 説明文

仮にこれらの情報が すべて必須であるならば、
いちいちインスタンスを生成してからセットするのではなく、
以下のようにして インスタンス生成時に一括で値をセットする 方が賢い書き方になります。

ここまではインスタンスを生成してから、フィールドの値をセットしてきましたが、これはインスタンスフィールドが増えると面倒になりそうです。
実はインスタンスフィールドへの値のセットを楽にする方法が用意されています。

※ ちなみに中に入っている this という値は「ローカル変数とフィールド変数を明確に区別するため、フィールド変数名の頭につける特殊な変数」です。this は クラス内のメソッドの定義の中でのみ使用できます。

コンストラクタ がある時の値のセット

Pokemonクラス

//【Pokemon.java】
public class Pokemon {
    // フィールド変数
    public int number;
    public String name;
    public String category;
    public String type;
    public String description;

    public Pokemon(int number, String name, String category, String type, String description) {
        this.number = number;
        this.name = name;
        this.category = category;
        this.type = type;
        this.description = description;
    }

}

Main.java

//【Main.java】
public class Main {

    public static void main(String[] args) {
        // 呼び出し(new した後で、引数へ与えられた値を元に Pokemon が生成されます)
        Pokemon pikachu = new Pokemon(025, "ピカチュウ", "ねずみポケモン", "でんき",
                "つくる でんきが きょうりょくな ピカチュウほど ほっぺの ふくろは やわらかく よく のびるぞ");

        // 使用時
        System.out.print("No." + pikachu.number);
        System.out.println(" " + pikachu.name);
        System.out.print(pikachu.category);
        System.out.println(" " + pikachu.type + "タイプ");
        System.out.println(pikachu.description);

    }
}

実行結果

No.21 ピカチュウ
ねずみポケモン でんきタイプ
つくる でんきが きょうりょくな ピカチュウほど ほっぺの ふくろは やわらかく よく のびるぞ

コンストラクタ なしの時の値のセット

//【Main.java】
public class Main {

    public static void main(String[] args) {
        // 呼び出し(new した後で、引数へ与えられた値を元に Pokemon が生成されます)
        Pokemon mewtwo = new Pokemon();
        // set〇〇で値をセットする
        mewtwo.setNumber(150);
        mewtwo.setName("ミュウツー");
        mewtwo.setCategory("いでんしポケモン");
        mewtwo.setType("エスパー");
        mewtwo.setDescription("研究のために遺伝子をどんどん組み換えていった結果 凶暴なポケモンになった。");
        // get〇〇で値を取得する
        System.out.println("No." + mewtwo.getNumber());
        System.out.println(mewtwo.getName());
        System.out.println(mewtwo.getCategory());
        System.out.println(mewtwo.getType() + "タイプ");
        System.out.println(mewtwo.getDescription());
    }
}

//【Pokemon.java】
public class Pokemon {
    // フィールド変数
    private int number;// ポケモンのナンバー
    private String name;// ポケモンの名前
    private String category;// ポケモンの分類
    private String type;// ポケモンのタイプ
    private String description;// ポケモンの説明

    // setter
    public void setNumber(int number) {
        this.number = number;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public void setType(String type) {
        this.type = type;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    // Getter
    public int getNumber() {
        return this.number;
    }

    public String getName() {
        return this.name;
    }

    public String getCategory() {
        return this.category;
    }

    public String getType() {
        return this.type;
    }

    public String getDescription() {
        return this.description;
    }
}

実行結果

No.150
なまえ ミュウツー
いでんしポケモン
エスパータイプ
研究のために遺伝子をどんどん組み換えていった結果 凶暴なポケモンになった。

カプセル化に必要な getter 及び setter の理解が全然出来ていなかったので実装に時間かかった。。

getter・setter

結論から言うと、private になっているフィールド変数を

  • *変更するのが setter *
  • *取得するのが getter *

です!
なぜ、どうして、どのように使うのかというのはまずカプセル化

カプセル化とは

オブジェクト指向の重要な機能の1つで、 「オブジェクトの情報が外部に公開しないようにすること」、「使い手に必要ないものを隠してしまうこと」 **それがカプセル化**です!

  • 大切なデータが他の人が操作した時変わってしまわないように
  • クレジットカードの情報が外にもれないように
  • ネットで勝手に買物をされないように

そのために情報を アクセス修飾子 の private でクラスの外部から変更できないように設定する必要があります。

よほどの理由がない限りは** フィールド変数(メンバ変数) はすべて private に設定しましょう。**

getter

getter は単純に「フィールドの値を取り出すだけのメソッド」 です。

前述の通り、private に設定されたフィールドは外部からアクセスが出来ないので、こちら

getter の書き方

こちらがgetter メソッドの書き方になります。

【getter の命名規則】

getter の命名規則は フィールド名の頭に「get」をつけたキャメルケースの書き方をすること。(例:getName)

【public で記述する】

また、フィールドはprivateで書くのがルールなのに対し、
getter, setter は 外部で扱えなくてはいけないため、すべてpublic で記述すること!

//フィールド変数を定義
private データ型 フィールド名

// getter
public データ型 getフィールド名() {
    return this.フィールド名;
}

こちらは、number というフィールド変数に対して作った getter のサンプルです。

// フィールド変数
private int number;

// Getter
public int getNumber() {
    return this.number;
}

setter

setter は単純に「フィールドに値を代入するためのメソッド」 です。

setter の書き方

こちらがsetter メソッドの書き方になります。

【setter の命名規則】

setter の命名規則は getter と同じです。
フィールド名の頭に 「set」 をつけたキャメルケースの書き方をしてください。(例:setName)

【public で記述する】

繰り返しになりますが、
getter, setter は 外部で扱えなくてはいけないため、すべてpublic で記述すること!

// フィールド変数
private int フィールド名;

// setter
public void setフィールド名(int 引数名) {
    this.フィールド名 = 引数名;
}

こちらは、number というフィールド変数に対して作った setter のサンプルです。

// フィールド変数
private int number;
// setter
public void setNumber(int number) {
    this.number = number;
}

setter をチェックを掛けて使う

setterメソッドを使って書き込むことで、書き込むデータのチェックを行うことが出来ます。

例えば、フィールド に100以下の値しか入れたくない場合、フィールドに直接値を書き込む場合は書き込む側がチェックをする必要があります。
しかし、setterメソッドであれば、メソッドの中でチェックしておけば書き込む側の手間がなくなり安全性も高くなります。

// フィールド変数
private int フィールド名;

// setter
public void setフィールド名(int 引数名) {
    if ( 条件式 ){
    this.フィールド名 = 引数名;
    }
}

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む