« 2022年10月 | トップページ

2022年11月

2022/11/29

UMTPモデリングフォーラムのパネル討論の感想

先週11/24に行われたUMTPモデリングフォーラムのパネル討論だけを聞いた。
ラフな感想をメモ。

【参考】
MF2022プログラム - UMTP 特定非営利活動法人UMLモデリング推進協議会

30、50、100人の壁の正体|山本 正喜 / Chatwork CEO|note

データモデリングの立場の中山さん、渡辺さんに対し、ドメイン駆動設計の増田さん、スクラムの原田さんという割りと立場や意見も異なる人達の討論だった。
話は色々あったが、その中で気になった点は2つある。

1つは、少人数のベンチャー企業から大人数の大企業へ進化する時にどんな壁があるのか?

スパン・オブ・コントロールの原則通り、1人の社長が統率できる人数はせいぜい5~7人まで。
そこから20名、50名、100名、300名と増えるごとに、ピラミッドのような階層構造を持つ組織になっていく。
すると、必ずその会社特有の業務システムが必要になってくる。

興味深かったのは、30名未満の少人数ベンチャー企業が、従業員数よりも多い個数のSaaSを運用している会社があるよ、という話。
おそらく、10名未満の少人数ベンチャー企業であれば、自社だけに作り込んだ業務システムは不要であり、SaaSを導入するだけで十分やっていけるだろう。
しかし、事業や業務がどんどん拡大していき、従業員も増えるが、それ以上に業務が複雑化して、その業務を支えるSaaSを次々に導入して運用してしまった。
しかし、SaaSにインポートするデータは、各事務員がExcelで作りこんで準備して取り込んで修正する作業を行っている、と。
これは、いわゆる「人間バッチ」と同じですね、と。

「人間バッチ」と揶揄する理由は、本来は事業や業務を回すための業務システムを独自に作って自動化する必要があるのに、それをさぼって、事務員が労力をかけて業務データをExcelで作り込んでSaaSに流し込むという手作業をこなっているからだろう。
結局、今はどんな企業であれ、税務会計だけでなく、事業や業務を回すためのシステムも必要になっているわけだ。

そんな状況ではデータモデリングがとても威力を発揮すると思う。
なぜならば、業務を回すための仕組みを分析するには、業務フローだけでなく、事務員が作り込んでいるExcelデータを抽象化したデータモデルが必要になってくるからだ。
そのデータモデルさえきちんと分析できれば、業務フローも画面もバッチも帳票もほぼ決まってしまう。
業務分析とデータモデリングは表裏一体と思う。

もう一つは、データモデリングが業務分析、ビジネスモデルの分析でとても有用なのに、なぜその技術が普及せず、軽んじられているのか?

パネラーの方も色々話されていたが、僕は本当の原因が他にあるような気がした。
単にIT技術者や事務員にデータモデリングの知識が足りないから、だけではないだろう。
データモデリングを習得するモチベーションがそもそもないことに真因があるだろう。

特に昨今のアジャイル開発に興味を持つ人であれば、古臭いデータモデリングよりもドメイン駆動設計の方に惹かれるだろう。
実際、増田さんが主催されるドメイン駆動設計の勉強会にはたくさんの開発者が集まるのに、データモデリングの勉強会はあまり開催されていないし、開催されたとしても正直あまり人は集まらない。

それはなぜなのか?
その理由は僕もわからない。
このテーマは今後も考えてみたい。


| | コメント (0)

2022/11/20

ComparableとComparatorの違いは何か

ComparableとComparatorの違いを混同していた。
自分用のラフなメモ書き。

【参考】
Java:任意の順番でのソート ? サイゼントの技術ブログ

compareToでJavaのソートは自由自在! 一からお伝えします

Java - オブジェクトの比較(==、equals、Comparable、Comparator)

Java Comparatorメモ(Hishidama's Java Comparator Memo)


結論は、
java.lang.Comparableは、Arrays.sort(Object[]), Collections.sort(List)で使う。
ソートを行いたいクラスにComparatorを明示的に実装する場合に使われる。

java.util.Comparatorは、ラムダ式やstream.sorted()で使う。
Comparatorは、ソートしたいクラスからソートのロジック部分を分離したいときに使われる。

違いは、Comparatorインターフェイスではなく、Comparatorはオブジェクトとして作成する。

class Book implements Comparable{} は、
処理の中で自分のクラス(Book)のソート順を定義します。
comparaTo()をオーバーライドして定義します。

//java.lang.Comparableは、自分のクラスと比較してソートする
public class Book implements Comparable{
// タイトル
private String title;
// 値段
private int price;
// 発行日
private LocalDate dateOfIssue;
@Override
public int compareTo(Book book){
return title.compareTo(book.title);
}
}
Collections.sort(bookList);

つまり、Comparableを格納しているListをソートする際は、Collections.sort(List)/reverse(List)を使うのが基本。
AA.compareTo(BB) => java.lang.Comparable を連想する。

たとえば、String#compareTo(String)、Integer#compareTo(Integer)になる。
Comparable.compareToのコツは、判断結果は小さい・等しい・大きいの3種類だけ。
値や文字列が等しいか、どちらが大きいかを判断するだけ。

オブジェクトや文字列や数値のListやSetを直接ソートしたい場合は、Comparableを継承して、compareToメソッドを実装する。
その方が楽。

一方、class BookTitleComparator(ソート用クラス) implements Comparator{} は、
処理の中で何かのクラス(ソートさせたいクラス)のソート順を定義します。
compare()をオーバーライドして定義します。

//java.util.Comparatorは、任意のクラスをソートできる
public class BookTitleComparator implements Comparator {
@Override
public int compare(Book book1, Book book2){
return book1.getTitle().compareTo(book2.getTitle());
}
}
bookList.sort(new BookTitleComparator());
または
bookList.sort((book1, book2) -> book1.getTitle().compareTo(book2.getTitle()));

ストリームAPIでは、基本はComparatorを使う場合が多い。
なぜなら、ソート処理にラムダ式を頻繁に使うから。

こんなことを調べてみると、ComparableはComparatorよりも古いAPIなのだろう。
Java8以後でラムダ式が生まれたので、Comparatorはその後に定義されたのだろう。

実際、java.lang.Comparableなので、import文は不要。
一方、java.util.Comparatorなので、必ずimport文は必要になる。

| | コメント (0)

Javaのsumはreduceで置き換えられる

JavaのストリームAPIとして、sum()とreduce()をよく混同していた。
JDKのsum()の定義を読んだら、Javaのsumはreduceで置き換えられると分かった。
以下は自分用のラフなメモ書き。

IntStream (Java SE 11 & JDK 11 )

Javaのreduceの使い方は2種類ある: プログラマの思索

Java Optionalメモ(Hishidama's Java8 Optional Memo)

一般に、sumはこんな感じで使われる。
int total = items.stream().mapToInt(Item::getPrice).sum();

sumはIntStreamだけで定義されているのに、Streamでも使えると混乱していた。
だから、map()の後に使えるのか、mapToInt()の後に使えるのか混乱していた。
理由は、数値配列型のStreamでしか使えないからだろう。

もう一つは、sumの戻り値がなぜOptional型ではないのか?
averageの戻り値はOptionalDoubleだし、他の統計処理メソッドもOptionalが多いのに、なぜsumだけがint型が許されるのか?

(引用開始)
sum
int sum()
このストリーム内の要素の合計を返します。 これはリダクションの特殊な場合であり、次と同等になります。

return reduce(0, Integer::sum);

これは終端操作です。

戻り値:
このストリームの要素の合計
(引用終了)

上記の定義を読むと、sumは、 return reduce(0, Integer::sum); と同じなので、必ず初期値0が設定されているので、NULLになる可能性はなく、Optional型はなくてもいい。
sumの戻り値の型はIntegerが正しいが、オートボクシングされてint型もコンパイルOKになる。

つまり、
int total = items.stream().mapToInt(Item::getPrice).reduce(0, Integer::sum);

int total = items.stream().mapToInt(Item::getPrice).sum();
は同じ。

sumをreduceで書き換える時、こんな感じでもOK。

int total = items.stream().map(Item::getPrice).reduce((x,y) -> x+y).orElse(0);
int total = items.stream().map(Item::getPrice).reduce((x,y) -> x+y).get();
int total = items.stream().map(Item::getPrice).reduce(0, (x,y) -> x+y);

reduce(op)の戻り値はOptionalになる。
だから、Optional演算子orElse, getが必要。

一方、reduce(0, op)の戻り値はIntegerになる。
だから、戻り値はオートボクシングされてint型もOK。

IntStream.mapToInt(ToIntFunction).sum()で覚える。
Stream.map(Function,Optional>).reduce(bo)で覚える。

ちょっとややこしいのは、averageの場合、戻り値=OptionalDoubleになる。
なぜならば、DoubleStreamでaverageが定義されているから。
Optionalではない点に注意。

DoubleStream (Java SE 11 & JDK 11 )

こんな例かな。
double avg = items.stream().mapToInt(Item::getPrice).average().getAsDouble();
double avg = items.stream().mapToInt(Item::getPrice).average().orElse(0.0);

OptionalDoubleをOptionalへ変換できるか?という記事もあった。

Convert OptionalDouble to Optional - Stack Overflow

下記の記事が分かりやすい。
JavaのOptionalは、ScalaのOptionクラスに相当する。
Optional型で扱えば、空かどうかの判定を自動判定してくれるメリットがある。

Java Optionalメモ(Hishidama's Java8 Optional Memo)

「OptionalとOptionalInt等の相互変換は出来ないようだ。(継承関係も無いし、変換に使えそうなメソッドも無い)」とのことなので、OptionalとOptionalは明確に異なる。
たぶん、IntStreamの場合とStreamの場合で異なるのだろう。

| | コメント (0)

2022/11/16

XPエクストリームプログラミングは偉大だ~時代がその設計思想に追いついた

XPエクストリームプログラミング入門をオンラインで聞いた。
改めて、XPエクストリームプログラミングは偉大だ、時代がその設計思想に追いついた、と思った。
ディスカッションの内容から感じたことをラフなメモ。

【参考】
XPエクストリームプログラミング入門 - connpass

ITの地殻変動はどこで起きているのか?~チケット駆動開発はなぜ生まれたのか: プログラマの思索

僕は、「XPエクストリーム・プログラミング入門―ソフトウェア開発の究極の手法 」の第1版の方が好きだ。
理由は、荒削りだが内容はとてもシンプルで、当初考えていた直感的な思いが直接的に表現されているからだ。

- eXtreme Programmingの魅力を探るにある「Embrace Change - 変化ヲ抱擁セヨ」のグラフが一番好きだ。

勉強会の内容は放談会みたいで面白かった。

XPはプラクティスありきではない。
プラクティスは具体的な実践方法。
プラクティスは価値を実現したものの一つ。
しかし、価値は抽象的すぎるので、プラクティスと価値の間に原則を置いて、プラクティスと価値を橋でつなぐ。
そういう絵がXPではよく出るが、その意味がようやく分かった。

XPのプラクティスは、そのテーマ単体だけで一冊の本になる。
たとえば、リファクタリングなら、リファクタリング(第2版)
テスト駆動開発なら、テスト駆動開発実践テスト駆動開発
継続的インテグレーションなら、継続的インテグレーション入門継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化
見積もり手法や計画ゲームなら、アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~
ふりかえりなら、アジャイルレトロスペクティブズ 強いチームを育てる「ふりかえり」の手引き
シンプルな設計なら、エリック・エヴァンスのドメイン駆動設計
つまり、それぞれのテーマはとても奥深いのだ。

たぶん、それらのテーマは重要である、とケント・ベックは直感的に感じていたのだろう。
それを言語化して形式知としてプラクティスで取り上げたのはすごいと改めて思う。

福井さんいわく。
最初はスクラムは好きではなかった。
XPは具体的なのに、スクラムではプロセスはしっかりしているが、実際に実践しようとすると中身が分からない。
でも、今はスクラムは好きですよ、と。
スクラムはスクラムマスターの存在が凄く大きい、と。

アジャイル開発は自動車の運転のようなもの。
到着先は分かっていて、その道順が分かっていても、不確定要素があり、ハンドル操作で変化を受け入れながら進める。
つまり、運転は変化が全くない動作ではないし、変化を受け入れる動作範囲に落ち着くようにする。

時代がアジャイルにやっと追いついた。
アジャイラーは当初は周囲と戦っていた。
いかに導入するか、いかに普及させるか、に注力していた。
しかし、今はお客様からも、アジャイル開発を導入したいと言われる。

WF型開発の権化だったPMBOKがアジャイル開発の考え方を取り入れて、PMBOKの最新版でごっそり変わったのも大きいね、と。
実際、PMBOKは従来の分厚い数多くのマネジメント技法の知識体系だったのに、アジャイル開発の考え方を具現化して、価値や原則が主体のマネジメント体系に変わろうとしている。

アジャイル開発を支える技術が揃ってきたのも重要だろう。
特にクラウドが普及したおかげで、すぐにサーバーを立ち上げて、実際に動かしてみて、動かしながら作っていくのができるようになった。
それもコストをあまり掛けずに、個人ですら開発できるようになった。
つまり、継続的インテグレーション、継続的デプロイ、リファクタリング、テスト駆動、短期リリースなどを支える技術が揃ってきたおかげで、アジャイル開発を実践しやすくなった、と。

一方で、SIがアジャイル開発に追いついていないように思える、と。
発注者は自社で内製開発がしたいので、アジャイル開発を自然に受け入れやすい。
しかし、SIは受託なので、既に自分たちの標準プロセスを持っているし、人月単価のビジネスモデルもあるから、いきなりアジャイル開発に変換するのは難しい。

僕がXPやアジャイル開発に惹かれる最大の理由は、IT業界のきつい仕事から脱出できるための救いとして捉えていた面があったからだと思う。
多重請負の人月単価のビジネスモデルの中で、大量のプログラマや技術者をまるで仕掛在庫みたいに扱って、変動するバッファみたいに扱う手法がどうしても慣れなかった。
アジャイル開発は人重視であり、技術者の専門性を活かしながらチームでアウトプットを出していく、という思想に引かれていたのだと思う。
IT技術者として専門性を高めていくと自然にアジャイル開発に収れんされていくはずだ、と思っていた。
今もその思いは変わらない。


| | コメント (0)

2022/11/14

JavaのモジュールシステムでSPIとDIを実現するやり方

JavaGold黒本を読んでいたら、JavaのモジュールシステムでSPIとDIを実現するやり方をやっと理解できた。
理解できたことをラフなメモ。

【参考】
Javaのモジュールシステムの考え方をまとめてみた: プログラマの思索

クラウド上の開発がJavaに与えた影響は何なのか: プログラマの思索

Javaのモジュールシステムは複雑性をより増している: プログラマの思索

Java 9のモジュール機能「サービス(SPI)」と既存ライブラリの共存 (1/2)|CodeZine(コードジン)

DI(依存性の注入)とは依存性を注入するということである、、? - Qiita

module-info.javaに下記のような記述がある。
Sampleモジュールはどんな構造を持っているのか?

module Sample {
exports test;
uses test.Hello;
}

Sampleモジュールは、testパッケージを公開しており、test.Helloインターフェイスの実装クラスを利用する。
つまり、Sample単体ではコンパイルできるけれど、実装クラスがセットでなければ動作しない。

SPI(Service Provider Interface)を実装したHelloモジュールがない場合、コンパイルエラーにならない。
実際、ServiceLoader.load()は空のServiceLoaderインスタンスを返却するだけでスキップされる。
こんなプログラムになるだろう。

ServiceLoader loader = ServiceLoader.load(Hello.class);
Iterator iter = loader.iterator();
while (iter.hasNext()) {
Hello obj = iter.next();
System.out.println(obj.sayHello());
}

つまり、META-INF/services/helloというテキストファイルから読み込む時に、実装クラスが書いてなければ、ループ処理は空回りするだけ。

では、test.Helloインターフェイスの実装クラスtest.impl.HelloImplを持つHelloモジュールはどんな構造を持つのか?
たぶんこんな構造だろう。

module Hello {
exports test.impl;
requires Sample;
provides test.Hello with test.impl.HelloImpl;
}

Helloモジュールは、test.implパッケージを公開して、Helloの実装クラスHelloImplを提供する。
この時、HelloモジュールがSampleモジュールを呼び出し、Sampleへの依存関係を持つ点が重要。
なぜならば、test.Helloを利用するには、定義されているSampleモジュールをImportする必要があるから。

すると、SampleとHelloは依存性の注入(DI:Dependency Injection)を実現していることになる。
なぜならば、SPIの定義より、クライアント側Sampleはライブラリ側Helloの実装内容を利用しているのに、プログラムの依存関係としては、HelloからSampleへ逆向きの依存関係を持っているからだ。

つまり、普通は、Sample(利用側) --> Hello(提供側) になるはずだが、Sample(利用側) <-- Hello(提供側) なので、依存関係が逆転している。

まとめると、
Sample --> testパッケージ --> test.Helloインターフェイス
Hello --> Sample --> test.Helloインターフェイス
Hello --> test.impl.HelloImplクラス
という依存関係を持つ。

DIが実現されていることによってどんなメリットがあるのか?

まず、test.Helloインターフェイスを実装した具象クラスは、Sampleモジュールのモジュールパスに含める必要はない。
なぜならば、SPIの実装は後から提供されるので、実装に依存する必要はないからだ。
つまり、最初にIFだけ定義して公開しておけば、SPIの実装側ライブラリは後から実装すればいい。
IFという約束事だけ定義して、具体的な中身は後から開発できるので、開発スケジュールを調整しやすく、仕様変更にも柔軟に対応できる。

次に、test.Helloインターフェイスを実装するモジュールは、Sampleモジュールを再コンパイルする必要はない。
なぜならば、SPIの拡張ポイントとなるインターフェイスは変わらない限り、実装クラスに依存しないからだ。
つまり、SPIを利用する側のSampleモジュールと、実装クラスを提供するHelloは独立してコンパイルできる。

CやJavaなどでは、リプレース時にリコンパイルが必要だったりして、開発環境を準備したり、リリースするときは割と面倒だが、リコンパイルが不要であれば、過去にコンパイルしたモジュールをそのまま利用すればいい。

このモジュールシステムのサンプルから、僕はJDBCドライバの実装を連想した。
JDBCドライバでは、JDBCドライバのIFは既に定義されているが、各RDBごとにJDBCドライバの実装は異なる。
つまり、ユーザ側はJDBCドライバのIFを使ってプログラムを組めば良く、各RDBの実装の違いを意識する必要はない。
後から、利用するRDBのJDBCドライバを組み込めばいい。

2000年代にDIのアイデアが出た時はすごい設計技法のようなイメージだったが、2020年代の今となっては枯れた技術の一つにすぎない。
しかし、こういう依存関係を逆転する技術を利用して、プログラムの複雑性を手懐けようとする設計手法は、今後もその必要性は変わらないと思う。

| | コメント (0)

astahとExcelの間でマインドマップをやり取りする方法はコピペだけ

astahとExcelの間でマインドマップをやり取りする方法はコピペだけと分かったのでメモ。

【参考】
マインドマップのExcel出力 | astah in 5 min

マインドマップは個人的にはよく使う。
1日のタスクの洗い出す。
1日のToDo管理は、マインドマップ上でアイコンを付けて、完了、進行中、作業順番、重要度、優先度などを付ける。
提案資料のアウトラインを書き出して、内容を肉付けしていく。
問題分析するときは、問題の症状からロジックツリーのように分解する。
構想を練っている時は、とにかくアイデアを書き出して、枝葉にアイデアを移動したり、つなげたり、まとめたりして、整理していく。
テスト仕様書を作るときは、テスト観点をざっくり洗い出して、機能ごとにばらして細かく書いていく。

そんな内容がまとまったら、やっぱりSIの現場ではExcel仕様書が幅を利かせているので、Excelと行き来できるのは便利。

astahのマインドマップをコピーしてExcelに貼り付けるだけ。
一方、Excelでインデントを付けたテキストをastahに貼り付けるだけ。

このあたりも色々試せるのはいい。

| | コメント (0)

2022/11/13

Javaのreduceの使い方は2種類ある

Javaのreduceの戻り値が異なるのに戸惑っていた。
Javaのreduceの使い方は2種類ある。
ラフなメモ。

【参考】
Java:Streamのreduceの使用方法 | GWT Center

Stream BinaryOperator(Java Platform SE 8 )


Javaのreduceは、Rubyのreduceみたいに、累積する処理みたいなもの。
MapRedcueの間柄のように、map関数とreduce関数はペアで考える。

reduceの引数はBinaryOperator型になるのは分かる。
合計値のように、2つの引数を累積させる処理を行って、1つの戻り値を返すだけ。

しかし、reduce(BinaryOperator)とreduce(初期値, BinaryOperator)は戻り値の型が異なるのに混同していた。
結論は、初期値を設定していなければ、戻り値が空の場合があるのでOptionalでラッピングして返す。
Optionalであれば、NullPointerExceptionのリスクを無くせるメリットがある。

reduceの引数に初期値を設定していれば、戻り値がなくても初期値をそのまま返せばいい。
つまり、戻り値はプリミティブ型でも問題ない。

Java:Streamのreduceの使用方法 | GWT Centerの説明がわかりやすかった。
以下引用している。

【パターン1】Optional reduce(BinaryOperator accumulator)
戻り値がない場合があるので、Optionalで返す。

// 何らかの要素があったか
boolean foundAny = false;
// 最終結果
T result = null;
for (T element : このストリームの要素を列挙する) {
if (!foundAny) {
// 最初の要素の場合
foundAny = true;
result = element;
} else {
// 二番目以降の要素の場合
result = accumulator.apply(result, element);
}
}
// 結果があればそれを返す。なければ空を返す
return foundAny ? Optional.of(result) : Optional.empty();

【パターン2】T reduce(T identity, BinaryOperator accumulator)

初期値が与えられているので「値が存在しない」ということは無く、戻り値はOptionalではない。

// 初期値
T result = identity;
for (T element : このストリームの要素を列挙する) {
// 初期値に加算していく
result = accumulator.apply(result, element);
}
return result;

IntStream (Java SE 11 & JDK 11 )には、reduceの考え方が書かれている。
これは参考になる。

int reduce​(int identity, IntBinaryOperator op)
指定された単位元の値と結合的な累積関数を使ってこのストリームの要素に対してリダクションを実行し、リデュースされた値を返します。 これは、次の操作に相当します。

int result = identity;
for (int element : this stream)
result = accumulator.applyAsInt(result, element)
return result;

つまり、reduceは何らかのアルゴリズムに添って累積させる処理を行っている。
その累積処理は抽象化されているので、アルゴリズムにラムダ式を当てはめれば汎用的に使えるわけだ。

| | コメント (0)

2022/11/06

Go言語でできることは何なのか

Go言語でできることは何なのか、について考えたことをメモ。
全くのGo初心者がいろいろ考えたことのメモ。
間違えていたら後で直す。

【参考】
とほほのGo言語入門 - とほほのWWW入門

Go言語(golang)とは? 特徴・できること・将来性を徹底解説 | 【テックストックMAGAZINE】エンジニア向けスキル・キャリア情報

Go言語にできることってなに?人気の理由をくわしく解説 | 株式会社パソナ(旧パソナテック)|ITエンジニア・ものづくりエンジニアの求人情報・転職情報

Go言語の強みと得意分野を探る(上) - Go言語の強みと得意分野を探る:Computerworld

Go言語の強みと得意分野を探る(中)1 - Go言語の強みと得意分野を探る:Computerworld

Go言語の強みと得意分野を探る(中)2 - Go言語の強みと得意分野を探る:Computerworld

Go言語の強みと得意分野を探る(下) - Go言語の強みと得意分野を探る:Computerworld

Go言語でできることとは?Go言語で作れるアプリの事例を紹介 | プログラミング大陸

Ruby->Go->Scalaという習得順序がエンジニアの爆速の成長に最適である理由 - Qiita

Go言語の書籍を色々読んでみて色々気づきはあった。

Go言語は、マイクロサービスアーキテクチャを実装するプログラミング言語であるらしい。
色々記事を読んでみて、Go言語は、CLIやAPIを作るのに最適な言語であると感じた。

他システムがWebサーバーからデータを取得したり更新しようとする時、APIという公開IFを設けて疎結合な設計にしたい。
Go言語であれば簡単にHTTPでやり取りできるのでWebサーバを立ち上げる必要もなく、普通のクライアントアプリケーションみたいに作ればいい。
また、Go言語では並行プロセスの実装も割と簡単なので、負荷に応じてプロセスを増やせば良く、クラウド上でAPIを公開するためのアプリとして最適。

Go言語でCLIを作るイメージは、Unixコマンドを作るイメージだろうか。
Unixであれば、/binの中に各種コマンドがexeで配置されている。
別システムがバッチ処理をキックしてシステム連携したい場合、CLIという公開IFを叩けば良い。

そんなことを考えると、Go言語はかなり特殊な状況で使うもののように思う。
業務ロジックを実装するレイヤではなく、OSやアプリの間で処理するためのミドルウェア、ないしフレームワークみたいな役割を持つレイヤで実装すべき。

また、Go言語はクラウドと相性がいい。
Go言語はクロスプラットフォームでバイナリファイルを作れるので、CLIやAPIに向く。
また、Go言語で作ったバイナリファイルのサイズを小さくできれば、クラウドのリソースを少なく押さえられる。
また、メソッド呼び出し時のアプリ起動時間を短くでき、並行プロセスで走るアプリの起動時間(ロード時間)も短くできる

クラウド上の開発がJavaに与えた影響は何なのか: プログラマの思索

Javaのモジュールシステムの考え方をまとめてみた: プログラマの思索

つまり、Go言語はクラウド上でCLIやAPIを実装したプログラムに特化した言語なのだろう。
だから、マイクロサービスアーキテクチャと相性が良いと言われているのだろう。
そして、マイクロサービスアーキテクチャはドメインごとの境界で使われるので、ドメイン駆動設計とも相性がよく、それらの設計技法と密接に絡む。

そんなことを考えると、一昔前のオンプレ環境でのWebシステム構築で経験されて蓄積されたアーキテクチャ設計技法は古くなっており、クラウドに特化したアーキテクチャ設計技法をもっと探究していくべきだ、という方向性が出てくるのだろう。
このあたりの考え方もいろいろ調べている。

| | コメント (0)

コンテナはサーバーレスアーキテクチャのための1つの技術

コンテナとは一体何なのか?
コンテナとはサーバーレスアーキテクチャのための1つの技術にすぎない。
AWS初心者のラフなメモ。

【参考】
202106 AWS Black Belt Online Seminar CON110 なぜ今コンテナなのか

JAWS-UG初心者支部#50 ContainerをCICD PileLineでDeploy!! - connpass

[JAWS DAYS 2022] ハンズオン~コンテナサービスをCI/CDパイプラインでデプロイしよう~

AWS初心者向けにハンズオンの勉強会があったので参加してみた。
手順書に書いてある通りに、コマンドを叩くだけでVPSやAPI Gatewayなどの環境が全て作られて、CI/CDパイプラインを試せる。
AWSの実戦経験がないので全然分かっていないが、実際に動く環境を作れて、実際に試して試行錯誤できる経験を得た。
とても良かった。
AWSはたくさんのサービスが既にあるので、それらを組み合わせるだけで開発環境やSaaSを簡単に立ち上げられると実感した。

コンテナとはいったい何なのか?
コンテナとは、VMとWebアプリケーションを一体化したものみたいなイメージ。

コンテナとはどのようなもの?クラウドサービスを動かすのに必要不可欠 | クラウドエース株式会社

Dockerは何がすごいのか?
コンテナを簡単に作れてDeployできること。
クラウド上にDockerファイルをアップロードしてrunすれば、簡単にWebアプリケーションを実行できる。
既にDockerイメージはたくさん配布されている。

なぜコンテナが必要なのか?
VMで仮想サーバを建てて環境構築するだけでは、Deployや運用の手間がかかる。
クラウドでVMとWebアプリケーションを一体化したコンテナで配布すれば、いつでも最新版のWebアプリを立ち上げられる。
つまり、Webアプリケーションがどんどんバージョンアップするたびに、コンテナで新規にデプロイすれば、いつでもクリーンな環境で立ち上げられる。

すると、コンテナをもっと進化させればサーバーそのものが要らないんじゃないの?となる。
AWSラムダがそんな感じだろうか。

今回のハンズオンでは、AWSでCICD PileLineを作る前にAWS VPCをすべてコマンドで作った。
一方、オンプレであれば、ルータを導入してネットワークアドレスを切って、その上にサーバーを構築して、ソースコードをビルドする環境も作ってデプロイして、という手順が必要になる。
だから、AWSは全くの初心者だが、AWS特有のコマンドを叩きながら、なるほど、こういうネットワークを作りたいのね、とか、こういうサーバー構成にしてデプロイしたいのね、とか、色々考えるところがあった。

プログラミングはブロックを積み上げる感覚に似ているが、AWSのサーバー構築もいろんな形のブロックを当てはめて積み木を作っている感覚だった。
この面白そうな感覚はもう少し掘り下げたい。

| | コメント (0)

第23回東京Redmine勉強会の感想~コミュニティは仲間から生まれて続く #redmineT

第23回r東京Redmine勉強会の感想をラフなメモ。
3年ぶりのリアル会場でハイブリッド開催だった。

【参考】
第23回勉強会 - redmine.tokyo

2022/11/5 第23回redmine.tokyo勉強会 #redmineT - Togetter

Redmine Advent Calendar 2022 - Adventar

【1】リアル勉強会で嬉しかったのは、@yukiaさんと@shinyaさんに対面で会えたこと。

yukiaさんとRedmineのトラッカーをヘーゲル弁証法とフッサール現象学の観点で議論したことがあった。

Redmineのトラッカーをヘーゲル弁証法とフッサール現象学の観点で議論してみた - Togetter

Redmineのトラッカーは一般向けに説明が難しいよね、その原因は何か?
yukiaさんはヘーゲル弁証法の観点で、トラッカーは各人ごとの切り口でバラバラに使っているが、弁証法でより一層抽象化ないしもう一段上の抽象化レベルで議論すれば同じ概念だ、と話。
僕の観点では、フッサール現象学やプラトンのイデア論みたいに、トラッカーという概念は客観的に存在すると思われているが、各人の目線では、帳票設計だったり、チケットの種類だったり、ワークフローだったり、いろんな解釈で存在が認識される、という話。

yukiaさんは「強制エポケー」というフッサール現象学の言葉も知っているので、僕が言いたい内容ももちろん理解した上で発言されている。
懇親会ではあまり話せなかったけれど、この辺りももう一度話しみたい所。

shinyaさんの、塩漬けチケットを一気に却下したツイートを以前コメントしていたら、反応が多かった。
他にも退職者ツイートなど、面白いツイートがあったのですごく記憶にあった。

他にもリアル対面の人を認識できて良かった。

【2】前田剛さんの話では、RedMicaのお話と国民年金基金連合会がRedmineで作られていた話。
これには笑った。

Redmineで構築されている国民年金基金連合会の「他年金調査 事業所回答システム」を調べてみた - ファーエンドテクノロジー株式会社

他年金調査 事業所回答システム

実際にログイン画面を見れば分かるが、どう見てもRedmineだ。
日本企業の事業所は約300万と言われているらしいので、その事業所にいる社員数をRedmineで管理していると考えると、相当な数のレコードがRedmineに蓄積されていて、個人情報の観点でも非常にセンシティブな内容があるだろう。
Redmineなら安全に運用できるという判断があったのではないか。
このあたりの話も勉強会で聞けると嬉しいね。

【3】僕の話はチケット駆動開発の昔話。
あの頃は若かった。
なお、2020年頃からRedmineの勢いに陰りが出て、JiraやBacklogの勢いを感じている。
実際Googleトレンドではそんな感じ。

齋藤さんはTwitterを使っています: 「@akipii google トレンドの話に、興味を持ちました。JIRA / backlog 勢がほぼ同じような動きですね。 実際の日本でのシェアは、どんなもんですかね? #redmineT」 / Twitter

akipiiさんはTwitterを使っています: 「@saito0119 #redmineT 詳細は知らないですが、ネットやコミュニティの話を見聞すると、JiraやBacklogの勢いは感じますよね。」 / Twitter

中村さんの話は、Redmineを5.0にVerUpしたお話。
プラグインの互換性確認のために手間がかかったそうだが、@g_maedaさんやプラグイン開発者、パッチ提供者のおかげで無事に乗り切れた、とのこと。
Redmineコミュニティが活発であるからこそ、安心して運用できるわけだ。

@geosanak さんの話は、Redmineプラグインのテスト自動化を頑張っている話。
ビルド管理ツールはJenkinsからCircleCIまで色々あるが、GithubActionを使ったよという話。
詳細をもう少し聞きたかったが時間切れ。

@bowkoba さんのオフショア開発にRedmineを運用した時に、コミュニケーションの問題が発生した話は同感だった。
チーム運営、プロジェクト運営で発生する問題は、結局のところ、プロマネが伝える内容が伝わっていない、指示を仰ぐメンバーが理解できていないことに尽きる。
その問題はコミュニケーション不足の症状として現れるが、その根本原因と再発防止策は、それぞれの現場で異なる。
現在、アジャイル界隈では、DXを実現するための組織論の話が多いが、その観点も、このコミュニケーション不足の問題と同じ構造を持つと思う。
結局のところ、組織文化の問題として出てくるが、本当の真因は、プロセスや組織構造に根っこがあるわけだ。

@t_tsuru さんのRedmineUIの問題点は、従来から問題提起されてきた。
この問題の改善は、今後どんどん重要視されてくるだろうと思う。
他のPJ管理ツールやSaaSでは、チケットのコメントがリアルタイムに表示されたり、UIが今風で使いやすかったりするので、どうしてもその観点から比較されて敬遠されてしまうから。

チケット茶番劇も面白かった。
実際にチケットのやり取りを見るのは楽しい。
チケットを書く人がどんな気持ちでいるのか?
リアルで見えるのはいい。

@yokoba569さんの話では、チケット駆動開発が良かったよ!という話。
チケット駆動が楽しい!
Redmineが実績管理にとても向いていて、実際にデータをメンバー自ら採取して分析し始める。
見積もりと持ち工数の観点でPJ管理をどんどん改善しようとする。

@tohosaku さんはRedmine を railway にデプロイしてみた話。
@agilekawabata さんは、Redmineハンドブックの紹介。
わかりやすくてとても良い本です。

@tkusukawa さんは、Redmineを利用する趣旨のお話。
趣旨を説明するのはいつも大事。

@hiroiwsk6さんは、お役所の問い合わせ管理と帳票出力をRedmineで改善した時に、どんな設計で構築したのか、というお話。
問い合わせチケットのステータスごとに、送信メールが作られるのが面白い。
つまり、ステータスごとに、メールの内容や宛先が微妙に異なってくるので、メールテンプレートをいかに共通化して設計するかが肝なのだろう。

@naitohさんは、勉強会の参加者や利用Redmineの属性分析のお話。
もう8年以上蓄積されているので、Redmineにも波がある。

【3】今回はハイブリッド開催。
会場の参加者は26人くらいで、そのほとんどが常連さんで初めての方もチラホラ来られていた。
その後の懇親会では、久しぶりの再会を皆で喜んだ。

オンライン開催が普通になった今では、確かにZoomでやった方が正直楽だ。
しかし、会場開催の方が、反応を生で感じられるし、いろんな人達と交流できるのが楽しい。
生身の人間と肌感を感じるのがとても久しぶりだったから、本当にそう感じた。

Redmineコミュニティももう11年目で、他コミュニティに比べても古参になった。
スタッフや参加者も入れ替わりがありながら、よく続いているなと思う。
熱量がある人が入れ替わり立ち替わり居続けることで続いているんだと思う。
コミュニティは仲間から生まれて続く。

| | コメント (0)

« 2022年10月 | トップページ