为了简单起见,我们只使用静态页面——HTML和JavaScript。我们构建SnackMachineView页面:

    1. <html lang="en">
    2. <head><title>snackMachine</title></head>
    3. <body>
    4. <table style="width:100%">
    5. <tbody>
    6. <tr>
    7. <td>
    8. <button id="btnBuy">Buy a Snack</button>
    9. </td>
    10. </tr>
    11. <tr>
    12. </tr>
    13. </tbody>
    14. </table>
    15. <br>
    16. <br>
    17. <br>
    18. <span>Money inserted :$<span id="moneyInserted">0</span></span>
    19. <br>
    20. <table style="width:100%">
    21. <tbody>
    22. <tr>
    23. <td>
    24. <button id="btnInsertCent">Insert 1 cent coin</button>
    25. </td>
    26. <td>
    27. <button id="btnInsertTenCent">Insert 10 cent coin</button>
    28. </td>
    29. <td>
    30. <button id="btnInsertQuarter">Insert 25 cent coin</button>
    31. </td>
    32. </tr>
    33. <tr>
    34. <td>
    35. <button id="btnInsertDollar">Insert 1 dollar note</button>
    36. </td>
    37. <td>
    38. <button id="btnInsertFiveDollar">Insert 5 dollar note</button>
    39. </td>
    40. <td>
    41. <button id="btnInsertTwentyDollar">Insert 20 dollar
    42. note
    43. </button>
    44. </td>
    45. </tr>
    46. </tbody>
    47. </table>
    48. <br>
    49. <br>
    50. <br>
    51. <button id="btnReturnMoney">Return Money</button>
    52. <br>
    53. <br>
    54. <br>
    55. <br>
    56. <br>
    57. <br>
    58. <br>
    59. <br>
    60. <br>
    61. Number of coins and Notes in SnackMachine
    62. <table style="width:100%">
    63. <tbody>
    64. <tr>
    65. <td>No. of 1 cent coin : <span id="cent">0</span></td>
    66. <td>No. of 10 cent coin : <span id="tenCent">0</span></td>
    67. <td>No. of 25 cent coin : <span id="quarter">0</span></td>
    68. </tr>
    69. <tr>
    70. <td>No. of 1 dollar note : <span id="dollar">0</span></td>
    71. <td>No. of 5 dollar note : <span id="fiveDollar">2</span></td>
    72. <td>No. of 20 dollar note : <span id="twentyDollar">0</span></td>
    73. </tr>
    74. </tbody>
    75. </table>
    76. <script src="../common/jquery-3.6.0.min.js"></script>
    77. <script src="snackMachine.js"></script>
    78. </body>
    79. </html>

    效果:
    image.png
    image.png
    同时我们增加Controller:

    1. package com.lugew.springbootddd;
    2. import com.lugew.springbootddd.snackmachine.SnackMachine;
    3. import org.springframework.web.bind.annotation.RequestMapping;
    4. import org.springframework.web.bind.annotation.RestController;
    5. /**
    6. * @author 夏露桂
    7. * @since 2021/6/10 11:55
    8. */
    9. @RestController
    10. @RequestMapping("snackmachines")
    11. public class SnackMachineController {
    12. static SnackMachine snackMachine = new SnackMachine();
    13. }

    我们以静态字段SnackMachine表示售货机对象,后期引入数据库之后我们将重构。同时为了将实体传输到页面UI,我们增加SnackMachineDto类:

    1. package com.lugew.springbootddd;
    2. import com.lugew.springbootddd.snackmachine.Money;
    3. import lombok.Getter;
    4. import lombok.Setter;
    5. /**
    6. * @author 夏露桂
    7. * @since 2021/6/10 12:00
    8. */
    9. @Getter
    10. @Setter
    11. public class SnackMachineDto {
    12. private Money moneyInside;
    13. private Money moneyInTransaction;
    14. private long id;
    15. }

    为SnackMachine添加转换方法:

    1. package com.lugew.springbootddd.snackmachine;
    2. import com.lugew.springbootddd.Entity;
    3. import com.lugew.springbootddd.SnackMachineDto;
    4. import lombok.Getter;
    5. import lombok.Setter;
    6. import java.util.Arrays;
    7. import static com.lugew.springbootddd.snackmachine.Money.None;
    8. @Getter
    9. @Setter
    10. public final class SnackMachine extends Entity {
    11. private Money moneyInside;
    12. private Money moneyInTransaction;
    13. public SnackMachine() {
    14. moneyInside = None;
    15. moneyInTransaction = None;
    16. }
    17. public void insertMoney(Money money) {
    18. Money[] coinsAndNotes = {Money.Cent, Money.TenCent, Money.Quarter,
    19. Money.Dollar, Money.FiveDollar,
    20. Money.TwentyDollar};
    21. if (!Arrays.asList(coinsAndNotes).contains(money))
    22. throw new IllegalStateException();
    23. moneyInTransaction = Money.add(moneyInTransaction, money);
    24. }
    25. public void returnMoney() {
    26. moneyInTransaction = None;
    27. }
    28. public void buySnack() {
    29. moneyInside = Money.add(moneyInside, moneyInTransaction);
    30. moneyInTransaction = None;
    31. }
    32. public SnackMachineDto convertToSnackMachineDto() {
    33. SnackMachineDto snackMachineDto = new SnackMachineDto();
    34. snackMachineDto.setId(getId());
    35. snackMachineDto.setMoneyInside(getMoneyInside());
    36. snackMachineDto.setMoneyInTransaction(getMoneyInTransaction());
    37. return snackMachineDto;
    38. }
    39. }

    SnackMachineContoller添加接口:

    1. package com.lugew.springbootddd;
    2. import com.lugew.springbootddd.snackmachine.SnackMachine;
    3. import org.springframework.web.bind.annotation.GetMapping;
    4. import org.springframework.web.bind.annotation.PathVariable;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import org.springframework.web.bind.annotation.RestController;
    7. /**
    8. * @author 夏露桂
    9. * @since 2021/6/10 11:55
    10. */
    11. @RestController
    12. @RequestMapping("snackmachines")
    13. public class SnackMachineController {
    14. static SnackMachine snackMachine = new SnackMachine();
    15. @GetMapping("{id}")
    16. public SnackMachineDto getSnackMachine(@PathVariable("id") long id) {
    17. return snackMachine.convertToSnackMachineDto();
    18. }
    19. }

    同时,snackMachine.js加入以下代码:

    1. const rootURI = "http://localhost:23333/snackmachines/1";
    2. getSnackMachine();
    3. function getSnackMachine() {
    4. $.get(rootURI, function (data, status) {
    5. $('#moneyInserted').html(data.moneyInTransaction.amount);
    6. $('#cent').html(data.oneCentCount);
    7. $('#tenCent').html(data.tenCentCount);
    8. $('#quarter').html(data.quarterCount);
    9. $('#dollar').html(data.oneDollarCount);
    10. $('#fiveDollar').html(data.fiveDollarCount);
    11. $('#twentyDollar').html(data.twentyDollarCount);
    12. });
    13. }

    此时页面
    image.png
    image.png
    是可以正常接收到请求的,但是页面按钮无效,接下来为insert按钮增加事件:

    1. const rootURI = "http://localhost:23333/snackmachines/1";
    2. getSnackMachine();
    3. function getSnackMachine() {
    4. $.get(rootURI, function (data, status) {
    5. $('#moneyInserted').html(data.moneyInTransaction.amount);
    6. $('#cent').html(data.oneCentCount);
    7. $('#tenCent').html(data.tenCentCount);
    8. $('#quarter').html(data.quarterCount);
    9. $('#dollar').html(data.oneDollarCount);
    10. $('#fiveDollar').html(data.fiveDollarCount);
    11. $('#twentyDollar').html(data.twentyDollarCount);
    12. });
    13. }
    14. $("button").click(function () {
    15. switch (this.id) {
    16. case "btnInsertCent" :
    17. insert("Cent")
    18. break;
    19. case "btnInsertTenCent" :
    20. insert("TenCent")
    21. break;
    22. case "btnInsertQuarter" :
    23. insert("Quarter")
    24. break;
    25. case "btnInsertDollar" :
    26. insert("Dollar")
    27. break;
    28. case "btnInsertFiveDollar" :
    29. insert("FiveDollar")
    30. break;
    31. case "btnInsertTwentyDollar" :
    32. insert("TwentyDollar")
    33. break
    34. default :
    35. break;
    36. }
    37. });
    38. function insert(coinOrNote) {
    39. $.ajax({
    40. url: rootURI + '/moneyInTransaction/' + coinOrNote,
    41. type: 'PUT',
    42. success: function (result) {
    43. // Do something with the result
    44. }
    45. });
    46. location.reload();
    47. }
    1. package com.lugew.springbootddd;
    2. import com.lugew.springbootddd.snackmachine.SnackMachine;
    3. import org.springframework.web.bind.annotation.*;
    4. import static com.lugew.springbootddd.snackmachine.Money.*;
    5. /**
    6. * @author 夏露桂
    7. * @since 2021/6/10 11:55
    8. */
    9. @RestController
    10. @RequestMapping("snackmachines")
    11. public class SnackMachineController {
    12. static SnackMachine snackMachine = new SnackMachine();
    13. @GetMapping("{id}")
    14. public SnackMachineDto getSnackMachine(@PathVariable("id") long id) {
    15. return snackMachine.convertToSnackMachineDto();
    16. }
    17. @PutMapping("{id}/moneyInTransaction/{coinOrNote}")
    18. public void inserMoney(@PathVariable("id") long id, @PathVariable("coinOrNote") String coinOrNote) {
    19. if (coinOrNote.equalsIgnoreCase("Cent")) snackMachine.insertMoney(Cent);
    20. else if (coinOrNote.equalsIgnoreCase("TenCent"))
    21. snackMachine.insertMoney(TenCent);
    22. else if (coinOrNote.equalsIgnoreCase("Quarter"))
    23. snackMachine.insertMoney(Quarter);
    24. else if (coinOrNote.equalsIgnoreCase("Dollar"))
    25. snackMachine.insertMoney(Dollar);
    26. else if (coinOrNote.equalsIgnoreCase("FiveDollar"))
    27. snackMachine.insertMoney(FiveDollar);
    28. else if (coinOrNote.equalsIgnoreCase("TwentyDollar"))
    29. snackMachine.insertMoney(TwentyDollar);
    30. }
    31. }

    此时,我们可以在页面验证投币功能:
    image.png
    接下来我们完善退币和购买功能:

    1. @PutMapping("/{id}/moneyInTransaction")
    2. public void returnMoney(@PathVariable("id") long id) {
    3. snackMachine.returnMoney();
    4. }
    5. @PutMapping("/{id}/{slotNumber}")
    6. public void buySnack(@PathVariable("id") long id, @PathVariable("slotNumber")
    7. int slotNumber) {
    8. snackMachine.buySnack();
    9. }
    1. const rootURI = "http://localhost:23333/snackmachines/1";
    2. getSnackMachine();
    3. function getSnackMachine() {
    4. $.get(rootURI, function (data, status) {
    5. $('#moneyInserted').html(data.moneyInTransaction.amount);
    6. $('#cent').html(data.moneyInside.oneCentCount);
    7. $('#tenCent').html(data.moneyInside.tenCentCount);
    8. $('#quarter').html(data.moneyInside.quarterCount);
    9. $('#dollar').html(data.moneyInside.oneDollarCount);
    10. $('#fiveDollar').html(data.moneyInside.fiveDollarCount);
    11. $('#twentyDollar').html(data.moneyInside.twentyDollarCount);
    12. });
    13. }
    14. $("button").click(function () {
    15. switch (this.id) {
    16. case "btnInsertCent" :
    17. insert("Cent")
    18. break;
    19. case "btnInsertTenCent" :
    20. insert("TenCent")
    21. break;
    22. case "btnInsertQuarter" :
    23. insert("Quarter")
    24. break;
    25. case "btnInsertDollar" :
    26. insert("Dollar")
    27. break;
    28. case "btnInsertFiveDollar" :
    29. insert("FiveDollar")
    30. break;
    31. case "btnInsertTwentyDollar" :
    32. insert("TwentyDollar")
    33. break;
    34. case "btnReturnMoney" :
    35. returnMoney()
    36. break;
    37. case "btnBuy" :
    38. buy("1")
    39. break;
    40. default :
    41. break;
    42. }
    43. });
    44. function insert(coinOrNote) {
    45. $.ajax({
    46. url: rootURI + '/moneyInTransaction/' + coinOrNote,
    47. type: 'PUT',
    48. success: function (result) {
    49. // Do something with the result
    50. }
    51. });
    52. location.reload();
    53. }
    54. function returnMoney() {
    55. $.ajax({
    56. url: rootURI + '/moneyInTransaction',
    57. type: 'PUT',
    58. success: function (result) {
    59. // Do something with the result
    60. }
    61. });
    62. location.reload();
    63. }
    64. function buy(position) {
    65. $.ajax({
    66. url: rootURI + '/' + position,
    67. type: 'PUT',
    68. success: function (result) {
    69. }
    70. });
    71. location.reload();
    72. }

    上述几个方法中一些参数目前是无效的,作为后期使用。insertMoney方法中的参数只能是标准币值,所以将之更名为insertCoinOrNote