Upgrade to Pro — share decks privately, control downloads, hide ads and more …

フロントエンドはDDDの夢を見るか

yukieen
March 05, 2016

 フロントエンドはDDDの夢を見るか

yukieen

March 05, 2016
Tweet

Other Decks in Technology

Transcript

  1. ࢯ໊υϝΠϯϞσϧ public class PersonName {
 FirstName firstName = new FirstName();


    LastName lastName = new LastName();
 
 public FirstName getFirstName() {
 return firstName;
 }
 
 public LastName getLastName() {
 return lastName;
 }
 }
  2. <head>
 <title>ձһ৘ใ</title>
 </head>
 <body th:with="member = ${member}">
 <section th:with="resume =

    ${member.resume}">
 <h1>Ϩδϡϝ৘ใ</h1>
 <section th:with="profile = ${resume.profile}">
 <h2>ϓϩϑΟʔϧ</h2>
 <section th:with="personName = ${profile. personName}">
 <h3>ࢯ໊</h3>
 <span th:text=“${personName.lastName.value}”> </span>
 <span th:text=“${personName.firstName.value}”> </span>
 </section>
 </section>
 </section>
 </body> ը໘ʹެ։͞ΕΔߏ଄)5.-ͷΞ΢τϥΠϯߏ଄ ઌ΄ͲͷαϯϓϧίʔυΛ ۃ୺ʹॻ͖௚͢ͱ͜͏ͳΔ
  3. )5.-ͷΞ΢τϥΠϯߏ଄ʹӨڹ͠ͳ͍෦෼͸Ӆṭ͢Δ <head>
 <title>ձһ৘ใ</title>
 </head>
 <body th:with="member = ${member}">
 <section th:with="resume

    = ${member.resume}">
 <h1>Ϩδϡϝ৘ใ</h1>
 <section th:with="profile = ${resume.profile}">
 <h2>ϓϩϑΟʔϧ</h2>
 <section th:with="personName = ${profile. personName}">
 <h3>ࢯ໊</h3>
 <span th:text=“${personName.lastName.value}”> </span>
 <span th:text=“${personName.firstName.value}”> </span>
 </section>
 </section>
 </section>
 </body>
  4. ࢯ໊υϝΠϯϞσϧͷมߋ public class PersonName {
 FirstName firstName = new FirstName();


    LastName lastName = new LastName();
 
 public String getFirstName() {
 return firstName.value;
 }
 
 public String getLastName() {
 return lastName.value;
 }
 }
  5. ͞Βʹ)5.-ͷΞ΢τϥΠϯߏ଄ʹӨڹ͠ͳ͍෦෼͸Ӆṭ͢Δ <head>
 <title>ձһ৘ใ</title>
 </head>
 <body th:with="member = ${member}">
 <section th:with="resume

    = ${member.resume}">
 <h1>Ϩδϡϝ৘ใ</h1>
 <section th:with="profile = ${resume.profile}">
 <h2>ϓϩϑΟʔϧ</h2>
 <section th:with="personName = ${profile. personName}">
 <h3>ࢯ໊</h3>
 <span th:text=“${personName.lastName.value}”> </span>
 <span th:text=“${personName.firstName.value}”> </span> <span th:text=“${personName.fullName}”> </span>
 </section>
 </section>
 </section>
 </body>
  6. ࢯ໊υϝΠϯϞσϧͷมߋ public class PersonName {
 FirstName firstName = new FirstName();


    LastName lastName = new LastName();
 
 public String getFullName() {
 return String.format("%s %s", firstName.value, lastName.value);
 }
 }
  7. ٻਓҰཡυϝΠϯϞσϧ public class Offers {
 List<Offer> values = new ArrayList<>();


    
 public boolean isEmpty() {
 return values.isEmpty();
 }
 } <div th:if=“${offers.empty}">
 <div class="empty-message"> ࢦఆ͞Εͨ৚݅ʹ֘౰͢Δٻਓ৘ใ͸͋Γ·ͤΜɻ </div> </div> ٻਓҰཡը໘
  8. ٻਓυϝΠϯϞσϧ public class Offer {
 LocalDate createDate;
 
 public boolean

    isNewArrival() {
 return createDate.until(LocalDate.now(), ChronoUnit.DAYS) <= 7;
 }
 } <span th:if="${offer.newArrival}" class=“new- offer-label“>৽ண!</span> ٻਓը໘
  9. .search-result_header {
 display: block;
 padding: 1.2rem 1.0rem;
 border: 1px solid

    #c7c7c7;
 font-size: 1.2rem;
 }
 
 .search-result_header--offer {
 @extend .search-result_header;
 background-color: #FFF4C3;
 }
 
 .search-result_header--agency {
 @extend .search-result_header;
 background-color: #D4E1F5;
 }
 
 .search-result_header--adviser {
 @extend .search-result_header;
 background-color: #FCDAE6;
 } 検索結果ヘッダは基本的にこの ルールセットを適⽤するよ = Structure ドメインごとにそれぞれのルー ルセットを適⽤するよ = Skin
  10. ͜ΕΛ4USVDUVSFͱ4LJOʹ෼͚Δͱ w #BTF w -BZPVU w .PEVMF w 4UBUF w

    5IFNF 4USVDUVSFجຊͱͳΔߏ଄΍ମࡋ 4LJOݟͨ໨ɻυϝΠϯΛදݱͰ͖Δ෦෼
  11. .PEVMFυϝΠϯΛ.PEJpFSͰදݱ͢Δ .search-result_header {
 display: block;
 padding: 1.2rem 1.0rem;
 border: 1px

    solid #c7c7c7;
 font-size: 1.2rem;
 }
 
 .search-result_header--offer {
 @extend .search-result_header;
 background-color: #FFF4C3;
 }
 
 .search-result_header--agency {
 @extend .search-result_header;
 background-color: #D4E1F5;
 }
 
 .search-result_header--adviser {
 @extend .search-result_header;
 background-color: #FCDAE6;
 }
  12. ྫʣදࣔʗඇදࣔΛυϝΠϯϞσϧͰ੍ޚ͢Δ public class Offers {
 List<Offer> values = new ArrayList<>();


    
 public String getVisibleAsStyleClass() {
 return values.isEmpty() ? "hide" : "";
 }
 }
  13. ͓·͚ தԝدͤΊͬͪΌ͠ΜͲ͍ʂʂʂ text-align: center
 overflow: hidden
 display: -webkit-box
 display: -moz-box


    display: -ms-flexbox
 display: -webkit-flex
 display: flex
 -webkit-box-pack: center
 -moz-box-pack: center
 -ms-flex-pack: center
 -webkit-justify-content: center
 justify-content: center
 -webkit-box-align: center
 -moz-box-align: center
 -ms-flex-align: center
 -webkit-align-items: center
 align-items: center
  14. બ୒ର৅ͷ৬छϞσϧʢ+BWB4DSJQUʣ var JobTitle = function (code, name, categoryIndex) {
 this.code

    = code;
 this.name = name;
 this.categoryIndex = categoryIndex;
 };

  15. ৬छબ୒ϏϡʔϞσϧʢ+BWB4DSJQUʣ var JobTitleSelector = function (initialJobTitles) {
 
 this.selectedJobTitles =

    ko.observableArray(createJobTitles(initialJobTitles));
 
 var createJobTitles = function (initialJobTitles) {
 return _.map(initialJobTitles, function (jobTitle) {
 return new JobTitle(
 jobTitle.code,
 jobTitle.name,
 jobTitle.categoryIndex);
 });
 };
 
 this.selectedJobTitleCodes = function () {
 // selectedJobTitles͔ΒίʔυͷΈநग़͢Δ
 };
 
 this.checkInCategory = function (categoryIndex) {
 // ΧςΰϦʔ഑ԼΛ͢΂ͯνΣοΫ͢Δ
 };
 
 this.isAllCheckedInCategory = function (categoryIndex) {
 // ΧςΰϦʔ഑Լ͕͢΂ͯνΣοΫ͞Ε͍ͯΔ͔൑ఆ͢Δ
 };
 }; コンストラクタで受け取った ドメインモデルを元に職種モ デルを⽣成する
  16. ৬छબ୒ϏϡʔϞσϧੜ੒࣌ʹυϝΠϯϞσϧΛ౉͢ 
 <script th:inline=“javascript"> // ུʢϏϡʔϞσϧͷఆٛʣ var initialJobTitles = /*[[${jobTitles}]]*/

    [];
 var viewModel = new JobTitleSelector(initialJobTitles);
 ko.applyBindings(viewModel); </script> Thymeleafのインライン機能を使う と、ドメインモデルがJSON形式で 出⼒される
  17. νΣοΫϘοΫεͱͷόΠϯυ <input type="checkbox" ɹdata-bind="checked: isAllCheckedInCategory(1), click:checkInCategory.bind($data,1)"> اըɾࣄ຿
 <ul>
 <li> ɹɹɹɹ<input

    type="checkbox" ɹɹɹɹɹɹɹɹdata-bind="value:selectedJobTitleCodes"> ɹɹɹɹҰൠࣄ຿ ɹɹ</li>
 <li> ɹɹɹɹ<input type="checkbox" ɹɹɹɹɹɹɹɹdata-bind="value:selectedJobTitleCodes"> ૯຿ </li>
 </ul>
  18. ৬छυϝΠϯϞσϧʢαʔόʔαΠυʣ public class JobTitle {
 Code code = new Code();


    Name name = new Name();
 CategoryIndex categoryIndex = new CategoryIndex();
 
 public String getCode() {
 return code.value;
 }
 
 public String getName() {
 return name.value;
 }
 
 public Integer getCategoryIndex() {
 return categoryIndex.value;
 }
 }
  19. var JobTitleSelector = function (initialJobTitles) {
 
 this.selectedJobTitles = ko.observableArray(createJobTitles(initialJobTitles));


    
 var createJobTitles = function (initialJobTitles) {
 return _.map(initialJobTitles, function (jobTitle) {
 return new JobTitle(
 jobTitle.code,
 jobTitle.name,
 jobTitle.categoryIndex);
 });
 };
 
 this.clearAll = function () {
 // ͢΂ͯͷબ୒ঢ়ଶΛΫϦΞ͢Δ
 };
 
 this.checkInCategory = function (categoryIndex) {
 // ΧςΰϦʔ഑ԼΛ͢΂ͯνΣοΫ͢Δ
 };
 
 this.isAllCheckedInCategory = function (categoryIndex) {
 // ΧςΰϦʔ഑Լ͕͢΂ͯνΣοΫ͞Ε͍ͯΔ͔൑ఆ͢Δ
 };
 }; 「職種を⼊⼒する」という関⼼事 はここに凝集できて嬉しい! Ͱ΋ɺ,OPDLPVUKTͷϏϡʔϞσϧΛ࢖͏ͱ