Author Archives: pkhamdee

Unknown's avatar

About pkhamdee

Craft IT strategies to drive IT transformation and engineering of cloud-native architecture in cloud computing to build software that people love and rely on.

Software Development Strategy

Software Development Team ต่างมี Process ในการ Develop Application ที่แตกต่างกันไปตามขนาดของทีม และความซับซ้อนของ Application แต่สิ่งหนึ่งที่เป็นมาตรฐานที่ใช้กันทั่วไปก็คือ Agile โดยมีการแบ่งงานออกมาเป็นงานย่อยๆ และทะยอย Deliver ทีละส่วน (Iteration) focus ปัญหาเฉพาะอย่าง ทำให้การพัฒนาทำได้ง่าย มีประสิทธิภาพ และคาดการณ์ในการส่งมอบได้แม่นยำกว่าการพัฒนาทั้งหมดให้เสร็จในทีเดียว (water-fall) จะว่าไปแล้วการนำหลัก Agile มาใช้ก็ควรจะส่งผลดีต่อทีมในการ Deliver Software แต่ก็ไม่ใช่ทุกทีมจะ Success เนื่องจากไม่มีประสบการณ์ และมองภาพแค่การแบ่งงานออกเป็นชิ้นย่อยๆ การนำ Agile มาใช้เป็นแค่ปลายทางของ Process เท่านั้น จำเป็นต้องมี Process อื่นร่วมด้วยเช่น Design Thinking และ Lean โดยสรุปได้ดังภาพ

กระบวนการ Design Thinking เป็นขั้นตอนที่ทำให้เราเข้าใจปัญหา โดย Focus ที่ทำไมถึงเกิดปัญหาขึ้น (WHY) ด้วยกระบวนการ Discovery จาก Group session กับผู้ที่เกี่ยวข้องทั้งหมด การพูดคุยกับ user (user interview) จาก code และวิเคราะห์จากข้อมูลต่างๆ ซึ่งผลลัพธ์ก็จะได้ปัญหาย่อยๆ หลายปัญหาก็เป็นได้ แต่ก็ต้องทำการ priority ว่า ปัญหาอะไรควรจะหยิบมาเข้ากระบวนการก่อนหลัง

หลังจากนั้นก็จะเข้ากระบวนการหาวิธีเพื่อที่จะแก้ปัญหาจากสมมุติฐานต่างๆ ด้วยการสร้างต้นแบบ (prototype) และประเมินผล รวมถึงปรับปรุง prototype เพื่อให้มั่นใจว่าเป็นทางเลือกที่ดีที่สุดในการแก้ปัญหานั้นๆ จนออกมาเป็น MVP (Minimum Viable Product) เพื่อนำเข้าสู่การพัฒนา เป็นกระบวนการ Lean Methodology (WHAT) ที่จะได้ Product ที่ถูกต้องสำหรับปัญหานั้นๆ (build the right thing)

หลังจากนั้นถ้ามีเรื่องอื่นๆ อีกก็ต้องกลับไปทำกระบวนการ Design Thinking สร้างสมมุติฐานและสร้าง Prototype วน Loop แบบนี้เรื่อยๆ เพื่อให้สามารถสร้าง Product backlog ในกระบวนการ Agile ได้

ขั้นตอนสุดท้ายถึงจะเป็น Agile คือการแบ่งงานออกมาเป็นส่วนย่อยๆ (Product backlog) ทำการ Develop และ Deliver เพื่อให้เสร็จแต่ละรอบภายใน 1-2 สัปดาห์ (Sprint) ถ้าใช้เวลามากกว่านี้ต้องทำการแบ่งงานให้ย่อยลงไปอีก ซึ่งประสิทธิภาพของการพัฒนาในแต่ละรอบ (Iteration) ขึ้นอยู่กับคุณภาพของ Product backlog และความซับซ้อนของแต่ละ Features เพื่อที่จะทำให้สามารถทำงานได้จริง และง่ายต่อการใช้ ซึ่งก็คือการสร้าง Software ด้วยวิธีการที่ถูกต้อง (build the thing the right way)

รายละเอียดของแต่ละช่วงเวลา และ Practice ที่ใช้

Ref: https://tanzu.vmware.com/agile

DevOps Framework

กระบวนการ Deliver Software จาก Ideas จนถึงใช้งานบน Production ต้องผ่าน process อะไรบ้างเมื่อพิจารณากระบวนการ DevOps เข้ามาเกี่ยวข้อง สามารถสรุปเป็นแนวทางได้ดังนี้

เราควรมี Product Team ที่ประกอบด้วยผู้ที่เกี่ยวของกับการพัฒนา Product เช่น Product Owner, Designer และ Developer ทั้งนี้ทีมควรพิจารณาเรื่อง Balance Team ที่ต้องมีผู้ที่เกี่ยวข้องกับการพัฒนาและส่งมอบ Product อยู่ในทีม เพื่อให้การดำเนินการใดๆ สามารถทำได้เลย ไม่ต้องเสียเวลาในการขอความร่วมมือใดๆ ข้าม Team เช่นการมี Security และ Operation อยู่ใน Team ด้วย จะทำให้ทุกคนเข้าใจใน Product ที่กำลังพัฒนา การตัดสินใจ การร่วมไม้ร่วมมือตั้งแต่ต้น และตลอดการพัฒนา โดยใช้หลักการ Why (ทำไมเราต้องพัฒนา) What (ส่ิงที่ต้องพัฒนาคืออะไร) How (จะพัฒนาขึ้นมาได้ยังไง) เพื่อส่งเสริมความเข้าใจ และทำงานร่วมกันภายในทีม

เครื่องมือที่เกี่ยวข้อง

  • Portfolio Management
  • Application Lifecycle Management
  • Team Collaboration and Work Tracking (Jira)
  • Security Architecture and Design
  • Threat Modeling
  • Knowledge Sharing (Confluence)

สิ่งที่เป็น Output ของ Team คือ Source Code รวมถึง Application Code, Testing Code และ Infra Code จะถูกจัดการด้วย Code Repository (GitLab, GitHub, GitBucket) เพื่อให้สามารถจัดการเรื่อง Versioning และการ Peer Review กับผู้ที่เกี่ยวข้องได้ และต้องมีการจัดการเรื่อง Quality ของ Code เช่น จำนวน Test Coverage การ Follow ตาม Practice ของการเขียน Code เช่น Code Quality/Secure Coding Standards (SonarQube, Snyk) และมีการ Integrate Security Tool เพื่อตรวจสอบช่องโหว่ด้านความปลอดภัยในระดับ Code เช่น Open Source Security & License Tracking (BlackDuck, Snyk), Static Application Security Testing – SAST (Coverity, Fortify, SonarQube, Checkmarx, Veracode) เป็นต้น

เมื่อ Code ผ่านกระบวนการตรวจสอบแล้ว กระบวนการต่อไปคือการ Build (maven, npm, MSBuild) โดยจะได้ Binary File ที่สามารถทำงานได้ (Working Software) ทั้งนี้ขั้นตอนการ Build จะมีการเรียก Unit Test (junit, Nunit) และ Functional Test (Cucumber) หลังจากนั้นก็จะจัดเก็บ Binary File ไว้ใน Application Repository (jFrog, Nexus)

ถ้า Software จะต้องทำงานบน Container Platform ก็ต้อง Pack Binary File ไว้ใน Container Format (Containerize) ด้วยเครื่องมือ Container Build (Docker file, Buildpack) และจัดเก็บไว้ใน Container Registry (Habor, jForg, DockerHub) หลังจากนั้นจึงจะทำการสร้าง SBOM (Software Bill of Material) เพื่อเป็น metadata file อธิบายถึง ข้อมูล Components ต่างๆ ที่ใช้ในการสร้าง Software ขึ้นมา แล้วต่อด้วย Software Composite Analysis – SCA (Trivy, BlackDuck, Snyk, jFrog X-Ray) เพื่อหาช่องโหว่ด้านความปลอดภัยของ software components ต่างๆ ที่นำมาใช้

จากนั้นจะต้องมีการออก Release Number ของ Software เพื่อเป็น Reference ในระบบ Release Management ที่ประกอบด้วย Features หรือ Update ต่างๆ ของ Software Release และ Update ไปยังระบบ Work Tracking และทำการ Tag Release Version ใน Code Repository

หลังจากกระบวนการออก Release Version ของ Software เสร็จจะขึ้นอยู่กับการตกลงของทีม Delivery และ QA ที่จะนำ Software Release เข้าสู่กระบวนการทดสอบโดยทีม QA และ Security ที่ครอบคลุมทั้งที่เป็น Functional และ Non-Function Test โดยมีเครื่องมือ Quality Management และ Update ไปยัง Work Tracking

เครื่องมือที่ QA ใช้ในการทดสอบ Software เช่น

  • Katalon Studio
  • Selenium
  • Appium
  • Applitools
  • Blazemeter
  • Saucelabs
  • Smartbear
  • Wiremock

เครื่องมือสำหรับ Dynamic Application Security Test เช่น

  • Fortify
  • Aqua Sec
  • OWASP ZAP
  • Tanable Web App Scan

เครื่องมือในการทำ performance test เช่น

  • JMeter
  • Smartbear
  • Postman
  • Locust

การจะนำ software ที่ผ่านการทดสอบแล้วขึ้น production อาจจะมีกระบวนการ approval process และทำการ deploy ด้วยวิธีการที่เหมาะสมเช่น blue-green, cannary  หรือ a/b testing หลังจากนั้นอาจจะมีเครื่องมือสำหรับตรวจสอบความปลอดภัย เช่น Infra Valnerabilities (Tenable Nessus), Interactive application security testing – IAST (AquaSec, Twistlock, Synopsys Seeker) และ Chaos Testing (Chaos Monkey, Chaos Mash) เพื่อให้มั่นใจว่าระบบจะสามารถทำงานได้ในสถานการณ์ต่างๆ เช่น ช่วง peak time และบางส่วนของระบบมีปัญหา

สิ่งที่สำคัญที่ขาดไม่ได้คือ log, monitoring และเก็บข้อมูลสถิติต่างๆ (Metric Collection – Prometheus, InfluxDB) เพื่อนำมาใช้ในการปรับปรุงระบบ ให้ดีขึ้นเรื่อยๆ ด้วยการ Update ข้อมูลกลับไปยัง Product Team พิจารณาแก้ไขให้ดีขึ้น

เครื่องมือสำหรับ Log และ Monitoring เช่น

  • Datadog
  • Grafana
  • Appdynamic
  • Dynatrace
  • Splunk
  • Solarwind
  • Elastic Stack (EFK, ELK)

Technology Adoption Lifecycle – Crossing the Chasm

Implement ระบบ IT ด้วยการนำ technology ใหม่ๆ เช่น containerize หรือพวก cloud native application รวมถึงหลักการใหม่ๆ อย่าง DevSecOps ที่บางองค์กรก็ success คือได้ผลลัพธ์จริง และสามารถ transform หน่วยงานและองค์กรด้วยการใช้ technology ใหม่ๆ ได้ แต่บางองค์กรก็ยังไม่ได้เห็นผลที่ชัดเจนและระบบส่วนใหญ่ก็ยังเป็นในรูปแบบเดิมอยู่นั้น สามารถอธิบายได้ด้วย Crossing the Chasm ซึ่งเป็นหนังสือที่เขียนโดย Geoffrey A. Moore ที่เมื่อมี technology ใหม่ องค์กรก็จะพยายามที่จะ adopt และนำมาใช้

ในช่วงที่เป็น Early adopters ทีมเริ่มพัฒนาและ integrate งานส่วนใหม่ๆ เข้าไปเพื่อให้แก้ปัญหา และช่วยงานต่างๆ ในการพัฒนาสินค้าและบริการให้ดียิ่งขึ้น เช่นอาจจะเรียกให้ vendors เข้ามา deliver application ให้เป็น container หรือให้ทีมต้องพัฒนา application ในรูป container ให้ใด้เร็วที่สุด เพื่อประเมินผลลัพธ์

แต่การที่เราจะเห็นการใช้ technology นี้ใน scale ที่ใหญ่ขึ้น และใช้งานต่อเนื่อง หรือไปต่อกับ technlogy นั้นอาจจะต้องใช้เวลา และเจออุปสรรคที่ค่อนข้างเยอะ (challenges) เพราะเรามักจะมองว่าการข้ามจาก early adopters ไป fast followers จะเป็น journey ที่ต่อเนื่องเช่น phase1 ไป phase2 แต่ความเป็นจริงแล้วมันคือการข้ามหุบเหว (chasm) ที่ถ้าเราข้ามไปไม่ได้เราก็จะยังคงอยู่ใน phase1 หรือ Early adopters ต่อไป หรือไม่ก็ยกเลิก technology นี้ไปเลย

การจะข้าม Chasm นี้ได้มักจะเกี่ยวกับเรื่องของ learning หลักการ fail fast และแก้ปัญหา challenge ต่างๆ ที่ต้องอาศัย practice และ foundation ของระบบ IT ที่เอื้ออำนวยต่อการ scale และปรับเปลี่ยนได้เร็ว จึงจะทำให้อยู่ใน Fast followers ได้ ซึ่งถือเป็นจุดที่องค์กรได้ประโยชน์สูงสุดในการนำ technology ดังกล่าวมาใช้

ทั้งนี้ Technology ใดๆ ล้วนมี life cycle ของตัวเอง พอเมื่อถึงช่วงเวลาหนึ่งก็จะไม่สามารถที่จะแก้ปัญหา หรือตอบสนองต่อเรื่องใหม่ๆ ได้ หรือไม่ก็หยุดพัฒนา ก็จะเกิด technology ใหม่เข้ามาทำให้ต้องกลับไป Early adopters อีกครั้ง แต่การตัดสินใจก็มักจะต้องมีเหตุมีผลที่เพียงพอเพราะการไม่อยากเปลี่ยนแปลงอะไร เนื่องจาก technology เดิมก็ยังใช้งานได้ถึงแม้จะมีบางอย่างที่มีปัญหาบ้างก็สามารถแก้ปัญหาด้วย work around บางอย่างได้ การเปลี่ยนแปลงใดๆ ก็ตามต้องการ proven ก่อนค่อนข้างเยอะ ก่อนที่จะยอมรับเพื่อเข้าสู่ Early adopters ซึ่งช่วงนี้เรียกว่า Conservatives

แต่ละองค์กรที่มีการ adopt technology ใดๆ ก็จะมีช่วงเวลาของ technlogy เสมอ แต่สิ่งสำคัญที่สุดคือการข้ามหุบเหว (chasm) ที่ต้องอาศัยทั้ง culture, process การร่วมไม้ร่วมมือ เพื่อให้สามารถข้ามอุปสรรค์ต่างๆ ไปได้

Principles of Software Design

สรุป design software principle สำหรับเป็น guidelines เพื่อใช้ในการ design software ซึ่งโดยทั่วไปแล้ว pattern และ practices ก็เหมือนเครื่องเมื่อ (tools) เพื่อที่จะทำให้สามารถสร้าง software ที่มีคุณภาพ ตัวอย่างเช่น

  • KISS – Keep it simple, stupid ใช้หลักการออกแบบที่ง่าย ไม่ซับซ้อน จะทำให้ software ทำงานได้ดีกว่า
  • DRY – Don’t repeat yourself หลีกเลี่ยงการทำอะไรซ้ำๆ หรือมีส่ิงเดียวกันหลายๆ ที่ ทำให้แก้ไขลำบาก
  • YAGNI – You aren’t gonna need it ไม่ควรพัฒนาหรือเพิ่ม function ใดๆ จนกว่าจะเห็นว่าจำเป็นจริงๆ
  • SoC – Separation of concerns หลักการออกแบบ software เป็นลักษณะ modular ที่ทำงานใดงานหนึ่งสมบูรณ์ในตัวเอง
  • SOLID – Single responsibility, Open/Close, Liskov substitution, Interface segregation, Dependency inversion เป็นหลักการในการเขียน object-oriented programming (OOP) ที่จะทำให้ software มีโครงสร้างที่ดี และแก้ไขได้ง่าย

Single Responsibility Principle – หลักการออกแบบ Class

หลักการที่เรามีแค่เหตุผลเดียวในการสร้าง class ขึ้นมาเพื่อทำงานใดงานหนึ่ง ไม่ควรให้ class ที่สร้างขึ้นมาทำงานหลายหน้าที่ (responsibility) เช่นออกแบบ class เพื่อหาพื้นที่รวมของรูปทรงต่างๆ ก็ไม่ควรให้ class นี้จะต้องทำเรื่องการแสดงผล (output format) ที่ได้ออกมาในรูป html หรือ json เพราะจะทำให้ class นี้ถูกสร้างขึ้นมาด้วยเหตุผลมากกว่าหนึ่งเหตุผล หรือถูกใช้หรือ support เฉพาะบางกลุ่มหรือบาง role

Open Closed Principle – หลักการออกแบบ Interface

Object หรือ entities ต้องสามารถ extend ได้ แต่ต้องแก้ไขไม่ได้ เป็นหลักการที่ทำให้โครงสร้างของ code เดิมไม่กระทบเมื่อมี type หรือ object ที่แตกต่างออกไป เช่น การที่เรามี class สำหรับรวมพื้นรวมของรูปทรงสี่เหลี่ยม กับวงกลม ด้วย method sum() ถ้าเรามีสามเหลี่ยมเพิ่มขึ้นมาก็จะหลีกเลี่ยงการแก้ไข method เดิมไม่ได้ เราสามารถแก้ไขได้ด้วยการสร้าง interface shape โดยให้ type object ใดๆ สามารถ extend ไปเพื่อ implement logic หา area ตัวเอง ก็จะทำให้ mothod sum() ของเราก็ไม่ต้องแก้ไขอะไร เพื่อที่จะ support รูปทรงใหม่ๆ

interface ShapeInterface
{
    public function area();
}
class Square implements ShapeInterface
{
    // ...
}
class Circle implements ShapeInterface
{
    // ...
} 
class AreaCalculator
{
    // ...
    public function sum()
    {
        foreach ($this->shapes as $shape) {
            if (is_a($shape, 'ShapeInterface')) {
                $area[] = $shape->area();
                continue;
            }
            throw new AreaCalculatorInvalidShapeException();
        }
        return array_sum($area);
    }
}

Liskov Substitution – หลักการออกแบบ Inheritance

เป็นหลักการที่ object ของ supper class จะต้องสามารถแทนทีด้วย object ของ subclass ได้โดยที่ต้องไม่ส่งผลต่อ program และ object ของ subclass จะต้องสามารถ access ทุก method และ property ของ super class

public interface Bird{
    public void fly();
    public void walk();
}

public class Parrot implements Bird{
    public void fly(){ // to do}
    public void walk(){ // to do }
}// ok 

public class Penguin implements Bird{
    public void fly(){ // to do }
    public void walk(){ // to do }
}  // it's break the principle of LSP. Penguin can not fly.

จากตัวอย่าง code จะเห็นว่า subclass สามารถ access superclass ได้ แต่จะเห็นว่า penguin ที่เป็น subclass เข้ากันไม่ได้กับ superclass เพราะ penguin ไม่สามารถบินได้จึงผิดหลัก Liskov substitution

public interface Bird{
    // to do;
}

public interface FlyingBird extends Bird{
    public void fly(){}
}

public interface WalkingBird extends Bird{
    public void work(){}
}

public class Parrot  implements FlyingBird, WalkingBird {
    public void fly(){ // to do}
    public void walk(){ // to do }
}

public class Penguin implements WalkingBird{
    public void walk(){ // to do }

ถ้าเปลี่ยนใหม่ให้ penguin สือทอดจาก walkingbird ก็จะทำให้ถูกต้องตามหลักการ และไม่ส่งผมต่อ program ทำให้เกิด bug

Interface segregation – หลักการออกแบบ Polymorphism

code จะต้องไม่ถูกบังคับให้ implement หรือเกี่ยวพันกับ method ที่ไม่ได้ใช้ เช่นกรณีที่เรามี class interface ที่มี method คำนวณพื้นที่ และปริมาตรสามมิติ ซึ่งถ้า type ของสี่เหลี่ยมเป็น 2 มิติก็จะไม่สามารถ implement method คำนวณปริมาตรได้เป็นต้น

Dependency Inversion – หลักการออกแบบ Decoupling and Abstraction

หลักการในการจัดการ dependency ของสอง object ที่เมื่อถ้าต้องเปลี่ยนไปใช้ อีก object จะทำได้ง่ายๆ โดยไม่กระทบกับ code ด้วยวิธีการใช้ intermediate object เพื่อเชื่มระหว่างทั้งสอง object เข้าด้วยกัน แทนที่จะให้ทั้งสอง object มีการเรียกใช้กันตรงๆ

public class Book {

    void seeReviews() {
         ...
    }

    void readSample() {
         ...
    }
}


public class Shelf {

     Book book;

     void addBook(Book book) {
          ...
     }

     void customizeShelf() {
          ...
     }
}

ตัวอย่างนี้ถ้าเราสร้าง shelf ไว้เก็บหนังสือ (book) อนาคตถ้าต้องการเก็บ DVD ด้วยก็เลี่ยงไม่ได้ที่ต้องแก้ class shelf เพราะความสัมพันธ์ที่ขั้นตรงต่อกันของทั้งสอง object

public interface Product {

    void seeReviews();

    void getSample();

}

public class Book implements Product {

    @Override
    public void seeReviews() { 
          ...
    }

    @Override
    public void getSample() {
          ...
    }
}

public class DVD implements Product {

    @Override
    public void seeReviews() { 
         ...
    }

    @Override  
    public void getSample() {
          ...
    }
}


public class Shelf {

    Product product;

    void addProduct(Product product) {
          ...
    }

    void customizeShelf() {
          ...
    }
}

ถ้าไม่ต้องการให้ object มี dependency ต่อกันก็ต้องสร้าง intermediate object ขึ้นมา ตัวอย่างนี้คือ object product ซึ่งเป็น abstraction ของทั้งสอง object ทำให้อนาคตถ้ามี object ใหม่ๆ เกิดขึ้น ก็สามารถเพิ่มเข้า หรือลบออกได้ง่าย

บทความที่น่าสนใจ และศึกษาเพิ่มเติมเพื่อให้เข้าใจมากขึ้นสำหรับ architecture และ software pattern อื่นๆ

Architecture

Design Patterns

Chaos Engineering

What is DevOps

ในความเข้าใจเกี่ยวกับ devops นั้นแตกต่างตามบริบทการใช้และการเรียกของแต่ละคน จึงไม่ได้เป็นประเด็นมากนักว่า devops นั้นมีความเข้าใจถูกหรือผิด เพราะคนใช้มีบริบทที่แตกต่างกัน ลองดูบริบทในมุมของ ความเป็นมาและทำไมต้องมี

devops เกิดขึ้นจากปัจจุบันที่แต่ละทีม มีการแข่งขันกันในการสร้าง Innovation และนำ technology ใหม่ๆ มาใช้เพื่อปรับปรุงการทำงาน และสร้าง service ต่างๆ ออกมาให้ตรงใจและพึงพอใจต่อผู้ใช้งาน

Development team มีการใช้ technology container ในการ package application ด้วยการ pack ความต้องการที่ application ต้องใช้ในการทำงานไว้ใน package เดียวทั้งที่เป็น OS, application dependency, lib และ configuration ที่จำเป็น ทำให้ container สามารถทำงานในสภาพแวดล้อมต่างๆ ได้ง่าย และการทำงานได้ผลลัพธ์ไม่แตกต่างๆกัน

ขณะเดียวกัน Operation team ก็ศึกษา Kubernetes เพื่อให้เป็น platform สำหรับ application team สามารถเรียกใช้ผ่าน APIs ในการ deploy และทดสอบ application โดยที่ไม่ต้องเสียเวลาในการขอบริการ Virtual Machine, Network, Storage ทำให้ประหยัดเวลาในการให้บริการกับทีม Developer (Kubernetes = Infra APIs)

จะเห็นว่าแต่ละทีมต่างก็เสนอ Innovation ใหม่ๆ สิ่งที่เกิดขึ้นคือเกิดการพูดคุย ร่วมด้วยช่วยกันมากขึ้นระหว่างทีม Development และ Operation เกิดเป็น Culture และมีเป้าหมายที่ชัดเจนในการที่จะทำยังไงเพื่อทีจะทำให้การสองมอบ application และบริการถึงมือผู้ใช้ได้ดีที่สุด

ดังนั้น DevOps จึงเป็น culture ไม่ใช่ tool หรือ technology

Culture

DevOps เกี่ยวข้องกับการทำลายอุปสรรคระหว่างทีม เวลาที่เสียไประหว่างที่รอเพื่อให้ได้ resource ตามความต้องการ เอกสารและ process ที่ทำให้กระบวนการส่งมอบ software ไม่มีประสิทธิภาพ การที่ทีม Dev และ Operation มีการพูดคุยเพื่อทบทวนกระบวนการ และหา tool ที่สามารถลดขั้นตอน รวมทั้งลดอุปสรรค์ระหว่างการส่งมอบ software ให้น้อยที่สุด จะส่งผลดีโดยรวมต่อระบบ IT

Automation

เพื่อให้บรรลุเป้าหมาย การใช้ระบบอัตโนมัตินอกจากช่วยประหยัดเวลาแล้วยังป้องกันข้อบกพร่อง สร้างความสม่ำเสมอ รวมถึงการส่งเสริมการให้บริการในรูปแบบ self-service ในทีม

Measurement

เป้าหมายของทีมคือการปรับปรุงกระบวนการอย่างต่อนเนื่อง ดังนั้นจำเป็นต้องมีการวัดผล หรือ dashbarod ที่แสดงสถานะการทำงานปัจจุบัน จึงจะสามารถนำข้อมูลมาใช้ในการปรับปรุงระบบให้ดีอยู่เสมอได้

Sharing

กุญแจสำคัญของความสำเร็จของ DevOps ในทุกองค์กรคือการแบ่งปันเครื่องมือ ความรู้ บทเรียนที่ค้นพบ เพื่อให้ทีมได้รับข้อมูลเกี่ยวกับวิธีการใหม่ๆ สร้างสรรค์สิ่งใหม่ๆ สร้างการเรียนรู้ในทีมร่วมกัน

ทุกองค์กร จำเป็นต้องมี DevOps การจะพัฒนา culture นี้ขึ้นมา จะช้าหรือเร็วนั้นขึ้นอยู่กับวัฒนธรรมองค์กรนั้นๆ ว่าเอื้ออำนวยขนาดไหน ไม่ช้าก็เร็วองค์กรก็จะต้องมี DevOps เกิดขึ้น เหมือนถนนที่ใช้เดินทางไปยังกรุงโรม ที่เมื่อออกเดินทาง ปลายทางก็จะเป็นกรุงโรม

Note:

DevOps = Developer + Operation

DevSecOps = Developer + Security + Operation เป็น term ใหม่ ที่ทีม security เข้ามาร่วมด้วยในกระบวนการส่งมอบ software โดยการใช้ทักษะและ tool ที่ทีม security มีมาใช้เป็นส่วนหนึ่งในกระบวนการส่งมอบ โดยการตรวจสอบช่องโหว่ด้านความปลอดภัยตั้งแต่เริ่มต้น develop software (shift-left security)

FinOps = Financial + Operation เป็นอีก term ที่ทีม financial ที่เป็นผู้ support เรื่อง budget ต่างๆ สำหรับทีม operation เพื่อใช้ manage application อยากรู้ข้อมูลเรื่องค่าใช้จ่าย และความสมเหตุสมผลการการลงทุน การมีข้อมูลที่ monitor เรื่อง IT spending อยู่ตลอดเวลาทำให้ทีม Finance สามารถ plan เรื่อง budget และควบคุมค่าใช้จ่ายได้ ขณะเดียวกัน operation team ก็สามารถใช้ข้อมูลนี้ในการ optimize resource ที่ใช้สำหรับ run application ได้เช่นเดียวกัน

Agile Operation

รูปแบบการจัดการทีมงาน เมื่อต้องรองรับการทำงานแบบ agile บางครั้งจะมองว่าเป็นเรื่องของทีม development ที่จริงแล้วต้องมองภาพรวมของทั้ง IT จึงจะสามารถขับเคลื่อนได้อย่างมีประสิทธิภาพ

ด้วยการแบ่ง Roles และสิ่งที่ต้อง focus ในแต่ละ layers ของ IT landscape คือ

Business Capability ต้องมี product team ที่จัดการในลักษณะ cross-functional โดยประกอบด้วย product owner, designer, dev, QA รับผิดชอบในการ develop application ตลอด life cycle เช่น plan, design, develop และ test

Platform ต้องมีผู้ที่มีหน้าที่เป็น application operators รับผิดชอบในการ config, deploy, ตรวจสอบความพร้อมของ application (QA), monitor และ scale app ผู้ที่รับผิดชอบส่วนนี้จะมาจากฝั่งทางด้าน development team ที่มีความรู้ความเข้าใจเกี่ยวกับ application พอสมควรและเข้าใจกระบวนการ CI/CD ที่เกี่ยวข้อง

Site Reliability ต้องมีผู้ที่มีหน้าที่เป็น Platform Operators ที่มีพื้นฐานทางด้าน Midle-ware หรือ Web server เพราะต้อง provide resource ที่ต้องใช้เสำหรับการ run application บริหารเรื่อง high availability, consistency และ resiliency ของ application การทำ capacity planning การ upgrade platform และขยาย platform เพื่อให้รองรับการใช้งานที่มากขึ้น

Infrastructure ต้องมีผู้ที่มีหน้าที่เป็น Engineer ที่ดูแล virtual infrastructure และ equipment ต่างๆ เช่น storage, security, network

แต่ถ้าเราจะมองในมุม functional ของงานและแบ่งแยกย่อยลงไปอีกก็สามารถใช้รูปแบบนี้เป็น model ก็ได้เช่นกัน

และเมื่อ map role กับ functions งานก็จะได้ดังรูป

การจะเลือกรูปแบบใดนั้นขึ้นอยู่กับความซับซ้อน และขนาดของระบบที่แต่ละองค์กรมีความแตกต่างกัน ดังนั้น role ของ IT ในแต่ละองค์กรจึงไม่จำเป็นต้องเหมือนกันทุกองค์กร

Engineering Standard for DevOps

สรุปมาตรฐานในการพัฒนา DevOps ในองค์กร เพื่อเป็นหลักพิจารณาในการเริ่มต้นสร้างวัฒนธรรม (culture) กระบวนการ (process) และเลือก technology ที่เหมาะสม โดยสรุปเป็นหลักการได้ดังนี้

12 Factors

Application ต้องถูกสร้างตามหลักการ 12 Factors ซึ่งเป็นหลักการในการพัฒนา cloud native application ที่สามารถทำงานในสถาพแวดล้อมที่แตกต่างๆ กันได้ง่าย โดยมีหลักการเช่น ไม่เขียน log ลง file โดยให้ผ่าน standard output สร้าง environment ที่มี component, version และ configuration เหมือนกัน (dev, sit, prod) จัดการ configuration แยกจาก application ผ่านทาง environment เป็นต้น

Git Pre-Commit Hooks

ต้องมั่นใจว่ามีการใช้ pre commit hooks ของ GIT เพื่อ validate code ก่อนที่ code จะถูกจัดเก็บใว้ใน repository การทำ hook คือทุกครั้งที่ engineer ทำการ push code ไปยัง source control นั้น code จะถูกตรวจสอบและทำการ test ก่อน เพื่อป้องกัน code ที่ไม่สมบูรณ์​​ (poor quality code) ถูกเขียนลง repository การที่มี process นี้ก่อนกระบวนการ commit จะทำให้มั่นใจได้ว่า code ที่จัดเก็บจะเป็น code ที่มีคุณภาพเสมอ แนะนำตรวจสอบตามรายการดังนี้

  • Linting เป็นการตรวจสอบ code ว่าตรงตาม coding standards หรือไม่ เช่น การตั้งชื่อ function หรือ variable การใช้ space การเขียน comment
  • Unit Tests ทำการ execute test case
  • Commit Message เช่น commit message จะต้องมีอย่างน้อย 80 ตัวอักษร เพื่อเป็นการบังคับให้ engineer สื่อความหมายของ code ที่จะเก็บใน repository ได้จัดเจน
  • Jira มีการ reference ส่วนของ code กับ ticket ใน Jira เพื่อให้สามารถ trace ได้ว่า code ชุดนี้เกี่ยวข้องกับ requirement อะไร

Source Code Management

Source code จะต้องถูกจัดการผ่าน Gitlab หรือ git version control รวมถึง Infra code หรือ technical code อื่นๆ เป็นการจัดการ code ที่เดียวเพื่อความชื่อถือและถูกต้องเสมอสำหรับ development team (one source of truth) โดยมีหลักพิจารณาคือ

  • Trunk Based Development เป็นการให้ engineer ทำงานอยู่บน development branch (main branch) ในระยะเวลาที่สั้น (short iterations) ดีกว่าให้มีหลายๆ release หรือ feature branch เพื่อลดปัญหาเรื่องความซับซ้อนและยากลำบากในการ merge code (merge conflicts)
  • Feature Toggles สำหรับ code ที่ยังใช้งานไม่ได้ หรือพัฒนายังไม่เสร็จจะต้องถูกซ่อนไว้ โดยใช้ feature toggle เพื่อป้องกันหรืออนุญาติให้มีการนำ code ไปใช้
  • Configuration in Environment ไม่เก็บ configuration ต่างๆ ใว้ใน source code เพื่อป้องกันไม่ให้ส่วนที่เป็น credential หรือข้อมูลสำคัญรั่วไหล อีกทั้งยังเป็นการทำให้ code ไม่มี dependency เรื่อง config สามารถจัดการ config ผ่านทาง environment ที่ง่ายกว่าและย้ายไปยัง environment ได้สะดวกด้วย

Continuous Integration and Delivery (CI/CD)

ทุกๆ commit ใน git จะมีการ start CD/CD pipeline เพื่อมั่นใจว่าทุก code จะมีการ run ขั้นตอนต่างๆ ที่เป็นมาตรฐานในการส่งมอบ Application ขององค์กร

  • Validate code standard อย่างเช่น space และ brackets ที่อ่านง่าย
  • Execute test case
  • Code quality metric จะต้องมั่นใจว่า code ผ่านมาตรฐานที่กำหนดไว้ เช่น ไม่มีช่องโหว่ด้านความปลอดภัย (vulnerabilities) จำนวน coverage unit จะต้องมีมากกว่า 80% จำนวน smells bug หรือ code ที่เขียนโดยไม่เป็นไปตาม practices
  • Automate end-to-end functional และ non-functional testing
  • Deploy ไปยัง environment ต่างๆ ด้วยรูปแบบที่เหมาะสมเพื่อไม่ให้กระทบกับการทำงาน เช่น bluegreen, canary

Automated Testing

ทำการ automate test ในทุกระดับทั้งที่เป็น functional และ non-functional โดยเลือกใช้ tool ที่เหมาะสมในแต่ละ test case การใช้ automate test tool จะทำให้เห็นปัญหาก่อน User ประกอบด้วย

  • Unit เป็นการทดสอบส่วนไดๆ ใน code โดยต้องมี coverage ในการ test ที่เหมาะสม
  • Integration เป็นการทำ end to end test ประกอบด้วยการทำ API test และ UI test เพื่อ simulate การใช้งานของ User
  • Security ประกอบด้วย static และ dynamic security testing เป็น simulate การโจมตี application เพื่อหาช่องโหว่ด้านความปลอดภัย (vulnerabilities)
  • Performance เป็นการ load test เพื่อให้มั่นใจว่า application สามารถทำงานได้ในภาวะการณ์ต่างๆ ได้ ทั้งกรณีที่มี request และมีการส่ง data (payload) เข้ามามากกว่าปกติ

Security Testing

Web app และ Mobile application จำเป็นต้องมีการตรวจสอบความปลอดภัยมากกว่าเดิม จากการเข้าถึงของผู้ใช้งานได้ทั่วไป ดังนั้นโดยทั่วไปจึงมีการทำ hardening และ end-to-end penetration test จากหน่วยงานภายนอกก่อนที่จะขึ้น production การทำ security testing สามารถทำได้หลายวิธี โดยการทำให้เป็นส่วนหนึ่งของ agile process และ devops

  • Dynamic Application Security Testing (DAST) และ Static Application Security Testing (SAST) เป็นเครื่องมือและวิธีการที่อยู่ในกระบวนการ Continuous Integration pipeline เพื่อให้มั่นใจว่าทุกขั้นตอนในการบวนการ code change build และ release จะมีการตรวจสอบ security อยู่เสมอ (shift-left security)
  • สำหรับการตรวจสอบจากองค์กรภายนอก (Third-Party Penetration) สามารถทำในบางจุดที่สำคัญเพื่อให้มีความคล่องตัว ลดเวลาและค่าใช้จ่ายในการตรวจสอบความปลอดภัยของ application ได้ โดยที่ไม่เป็นการเพิ่มความเสี่ยง

Dynamic App Security Testing – DAST

สามารถใช้ OWASP ZAP เพื่อ scan application ที่ทำงานอยู่ได้ (black box testing) โดยจะทดสอบความปลอดภัยด้วย test case พื้นฐานสำหรับ web application ที่เป็นมาตรฐานคือ OWASP Top 10 Vulnerabilities

ZAP สามารถเป็นขั้นตอนหนึ่งใน Continuous Integration Pipeline เพื่อให้ scan โดยอัตโนมัติเมื่อ code change, build และ release รวมถึงรายงานช่องโหว่ด้านความปลอดภัย (vulnerabilities) ให้กับทีม developer ทราบทันที ป้องกันไม่ให้ release application ที่ไม่ปลอดภัยไปยัง production

Static App Security Testing – SAST

ใช้ SonarQube เพื่อวิเคราะห์ source code และตรวจจับ code ที่อาจจะเป็นช่องโหว่ด้านความปลอดภัยของ application โดยให้ SonarQube เป็นส่วนหนึ่งของ Continuous Integration Pipeline จะทำให้มีความมั่นใจ และป้องกัน application ที่ไม่ปลอดภัยถูกใช้บน production

Independent App Penetration Testing

กระบวนการพัฒนา software ในแบบ waterfall project ส่วนใหญ่จะใช้ องค์กรอิสระที่เชื่อถือได้เพื่อตรวจสอบช่องโหว่ด้านความปลอดภัยของ software ก่อนขึ้น production ซึ่งส่งผลกระทบกับ cost ระยะเวลา และความถี่ในการ release software ทางเลือกที่เหมาะสมที่สามารถเข้าได้กับกระบวนการ agile และ devops คือรวมวิธีการของ DAST และ SAST เข้ามาใน process ก็จะทำให้ลดจำนวนที่ต้องใช้องค์การภายนอกได้ โดยมีหลักการพิจารณาคือ

  • Schedule appropriately กำหนดกรอบระยะเวลาที่ชัดเจนในการทำ penetration test หลังจากที่ทุก function มีการ implement เรียบร้อย
  • Lead time กำหนดให้ penetration test ทำในรอบ sprint ทำให้สามารถแก้ไขควบคู่กับการทดสอบ เพื่อไม่ให้ส่งผลกระทบกับการ release application
  • Cost สำหรับการทำ penetration test จะลดลงเมื่อมีการทำ penetration test แค่ครั้งเดียวก่อนที่จะ release application โดยที่ไม่พบช่องโหว่ด้านความปลอดภัย

OWASP Dependency-Check

เป็นการทำ Software composition analysis ด้วยการตรวจสอบข้อมูลของ File (file name, POM files, ZIP files, native libraries, .NET assemblies, package name ..) แล้วตรวจสอบกับฐานข้อมูล National Vulnerability Database – NVD เพื่อแจ้งเตือนถึงความเสี่ยงในการใช้งาน package หรือ library ใน source code ปัจจุบัน OWASP Dependency-Check สามารถใช้ร่วมกับหลายๆ tool เช่น

  • Ant Task
  • Command line tool – Windows, *nix
  • Gradle plugin
  • Jenkins plugin
  • Maven plugin

Semantic Versioning

ใช้ Semantic versioning เพื่อจัดการ version ของ release สำหรับหลาย ๆ microservice และ application โดยการ tag version number ที่ release branch ที่สร้างใน git repository

version ของ release ใช้หลักการที่ง่ายเพื่อให้ผู้ใช้ microservice หรือ application เข้าใจ change ที่เกิดขึ้น รวมถึงทีม tester การจัดการ version สามารถใช้หลักการดังต่อไปนี้

  • Major เป็นการเปลี่ยนแปลงที่สำคัญ หรือส่งผลกระทบต่อภายนอกเช่นการเปลี่ยนการเรียกใช้ API หรือ Interface
  • Minor การแก้ไขเพิ่มเติม function ที่มีอยู่แล้ว หรือเพิ่มความสามารถของ function เดิมให้สมบูรณ์และดียึ่งขึ้น
  • Patch เป็นการแก้ข้อผิดพลาดของ code (bug)
  • Chore เป็นการเปลี่ยนแปลงไดๆ ที่ไม่จำเป็นต้องเปลี่ยน version เช่นการทำ code refactoring

ข้อมูลเพิ่มเติมเกี่ยวกับ semantic version ได้จาก https://semver.org

Application & Platform Monitoring

Application ที่ทำงานบน environment มีการตรวจสอบสถานะการทำงานของ application และ platform และแจ้งเตือนเมื่อมีปัญหาไดๆ เกิดขึ้นแบบ realtime ด้วยการเก็บข้อมูลในรูปแบบ matrics อาจจะใช้ Prometheus และแสดงผลใน grafana dashboard เพื่อให้ทีมสามารถเห็นการทำงานของ application ที่เป็นปัจจุบันและสถิติที่ผ่านมาได้ ขอมูลจำเป็นที่ต้องจัดเก็บเช่น

  • Uptime/Downtime
  • CPU memory utilization
  • Failed network request 4xx 5xx response
  • Latency slow running request
  • Request Frequency (DDoS Protection)
  • Error message logged by application
  • Disk space usage

Collaboration

ช่องทางการติดต่อสือสารในทีม ทั้งที่เป็น internal และ external เป็นสิ่งสำคัญ และต้องใช้ tool ที่เหมาะสม เช่น

  • Slack ทีมสามารถ share ข้อมูลเกี่ยวกับ project พวก knowledge ต่างๆ ระหว่างทีม และสามารถใช้แจ้ง alert ได้กรณีที่ pipeline มีปัญหา อีกทั้งยัง invite business หรือ stakeholder เข้ามาในทีมด้วยเพื่อการรับรู้ข่าวสารต่างๆ ภายในทีม
  • Jira เป็น tool ที่ใช้ในการจัดการ product backlogs จัดการ sprint รวมถึง report ต่างๆ เพื่อให้ทีมเห็นถึง progress ในแต่ละงานได้

Cloud Platform

การทำ devops ให้สะดวกราบรื่นจำเป็นต้องมี platform ที่ช่วยอำนวยสะดวกในการ release, deploy, run และ manage application ได้ง่าย ปัจจุบันจะใช้ container technology ในการ packaging software และ run บน kubernetes environment เพราะสะดวกในการใช้งานเพราะการใช้งานจะผ่าน APIs ไม่มี manual process โดยใช้ Cloud Environment เป็น infrastructure เพื่อให้ platform สามารถ scale ได้ง่าย และ cloud environment ยังช่วยในเรื่องการจัดการ high availability , consistency และ resilent ของ application ได้ง่ายอีกด้วย

App Modernization Approach – Swift Process

หลักการในการพัฒนา modern app นั้นมีค่อนข้างหลากหลาย และถูกใช้ในแบบที่แตกต่างกันในแต่ละที่ แต่ละสภาพแวดล้อมของ App และทีม Development ส่วนตัวชอบ process การออกแบบโดยใช้ Swift เพราะเป็นวิธีการที่ prove แล้วว่าใช้ได้จริงในองค์กรใหญ่ๆ โดยใช้ concept DDD และมีขั้นตอนคร่าวๆ ดังนี้

  1. กำหนด OKR เพื่อให้ทีมเข้าใจในทิศทางเดียวกันว่ากำลังจะทำอะไร เพื่ออะไร แล้วจะวัดผลด้วยอะไร
  2. ทำ session Event Storming เป็นการร่วมกัน explore ว่าในเรื่องที่ทำนั้น (context) มีเหตุการณ์ (event) อะไรบ้างเรียงตามเวลาที่เกิดขึ้น session นี้จะทำให้ทั้งทีมเข้าใจในสิ่งที่จะ build ขึ้นมาว่ามีกระบวนการทำงานยังไง
  3. เลือกตัดส่วนที่เข้าใจชัดเจนที่สุด หรือมี impact มากสุดมาทำก่อน
  4. สร้าง diagram เพื่ออธิบาย architect ของแต่ละ module ที่อยู่ใน system (BORIS) ว่ามีความสัมพันธ์กันยังไง มีการแลกเปลี่ยนข้อมูล หรือให้บริการอะไรบ้าง รวมทั้งระบบภายนอกที่เกี่ยวข้อง (external system)
  5. ลงรายละเอียดเบื้องต้นของแต่ละ service (SNAP) เช่น APIs, Data, PUB/SUB, External System, User stories, UI และ Risk แล้วใช้ Project Management tools (Jira) เพื่อขยายรายละเอียดพร้อมสำหรับการนำไป Implement และเข้าสู่กระบวนการ agile
  6. พัฒนา Code
  7. Document กระบวนการ วิธีการพัฒนา ปัญหา วิธีการแก้ไข เพื่อให้ครั้งแต่ไปสามารถนำไปใช้ได้และ ไม่ต้อง research อีกครั้ง อีกทั้งช่วยทำให้คนใหม่ที่เข้ามาในทีมสามารถเรียนรู้ และ follow สิ่งที่ทำผ่านมาแล้วได้

สรุปรูปแบบข้างต้นจากบนลงล่าง

Enterprise Architecture Map

ในการออกแบบ IT system ของแต่ละองค์กรต่างมีแบบแผนที่ยึดหลักมาตรฐานต่างๆ เช่น TOGAF หรือไม่ก็ eTOM แต่วิธีการพวกนี้อาจจะเข้าใจยากและใช้เวลามาก เพื่อที่จะได้ landscape ของทั้ง IT ในมุมของการ invest และจัด priority วิธีที่ง่ายที่สุดในการสร้าง IT Enterprise Architecture คือการมองเรื่อง capability และ impact ที่ได้ต่อ business เมื่อมีการ invest และสามารถเห็นภาพรวมในสิ่งที่มีแล้วและสิ่งที่ขาด diagram นี้เป็น diagram หนึ่งที่ช่วยทำให้เราเข้าใจภาพรวมของระบบ IT ได้ง่ายขึ้น

จาก diagram นี้ถือเป็น diagram เริ่มต้น โดยเราต้องใส่ platform ที่เราใช้อยู่ปัจจุบันเข้าไปเช่น Container บน cloud ถ้าใช้ AKS ก็ระบุเข้าไปในกล่อง หรือมี service มากกว่านี้ที่ใช้บน cloud ก็สามารถเพิ่มกล่องเข้าไปได้ หลังจากทำเสร็จแล้วเราจะรู้ว่าปัจจุบันระบบ IT มีอะไรในส่วนไหนบ้าง แล้วยังขาดอะไรที่ต้องเติมเต็ม และสามารถใช้เป็นแผนงานสำหรับในแต่ละปีได้

DDD in Action

หลังจากที่ได้เรียนรู้ Domain Driven Design (DDD) แล้ว ลองเอา concept ของ DDD มาใช้เพื่อออกแบบ Software Architect โดยใช้หลักการของ Swift Method ซึ่งเป็น framework สำหรับการพัฒนา Modernization Software

เริ่มจากสิ่งที่เราเข้าใจ และอธิบายความหมายของคำว่า Item อย่างไร

Item สำหรับแต่ละคนมีความหมายที่แตกต่างกัน แล้วแต่ประสบการณ์และมุมมอง

Item เมื่อไปอยู่ในแต่ละ context ที่แตกต่างกัน ก็จะมีลักษณะไม่เหมือนกัน หรือเป็นคนละอย่างกันเลย เช่น Item ที่อยู่ใน Cart ก็อาจจะเป็นสินค้า แต่ Item ที่อยู่ใน Order ก็จะหมายถึงคำสั่งซื้อ โดยที่อาจจะมีข้อมูลและลักษณะใช้แทนกันไม่ได้เลยทีเดียว ดังนั้นการออกแบบ Software ที่หลายๆ Application ใช้ share data model เดียวกันจึงเป็นการออกแบบที่ไม่เหมาะสม เพราะจะมีปัญหาเรื่องของการ scale หรือแก้ไขเพิ่มเติม จะส่งผลกระทบกับหลายๆ Application ในภายหลัง

สิ่งสำคัญต่อมาคือการพัฒนาการสื่อสารที่เป็น common language ระหว่าง Business และ IT เพราะปัญหาของนักพัฒนา Application ส่วนใหญ่จะเป็นเรื่องของความเข้าใจที่คลาดเคลื่อน (misaligned) จากผู้ที่เป็น Business หรือเจ้าของ Project (Domain Experts) เพราะคนกลุ่มนี้จะไม่ค่อยเข้าใจเรื่อง IT ดังนั้น Software Developer จะต้องใช้ภาษาที่ Business เข้าใจง่าย รวมถึงการออกแบบจะต้องใช้รูปแบบที่แสดงให้เห็นถึงสิ่งที่เกิดขึ้นในชีวิตจริง จึงจะสามารถพัฒนา Code ตาม Business Concept ได้อย่างถูกต้อง

ซึ่งก็คือการใช้ ubiquitous language หรือที่เรียกว่าการใช้ภาษาเดียวกันภายใน bounded context ที่ทีมได้ร่วมกันพัฒนาอยู่

นอกจากนี้ยังต้องพิจารณาเรื่องของ integration ระหว่าง context อื่นๆ ที่ต้องมีรูปแบบการสื่อสารและความสำพันธ์ขึ้นอยู่กับ context นั้นๆ

และกรณีที่ต้องมีการแปลงการสื่อสารเพื่อให้สื่อสารได้ตรงกัน ก็จำเป็นต้องมี Anti-Corruption Layer ACL เข้ามาร่วมด้วย เช่นการสื่อสารระหว่าง 2 ทีม ที่เป็น upstream และ downstream โดยที่ downstream มีส่วนของ ACL เพื่อให้การสื่อสารสามารถเข้ากันได้ เป็นต้น

บางกรณีอาจจะพิจารณาใช้ Aggregates เพื่อให้ข้อมูลถูกนำไปใช้ได้เลย

อาจจะมองเป็นลักษณะของ transaction ที่ข้อมูลประกอบด้วยหลายๆ business entity เช่น Policy, Order, Customer, Account ที่ถูก Aggregates ไว้ด้วยกัน ซึ่งแสดงความสัมพันธ์เป็นลำดับชั้นของกราฟที่มี Root entity และ entity อื่นๆ รวมถึง value object

ตัวอย่างของ Aggregate ของ Item

Item เป็น transaction ที่ประกอบด้วยหลาย entity ภายใต้ขอบเขตเดียวกัน (consistency boundary) สามารถมีได้มากกว่าหนึ่ง entity และ value object โดยมีการ reference ผ่าน ID (ไม่ใช่ reference object) ดังนั้นเมื่อมีการเปลี่ยนแปลงใดๆ กับ Item ก็จะทำให้ผู้ที่เรียกใช้ Item นี้เห็นการเปลี่ยนแปลงนี้ด้วยเช่นกัน (eventually consistent)

Domain Events เป็นเหตุการณ์ที่เกิดขึ้นใน Business เนื่องจากเป็นเหตุการณ์ที่เกิดขึ้นแล้ว จึงนิยมใช้ในรูปแบบ Past Tense การเขียนจะต้องใช้ภาษาที่เข้าใจง่ายทั้ง dev และ domain expert โดยชนิดของ event มีทั้งที่เป็น การแจ้งเตือน (Notification) และ การเปลี่ยนสถานะ (State transfer)

Command ใช้เพื่อระบุว่าเกิดการ request หรือ trigger เพื่อให้เกิดเหตุการณ์ใดๆ ขึ้นใน Business

เมื่อนำ item, domain event และ command เพื่อแสดงสิ่งที่เกิดขึ้นใน domain มารวมกันจะทำให้ทั้ง business expert และ developer เข้าใจตรงกัน สื่อสารกันได้ง่ายและถูกต้อง

Event Storming

ในการออกแบบ software ควรต้องเริ่มต้นจาก events ที่เกิดขึ้นในแต่ละ business โดย event เองเป็น common language ที่ทั้ง business และ IT สามารถสื่อสารและเข้าใจกันได้ง่าย

ข้อดีของการทำ Event Storming

  • ทำให้ Business และ IT เข้าใจในทิศทางเดียวกัน
  • เป็นวิธีที่มีประสิทธิภาพในการทำงานกับ Business
  • ทำให้เข้าใจรายละเอียดของ Domain และ Sub Domain
  • พูดคุย แลกเปลี่ยนความคิดเห็น
  • วิธีการที่เร็ว ทำให้เห็นปัญหา แก้ไข และปรับปรุงให้ดีขึ้น
  • สามารถมองเห็นว่าควรจะทำอะไรก่อนหลัง (priority) และการ deliver
  • สามารถมองเห็นปัญหาได้แต่เนินๆ
  • ตัดสินใจเริ่มทำสิ่งใดสิ่งหนึ่งได้ง่าย

ในการทำ session Event Storming จำเป็นต้องจัดสถานที่ที่เหมาะสม เพื่อให้ business และ IT ได้ทำกิจกรรมด้วยกัน โดยมีกระดาน (board) ที่มีเนื้อที่ขนาดใหญ่ และ sticky note สำหรับแต่ละคนใช้เพื่อเขียน event ลงใน sticky note เพื่อแปะบนกระดาน (board) มีการอธิบายรูปแบบของสีที่ใช้ ว่าสื่อความความหมายถึงอะไร

ในการแปะ event ลงใน board จะต้องเรียงตามลำดับเวลาจากสิ่งที่เกิดขึ้นก่อน แล้วตามด้วยสิ่งที่เกิดขึ้นภายหลัง

ตัวอย่างการแปะ event โดยแบ่งตามสี ถ้าสีส้มคือ event ส่วนสี ชมพู หมายถึง note และแปะตามเวลาก่อนหลัง

ทั้งนี้อาจจะมีสีอื่นๆ เพื่ออธิบาย event ที่เกิดขึ้นได้ชัดเจน เช่น

ตัวอย่างการแปะ event เพื่อแสดง aggregate และ command ด้วย

Value Stream Scenario

ตัวอย่างของการใช้ Event Storming สำหรับระบบ E-Commerce ที่ลูกค้าสามารถเลือกสินค้าเข้าไปยังตะกร้า (cart) ทำการสั่งซื้อ (checkout) มีการส่ง order ไปยังระบบส่งของไปยังที่อยู่ปลายทาง (Shippping)

ลำดับเหตุการณ์ของระบบ purchase แบะ fulfillment จากการทำ Event Storming

จากลำดับเหตุการณ์ทำการ Grouping ให้ event ประเภทเดียวกันอยู่ด้วยกันเพื่อให้เข้าใจง่ายขึ้น และแปะชื่อกลุ่ม รวมถึง note ถ้ามี

แต่ละ group คือ sub domain ใน DDD ที่เคยเรียนมา ทำการแปะเพิ่มเติมในแต่ละกลุ่ม เพื่อให้ event มีความสมบูรณ์มากขึ้น โดยใช้สีแทนความหมาย (DDD – Tactical design)

หลังจากนั้นนำแต่ sub domain มาสร้างเป็นความสัมพันธ์ว่าในแต่ context นั้นมีการเรียกใช้ data หรือบริการอะไรจาก context อื่น เรียกแบบ Sync call หรือ Async event ด้วยวิธีการนี้จะทำให้เราเห็นภาพรวมของระบบ รวมถึงปัญหาที่อาจจะเกิดขึ้นจากการ integration ข้อมูลที่จำเป็นที่จำเป็นจะต้องรู้จากระบบภายนอก (external sytem) เป็นต้น

ตัวอย่างข้างต้นคือการทำ BORIS ซึ่งเป็นกระบวนการหนึ่งใน Swift Method

ขั้นตอนสุดท้ายคือการลงรายละเอียดของ APIs, Data, Pub/Sub, External System/UI, Agile Stories และ Risk เพื่อให้เข้าใจว่าในแต่ sub domain มีกระบวนการ ขั้นตอนการทำงานที่เป็น specification คร่าวๆ เพื่อนำไปเข้าระบบ project management tool (Jira) และทีม developer ก็สามารถจะเริ่มทำการ develop software ได้ตาม sprint หรือ agile process

ขั้นตอนนี้เรียกว่า SNAP ในกระบวนการของ Swift Method

ภาพรวมของทุก sub domain

จะเห็นว่ากระบวนการออกแบบ software เป็นเรื่องที่สนุกและการมีหลายๆ ทีมที่เกี่ยวข้องเข้ามาร่วมออกแบบจะทำให้ software ออกมาตรงความตรงการ และ business ก็สามารถเข้าใจ และแนะนำการแก้ไข และปรับปรุงได้ง่าย

และการมี diagram ที่ติดไว้ใน board จะทำให้ทีมที่เกี่ยวข้อง เข้าใจในส่ิงที่กำลัง develop และไม่เสียเวลามากนักในขั้นตอน document