Skip to content

Instantly share code, notes, and snippets.

Junichi Kato j5ik2o

Block or report user

Report or block j5ik2o

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
View 割り勘ドメインのワークショップ.md

「割り勘」ドメインのワークショップ(WIP)

成果物

  • チームで設計に合意すること

副産物

  • ドメインモデル図
    • モデル名を書いた付箋を模造紙に貼る
View 自動販売機.md

いまだかつてない自動販売機をかんがえる

ビジネスの概要

売り切りの通常の自動販売機 モデルではなく、サービスとしての自動販売機を考える。サービスの特徴は以下。

  • 利用者はあらかじめ会員登録が必要で、月額100円で専用のスマフォアプリから何度でも飲料を購入できる

アクター/外部システム

View DCI.md

Lean Architecture APPENDIX A, ScalaでのDCIサンプルです。コプリエンさん作です。

increaseBalanceUnitを返すとはないわ〜。(今どき可変オブジェクトを中心にドメインを考えたくないという意味で。多分こういう考え方の人は関数型勢に多い。

import java.time.Instant // 元のサンプルはjava.util.Dateだったがさすがにそれは辞めろ的な意味で書き換えた

// Data
trait Account {
  protected var balance: Long = 0
View sbt.md

https://github.com/j5ik2o/akka-persistence-dynamodb

sbt.version = 1.3.0 にしてビルドしたら以下のエラー

以前、sbt-coursierにしたときも同様のエラーでたことある

$sbt clean compile
[info] Loading settings for project global-plugins from idea.sbt,sbt-updates.sbt,plugins.sbt ...
View gist:52742bbf84a680e34e086cd3d5b9178a
View gist:4041a22c5396052ce2239ee3cae8e702

お題

勉強会に参加する方は、以下の映画料金表を参考して、映画料金を決定するドメインモデルを考えて実装してください(実装言語はScalaを想定しています。が、チームで相談して違う言語を選択してもよいです)

具体的には、入力として顧客や時間の条件を与えると何らかの計算を行い、出力として映画の価格を返してくれるクラスを実装するイメージです(ドメイン駆動設計の戦術的なプラクティスにこだわらなくてもOKです)。入力条件から複数の映画料金が求められる場合は安い価格を決定してくださいね…。クラスは何個作っても構いません。ただし永続化とかGUIのことは考えないでください。動作を確認できる、コンソールアプリケーションかユニットテストがあれば十分です。

https://cinemacity.co.jp/ticket/

以下の要件を満たすのは必須ではないですが、時間がある方は挑戦してみてください。思った以上に複雑な要件なので注意してください。 また、レディースディ(女性でかつ毎週水曜は安くなる)など新しいルールを作って実装してもOKです。

View gist:72f5281260376e7394c12cbcea17e5f1
package domain

import java.time.temporal.ChronoUnit
import java.time.{DayOfWeek, LocalDate, LocalDateTime}

import enumeratum._

sealed trait Age extends Ordered[Age] {
  def breachEncapsulationOfValue(today: LocalDate): Int
View 末尾再帰.md

入力されたリストの要素を2倍し合計する関数

def loop(in: List[Int], acc: Int): Int =
  in match {
    case Nil => acc // 終了条件
    case head :: tail =>
      val result = head * 2 // headのタスク
      loop(tail, acc + result) // 残りのリストと計算途中を渡して処理を継続
  }
View 抽象化.md
public static boolean isNameHashUpperCase(String name) {
  boolean result = false;
  for (int i = 0; i < name.length; i++) {
    if (Character.isUpperCase(name.charAt(i)) {
      result = true;
      break;
    }
  }
  return result;
View PersistentWalletAggregate.scala
object PersistentWalletAggregate {
def behaviorProxy(
id: WalletId,
chargesLimit: Int = Int.MaxValue
): Behavior[CommandRequest] =
Behaviors
.supervise(Behaviors.setup[CommandRequest] { ctx =>
val childRef: ActorRef[CommandRequest] =
ctx.spawn(WalletAggregate.behavior(id, chargesLimit), WalletAggregate.name(id))
You can’t perform that action at this time.