以核心域开始开发——自动售货机模型。首先创建Spring boot项目:
- 点击链接
Spring Initializer。 - 选择
Gradle Project->Java->Spring boot版本2.4.4。 group name为com.lugew,artifact name为spring-boot-ddd。- 添加三个依赖
JPA、RestRepositories和H2。 - 点击生成并导入。
如图:
之后自动生成。项目结构如图:
生成代码如下:
package com.lugew.springbootddd;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class SpringBootDddApplication {public static void main(String[] args) {SpringApplication.run(SpringBootDddApplication.class, args);}}
build.gradle
plugins {id 'org.springframework.boot' version '2.4.3'id 'io.spring.dependency-management' version '1.0.11.RELEASE'}ext {guavaVersion = "30.0-jre"spockVersion = "2.0-M4-groovy-3.0"groovyVersion = "3.0.6"lombokVersion = "1.18.16"openapiVersion = "1.5.2"byteBuddyVersion = "1.10.19"objenesisVersion = "3.1"}apply plugin: 'java'apply plugin: 'idea'apply plugin: 'java-library'group = 'com.lugew'version = '0.0.1-SNAPSHOT'sourceCompatibility = '11'targetCompatibility = '11'repositories {mavenLocal()maven {name '阿里云'url 'https://maven.aliyun.com/repository/public/'}mavenCentral()google()}test {useJUnitPlatform()}apply plugin: 'groovy'apply plugin: 'org.springframework.boot'apply plugin: 'io.spring.dependency-management'apply plugin: 'maven'dependencies {implementation("com.google.guava:guava:${guavaVersion}",'org.springframework.boot:spring-boot-starter',"org.springframework.boot:spring-boot-starter-web","org.springframework.boot:spring-boot-starter-data-jpa",)runtimeOnly("com.h2database:h2")compileOnly("org.projectlombok:lombok:${lombokVersion}")annotationProcessor("org.springframework.boot:spring-boot-configuration-processor","org.projectlombok:lombok:${lombokVersion}")testImplementation("org.codehaus.groovy:groovy-all:${groovyVersion}","org.codehaus.groovy:groovy:${groovyVersion}","org.spockframework:spock-core:${spockVersion}","net.bytebuddy:byte-buddy:${byteBuddyVersion}","org.objenesis:objenesis:${objenesisVersion}",)}
setting.gradle:
rootProject.name = 'spring-boot-ddd'
随后在springbootdd目录下创建snackmachine目录:
snackmachine下创建SnackMachine类:
package com.lugew.springbootddd.snackmachine;import lombok.Getter;import lombok.Setter;@Getter@Setterpublic final class SnackMachine {private int oneCentCount;private int tenCentCount;private int quarterCount;private int oneDollarCount;private int fiveDollarCount;private int twentyDollarCount;public void insertMoney(int oneCentCount,int tenCentCount,int quarterCount,int oneDollarCount,int fiveDollarCount,int twentyDollarCount) {oneCentCount += oneCentCount;tenCentCount += tenCentCount;quarterCount += quarterCount;oneDollarCount += oneDollarCount;fiveDollarCount += fiveDollarCount;twentyDollarCount += twentyDollarCount;}public void returnMoney() {}}
👆注意,此类使用final修饰符限定。我们使用字段记录当前售货机金额,并且引入insertMoney投币、returnMoney退币、buySnack购买零食功能。对SnackMachine类进一步改造:
package com.lugew.springbootddd.snackmachine;import lombok.Getter;import lombok.Setter;@Getter@Setterpublic final class SnackMachine {private int oneCentCount;private int tenCentCount;private int quarterCount;private int oneDollarCount;private int fiveDollarCount;private int twentyDollarCount;private int oneCentCountInTransaction = 0;private int tenCentCountInTransaction = 0;private int quarterCountInTransaction = 0;private int oneDollarCountInTransaction = 0;private int fiveDollarCountInTransaction = 0;private int twentyDollarCountInTransaction = 0;public void insertMoney(int oneCentCount,int tenCentCount,int quarterCount,int oneDollarCount,int fiveDollarCount,int twentyDollarCount) {oneCentCountInTransaction += oneCentCount;tenCentCountInTransaction += tenCentCount;quarterCountInTransaction += quarterCount;oneDollarCountInTransaction += oneDollarCount;fiveDollarCountInTransaction += fiveDollarCount;twentyDollarCountInTransaction += twentyDollarCount;}public void returnMoney() {oneCentCountInTransaction = 0;tenCentCountInTransaction = 0;quarterCountInTransaction = 0;oneDollarCountInTransaction = 0;fiveDollarCountInTransaction = 0;twentyDollarCountInTransaction = 0;}public void buySnack() {oneCentCount += oneCentCountInTransaction;tenCentCount += tenCentCountInTransaction;quarterCount += quarterCountInTransaction;oneDollarCount += oneDollarCountInTransaction;fiveDollarCount += fiveDollarCountInTransaction;twentyDollarCount += twentyDollarCountInTransaction;oneCentCountInTransaction = 0;tenCentCountInTransaction = 0;quarterCountInTransaction = 0;oneDollarCountInTransaction = 0;fiveDollarCountInTransaction = 0;twentyDollarCountInTransaction = 0;}}
InTransaction字段表示用户投币,当用户购买零食时,用户投币将被累加到机器账户,投币也将被清零。零食机的基本功能实现如上,在此基础上我们可以做进一步的改进,比如,我们可以将金额字段抽象于一个类Money中:
package com.lugew.springbootddd.snackmachine;public class Money {private int oneCentCount;private int tenCentCount;private int quarterCount;private int oneDollarCount;private int fiveDollarCount;private int twentyDollarCount;public Money(int oneCentCount, int tenCentCount, int quarterCount, intoneDollarCount, int fiveDollarCount, int twentyDollarCount) {this.oneCentCount = oneCentCount;this.tenCentCount = tenCentCount;this.quarterCount = quarterCount;this.oneDollarCount = oneDollarCount;this.fiveDollarCount = fiveDollarCount;this.twentyDollarCount = twentyDollarCount;}public static Money add(Money money1, Money money2) {return new Money(money1.oneCentCount + money2.oneCentCount,money1.tenCentCount + money2.tenCentCount,money1.quarterCount + money2.quarterCount,money1.oneDollarCount + money2.oneDollarCount,money1.fiveDollarCount + money2.fiveDollarCount,money1.twentyDollarCount + money2.twentyDollarCount);}}
不仅如此,Money类还内聚了add加法功能,从而SnackMachine类可以进一步简化:
package com.lugew.springbootddd.snackmachine;import lombok.Getter;import lombok.Setter;@Getter@Setterpublic final class SnackMachine {private Money moneyInside;private Money moneyInTransaction;public void insertMoney(Money money) {moneyInTransaction = Money.add(moneyInTransaction, money);}public void returnMoney() {//moneyInTransaction = 0}public void buySnack() {moneyInside = Money.add(moneyInside, moneyInTransaction);//moneyInTransaction = 0}}
👆可以看到SnackMachine更加精简了。
