TPSE 2013

Thailand Practical Software Engineering เป็นอีกหนึ่งงานจากทาง SPIN ค่ะ งานนี้ไปโดยไม่ค่อยหวังอะไร เพราะดูจาก agenda แล้วคล้ายๆ กับ Thailand SPIN 2013 มากๆ ทั้ง speaker แล้วก็หัวข้อ แต่ก็คิดว่าลองไปฟัง keynote speaker จาก NASA ดู แต่ก็ได้อะไรกลับมาพอสมควร



โดยงานนี้ แบ่งเป็น 2 วัน วันแรก มี keynote speaker ที่น่าสนใจ คือ Firouz Naderi  ซึ่งมาเล่าประสบการณ์จากการบริหารโครงการที่ NASA ให้ฟัง สรุปนะค่ะเค้ามีวิธี 3 ขั้นตอนในการทำให้โครงการประสบความสำเร็จ คือ

  1. get best people, mold them in team เรื่องนี้เค้าให้ระวังเรื่อง "chemistry" ในทีมด้วย แม้ว่าจะได้คนเก่งมา แต่ถ้าไม่เข้ากับทีม ก็มีปัญหา แต่ PM จะต้องเป็นคนทำยังไงก็ได้เพื่อให้คนในทีมเข้ากันให้ได้
  2. motivate team เค้าเน้นว่าเรื่องนี้สำคัญมาก เพราะเมื่อคนเราทำงานไประยะหนึ่งในโครงการก็จะมีช่วงจังหวะที่ล้า PM จะต้องเป็นคนที่ทำให้ทีมมีพลัง
  3. share success ง่ายๆ ก็คือ "ไม่ได้เอาดีใส่ตัว เอาชั่วใส่คนที่เหลือ"
นอกจากนี้ก็ยังมีประเด็นอื่นๆ ด้วย แต่ที่จับใจความได้ (คือภาษาอังกฤษไม่แข็งแรงค่ะ) คือ don't afraid to fail. เพราะทุกโครงการมีความเสี่ยง และไม่เคยมีข้อมูลเพียงพอสำหรับการตัดสินใจ ณ.เวลานั้น อยู่ที่ PM เลยว่าจะตัดสินใจยังไง แต่ทั้งนี้ทั้งนั้นสิ่งที่เลวร้ายที่สุดก็คือการไม่ตัดสินใจอะไรเลย (The worst is not making decision. In complex project, there is no enough information to make the decision.)


หลังจากนั้นตอนบ่าย ก็ไปฟัง "Robot Framework: Generic test automation framework for acceptance testing and acceptance test-driven development (ATDD)" ซึ่ง"เป็นการพูดถึง tools ชื่อ Robot ซึ่งจะช่วยในการทำ automated test ซึ่งโดย concept แล้วดีทั้งนั้นค่ะ การที่มี TDD ก็ดีอยู่แล้ว ATDD ก็ยิ่งดีขึ้นไปอีก แต่ถ้าจะใช้จริงๆ คงต้องศึกษาเพิ่มเติมอีกเยอะเลย

และ session สุดท้ายของวันแรกที่เข้าฟัง ก็คือ "Practical UX First step" ซึ่งเปิดโลกของเราสำหรับ UX เลย เพราะว่าไม่เคยได้ศึกษา หรือว่าอ่านเรื่องนี้มาก่อน ไว้จะเขียนลงไว้อีกครั้งหนึ่งค่ะ


สำหรับวันที่สอง เนื่องด้วยสะดุดปัญหาหลายอย่าง เลยอดไปฟัง keynote speaker ตอนเช้าที่มาจาก ThoughtWorks และ session เช้าทั้งหมด ไปฟังอีกทีตอนบ่ายเลย ซึ่งเราก็เข้าไปฟัง "Agile in Enterprise: the missing pieces" ซึ่งทำให้ได้ความรู้ในอีกมุมของการใช้และปัญหาของ scrum สำหรับองค์กรใหญ่ๆ แต่อาจจะไม่ค่อยเข้ากับเราเท่าไร เพราะก็ยังไม่คิดว่าจะได้เป็นคนเอามาใช้ หรือผลักดันให้ใช้อ่ะนะ คือไม่ได้อยู่ใน position นั้น และ session สุดท้ายที่ได้ฟังก็คือ "Lean/Kanban – Going beyond Scrum" อันหลังจะเข้ากับจริตมากกว่า เพราะว่ากฎน้อย ทำตามได้ง่าย ยืดหยุ่นกว่า แต่กฎที่น้อยนี่เองก็จะอาจจะเป็นทั้งจุดอ่อนและจุดแข็งในคราวเดียวกัน สำหรับการนำมาปฏิบัตสำหรับคนทั้งกลุ่มที่ยังไม่เคยรู้จัก agile การมีกฎดูจะทำให้ทำตามได้ง่ายกว่า แต่เมื่อรู้และเข้าใจกฎแล้ว การใช้ Kanban ดูจะช่วยให้อะไรๆ ง่ายขึ้น และปรับแต่งให้เข้ากับแต่ละที่ และสถานะการณ์ได้ง่ายกว่า

Reference:
http://www.tpseconf.org
Lean/Kanban – Going beyond Scrum






First UX ใน mind

ที่เขียนหัวข้อแบบนี้ เพราะว่ายังไม่ได้ศึกษา UX สักเท่าไร เพียงแต่ได้ยินมาจากงาน TPSE ก็เลยอยากจะบันทึกไว้ เผื่อจะได้ประโยชน์ในภายหน้า ถูกผิดอย่างไรของรับไว้ผู้เดียว ไม่เกี่ยวกับ speaker ค่ะ

"Practical UX First step" เป็น session สุดท้ายของงาน TPSE ที่ได้ไปร่วมมา ซึ่งสำหรับเราถือเป็นการเปิดโลกของ UX เป็นครั้งแรก เพราะว่าเป็นครั้งแรกที่ได้ทำความเข้าใจกับ UX จริงๆ โดยมี workshop แสนสั้นมาให้ลองทำกัน อันแรกเป็นการพูดถึงซอฟต์แวร์ แต่ละประเภทว่าจะมีลักษณะใดตามรูป

โดยซอฟต์แวร์ที่อยู่ในแต่ละ quadrant จะมีลักษณะที่ต่างกัน

  • จริงจัง+เครื่องมือ เป็นซอฟต์แวร์ประเภทที่ผู้ใช้เข้ามาใช้งาน ต้องการทำงานให้เสร็จ เช่น Email ซอฟต์แวร์ประเภทนี้ไม่ต้องเน้นความสวย แต่ควรจะเน้นเรื่องประสิทธิภาพ ทำให้ผู้ใช้สามารถทำงานได้เสร็จได้โดยเร็ว
  • สนุกสนาน+เครื่องมือ จะเป็นพวก home use เช่นซอฟต์แวร์การจดค่าใช้จ่ายรายวัน ซอฟต์แวร์ประเภทนี้ควรจะต้องเน้นความสวยงาม เพราะผู้ใช้มีเวลาในการใช้งานมาก ไม่รีบ ไม่ต้องเน้นประสิทธิภาพ
  • สนุกสนาน+เครื่องเล่น เช่น ซอฟต์แวร์เกมส์
  • จริงจัง+เครื่องเล่น เช่น Youtube เอาไว้ดูกีฬา ผู้ใช้จะจริงจังกับ content ภายใน แต่ไม่ได้สนใจตัวซอฟต์แวร์ที่เป็นตัวผ่าน content ดังนั้นซอฟต์แวร์ประเภทนี้ไม่ต้องเน้นสวย แต่ควรจะทำให้ผู้ใช้สามารถเข้าถึง content ได้เร็วๆ
  • ผู้ช่วย หรือซอฟต์แวร์ประเภทที่อยู่ตรงกลาง คือมีลักษณะกลางๆ เช่น ซอฟต์แวร์หน้าเดียว เช่นไฟฉาย, รายงานอากาศ, พยากรณ์อากาศ, เข็มทิศ
โดยซอฟต์แวร์ตัวหนึ่งๆ อาจจะวางไว้ตรงไหนก็ได้อยู่ที่ผู้ผลิตซอฟต์แวร์อยากจะมองกลุ่มตลาดไหน
ส่วน workshop อีกอันหนึ่ง จะเป็นการให้ความสำคัญกับ non-functional เช่น high performance, responsive, elegant, attractive, easy to use, adaptive, compatible, mobile, accessibility กับซอฟต์แวร์แต่ละประเภท เช่น เกมส์, home use, business, ซอฟต์แวร์สำหรับเด็ก, อื่นๆ 

ซึ่งทั้งนี้ในการออกแบบ UX จะขั้นตอนอยู่ โดยการทำ workshop ร่วมกัน เพื่อค้นหากลุ่มเป้าหมาย และ feature ของซอฟต์แวร์ที่ต้องการจริงๆ โดยมีการตั้งเป็น persona คือลักษณะที่ชัดเจนของกลุ่มเป้าหมาย เพื่อให้การพัฒนาซอฟต์แวร์ได้ออกมาตรงกับกลุ่มเป้าหมายจริงๆ โดยซอฟต์แวร์ที่ผลิตออกมาควรจะต้องทำให้ผู้ใช้ในกลุ่มร่วมของ first mover และ market target ใช้ให้ได้ แม้ว่าจะเป็นจำนวนน้อย แต่ถ้ามีผู้ใช้ในกลุ่มนี้เข้ามาใช้ ก็จะทำให้เกิดการบอกต่อ และขยายฐานผู้ใช้ของซอฟต์แวร์ออกไปได้

ที่ได้ฟังมาก็จับใจความได้เท่านี้ ด้วยปัญญาอันน้อยนิด ผิดถูกอย่างไร แล้วแต่ท่านจะพิจารณากันต่อไปค่ะ


.Net กับ Java

เนื่องจากเป็นคนที่มีพื้นฐานเดิมเป็น Java เวลาต้องมาเรียนภาษาใหม่ ก็เลยอดที่จะเทียบไม่ได้ เพื่อให้ตัวเองได้เรียนรู้และเข้าใจได้เร็วขึ้น และเลยอยากจะเขียนไว้เผื่อใครจะเจอสถานการณ์เดียวกันค่ะ

C#.NetJava
namespacepackage
using
ซึ่งสามารถเขียนเป็น alias ได้ด้วย
using MessageSource = Microsoft.CSharp.Introduction.HelloMessage;
import
isinstanceof
basesuper
สามารถ pass value-type parameter (หรือ primitive type ใน Java) by reference ได้
using System; 
class Test { 
    static void Swap(ref int a, ref int b) 
   { 
        int t = a; 
        a = b; 
        b = t; 
    } 
    static void Main() 
   { 
        int x = 1; 
        int y = 2; 
        Console.WriteLine("pre: x = {0}, y = {1}", x, y); 
        Swap(ref x, ref y); 
        Console.WriteLine("post: x = {0}, y = {1}", x, y); 
    } 
}
ไม่มีการ pass primitive type by reference
มีการรับ output ทาง parameter ซึ่งสามารถมีได้มากกว่า 1 ตัว (ซึ่งจะคล้ายๆ กับการ pass parameter by reference เพียงแต่ไม่จำเป็นต้อง initialize ค่าตัวแปรที่เป็น output
   static void Divide(int a, int b, out int result, out int remainder) {
      result = a / b;
      remainder = a % b;
   }
เนื่องจากไม่มีการ pass primitive type parameter by reference ดังนั้นการส่งค่า output ทำได้ทางเดียวคือ return ค่ากลับมาซึ่งส่งได้ตัวเดียว การ return กลับมาสามารถส่งกลับมาเป็น Object ก็ได้
สร้าง modifier ที่ต่างกันสำหรับ get กับ set ไม่ได้ เช่น public get กับ private set ไม่ได้
    private string caption; 
    public string Caption { 
        get { return caption; } 
        set { caption = value; } 
    }
    private string caption; 
    public string getCaption() { 
        return caption; 
    } 
    private void setCaption(String caption) {
        this.caption = caption; 
    }
การ override จะต้องกำหนดเป็น virtual method ก่อน และ overriding method จะต้องใส่ override ไว้ด้วย มิฉะนั้นจะถือว่าเป็น method ใหม่ที่ไม่ได้ override ของเดิมมา แต่ในกรณีนี้ compiler จะขึ้น warning แต่ถ้าไม่อยากให้ขึ้น warning และเป็น method ใหม่ที่ไม่ได้ override มา จะต้องใส่ new แทน override
class Class1
{
    public virtual void Test()
    {
        Console.WriteLine("test in class1");
    }
}
class Class2 : Class1
{
    public override void Test()
    {
        Console.WriteLine("test from class2");
    }

}
class Class1 {
    public void test() {
        System.out.println("test in class1");
   }
}
class Class2 extends Class1 {
    public void test() {
        System.out.println("test in class2");
การแปลง String เป็น Enum
public enum CarBrand 
{
    TOYOTA, BENZ
}
public static void main()
{
    CarBrand car = (CarBrand) Enum.Parse(typeof(CarBrand), "BENZ");
}
    
public enum CarBrand {
    TOYOTA, BENZ
}
public static void main() {
    CarBrand c = CarBrand.valueOf("BENZ");
}
สร้าง operator ใหม่ได้
   public static Digit operator+(Digit a, Digit b) {
      return new Digit(a.value + b.value);
   }
ต้องเขียนเป็น method
static constructor
   static Employee() {
      Console.WriteLine("Do in initialize class");
   }
static block
    static {
        System.out.println("Do in static block");
    }
Destructors
   ~CName() {
      Console.WriteLine("Destructed {0}", this);
   }
finalize ซึ่งไม่แนะนำ
    @Override
    protected void finalize() throws Throwable {
        System.out.println("do finalize");
        super.finalize();
    }
สามารถสร้าง class ให้เป็น indexer ได้
   public object this[int index] {
      get {
         return ...;
      }
      set {
         ...
      }
   }
ไม่มี indexer
มี struct ซึ่งคล้ายกับ class แต่ว่าเป็น value type (pass by value) ซึ่งมีข้อดีในเรื่องประสิทธิภาพของระบบในบางกรณี (แต่บางกรณีก็อาจจะทำให้ช้าลง)
struct Point
{
   public int x, y;
   public Point(int x, int y) {
      this.x = x;
      this.y = y;
   }
}
ไม่มี struct
สามารถซ่อน method ที่ implement จาก interface ได้ (แต่ยังนึกไม่ออกว่ามีจุดประสงค์เพื่ออะไร)
interface IControl
{
   void Paint();
}
public class EditBox: IControl, IDataBound
{
   void IControl.Paint() {...}
}
class Test
{
   static void Main() {
      EditBox editbox = new EditBox();
      // editbox.Paint();   // error: no such method
      IControl control = editbox;
      control.Paint();   // calls EditBox's Paint implementation
   }
}
method จากการ implement interface จะเป็น public เสมอ
มี Delegate ซึ่งทำหน้าที่เหมือนกับ function pointer และเป็นพื้นฐานของการเขียน Event

delegate void SimpleDelegate();

class Test
{
   static void F() {
      System.Console.WriteLine("Test.F");
   }
   static void Main() {
      SimpleDelegate d = new SimpleDelegate(F);
      d();
   }
}


ไม่มี Delegate ถ้าต้องการเขียน Event อาจจะต้องเขียนเองโดยใช้ Observer Pattern
มี attribute
[AttributeUsage(AttributeTargets.All)]
class HelpAttribute: Attribute
{
   public string Topic = null;
   private string url;

   public HelpAttribute(string url)
   {
      this.url = url;
   }
   public string Url
   {
      get { return url; }
   }
}

[Help("http://www.microsoft.com/.../Class1.htm")]
public class Class1
{
}

public static void main()
{
   Type type = typeof(Example.Attributes.Class1);
   object[] arr = type.GetCustomAttributes(typeof(HelpAttribute), true);
   HelpAttribute ha = (HelpAttribute)arr[0];
   Console.WriteLine("Url = {0}, Topic = {1}", ha.Url, ha.Topic);
}
คล้ายกับ annotation
สามารถ compile เป็น library (.dll) หรือว่า .exe ได้เลย
csc /target:library HelloLibrary.cs 
csc /reference:HelloLibrary.dll HelloApp.cs
compile เป็น .jar อย่างเดียว ต้องทำงานผ่าน java (จาก jvm)
javac -classpath .:/home/avh/classes:/usr/local/java/classes example.java
  • Class ที่ควรรู้ Environment, Enum, DateTime, Color, Font
Reference:

.Net Naming Convention

Microsoft จะแบ่งการตั้งชื่อเป็น 2 แบบคือ
  1. Pascal Casing คือขึ้นต้นด้วยตัวใหม่แล้วตามด้วยตัวเล็ก และคำถัดไปก็ขึ้นต้นด้วยตัวใหญ่อีกครั้ง เช่น PascalCase 
  2. Camel Casing คือขึ้นด้นด้วยตัวเล็กและตามด้วยตัวเล็กคำแรก และคำถัดไปขึ้นด้นด้วยตัวใหญ่ เช่น camelCase
สำหรับอักษรย่อ (Acronym) ที่มี 2 ตัว และจะใช้เป็นตัวแรกแบบ Pascal จะใช้เป็นตัวใหญ่ทั้งหมด เช่น IO
สำหรับอักษาย่อที่มี 2 ตัว และใช้แบบ Camel คำแรกจะใช้เป็นตัวเล็กทั้งหมด เช่น dbRate

สำหรับตัวย่อ (Abbreviation ซึ่งจะต่างจาก Acronym เพราะจะย่อแค่คำเดียว เช่น id เป็นตัวย่อของ identifier ส่วน Acronym เช่น HTML ซึ่งย่อมาจาก Hypertext Markup Language) ไม่ควรใช้สำหรับการตั้งชื่อ ยกเว้น ID และ OK

โดยทั่วไปการตั้งชื่อไม่ว่าชื่อ class, method, อื่นๆ จะต้องใช้เป็นแบบ Pascal ยกเว้น parameter เท่านั้นที่จะใช้เป็นแบบ Camel

Reference:

23 GOF Design Pattern

Creation Patterns

Structural Patterns
Behavioral Patterns
Reference:

Visitor Pattern

เป็นส่วนที่ไปทำงานบนระบบอื่น เพื่อให้ระบบอื่นเรียกใช้




Mediator Pattern




Interpreter Pattern

เป็นการแปลงข้อมูลจาก format หนึ่งไปยังอีก format หนึ่ง หรือการ convert ข้อมูล


ตัวอย่างของ Interpreter pattern เช่น parser, XML parser

Builder Pattern




Bridge Pattern

Bridge pattern will decouple an abstraction from its implementation so that the two can vary independently
แต่จะทำให้ระบบมีความซับซ้อนขึ้น และมี performance ต่ำลง แต่ว่าจะช่วยให้ระบบมีความยืดหยุ่นมากขึ้น



State Pattern

The State Pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.




Proxy Pattern

โดยเมื่อก่อนใช้คำว่า Stub โดยมี Skeleton เป็น implementation หรือ object เป็นตัวที่ตรงกันข้ามกับ Facade คือเป็นตัวกั้นทางออก กั้น request จากภายในระบบกับระบบภายนอก




Observer Pattern

The Observer Pattern defines a one-to-many dependency between objects so theat when one object changes state, all of its dependents are notified and updated automatically.

Observer เช่น เรา subscribe blog เอาไว้ เมื่อมีการ publish subject ใหม่ ก็จะส่ง subject นั้นๆ มาให้ เป็นลักษณะเดียวกับ Event-base system, Event-driven system หรือที่ใช้กันใน Listener
ข้อเสียคือถ้ามี hacker เข้ามา hacker ก็จะเห็นข้อมูลเหมือนกับ observer 

Observer มีอยู่ 2 แบบ
  1. publish
  2. subscribe




Template Pattern

เป็นการทำ template ไว้ให้เลย



Singleton Pattern

The Singleton Pattern ensures a clas has only one instance, and provides a global point of access to it.





Factory Pattern

The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.




The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.
Abstract Factory จะเป็น Interface สำหรับ Factory Class เพื่อให้ Factory Class ในระบบมี pattern เดียวกัน เช่น มีชื่อ Factory Method เดียวกัน




Facade Pattern

เป็นตัวกั้น request จากภายนอกที่จะเข้ามาเรียกการทำงานภายในระบบ



ตัวอย่างของ Facade pattern เช่น Front Controller ซึ่งเป็นตัวกั้น request จาก UI กับระบบภายใน

Decorator Pattern

The Decorator Pattern attaches additional reponsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.




Iterator Pattern




Composite Pattern

Compose objects into tree structures to represent part




Strategy Pattern

The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
มักใช้ร่วมกันกับ Bridge pattern




Strategy Pattern เป็น pattern ที่เปลี่ยนแนวความคิดจากการใช้ Inheritance มาเป็น Composition แทนซึ่งมีความยืดหยุ่นกว่า และเป็น pattern ที่ใช้ในอีกหลายๆ pattern ด้วย

Design principle


  • Encapsulate what varies. - Identify the aspects of your application that vary and separate them from what stays the same.
  • Program to an interface, not an implementation.
  • Favor composition over inheritances.
  • Strive for loosely coupled designs between objects that interact.
  • Classes should be open for extension, but closed for modification.
  • Depend upon abstractions. Do not depend upon concrete classes.
  • Only talk to your friends.
  • Don't call us, we'll call you.
  • A class should have only one reason to change.

หรือในอีกมุมหนึ่งจะดูตามหัวข้อ

  • Communication Path and Access Channel 
    • Communication Path เป็นการกำหนดเส้นทางสือสารระหว่าง Element ต่างๆ
    • Access Channel เป็นการกำหนดการเข้าถึง Element
  • Coupling and Cohesion
  • Modularity คือการกำหนดหน้าที่ (method) และคุณสมบัติ (property) ให้โมดูลมีความสมบูรณ์ และมีความอิสระ ไม่พึ่งพาโมดูลอื่นๆ
  • Classification ต้องใช้ Design Principle หลายชนิด 
    • Association, Aggretation, Composition
    • Hierarchy, Generalization, Specialization
    • Packaging
  • Hierarchy, Generalization and Specialization
  • Information Hiding, Encapsulation and Abstraction
  • Contract, Boundary and Interface Design
  • Capability, Operation and Method
  • Dispatch and Delegate
  • Association, Aggregation and Composition


Reference: Head First Design Patterns - O'reilly

Software Quality

สำหรับคนทำงาน IT ทั้งคนวิเคราะห์ คนเก็บ requirement และทั้งสำหรับลูกค้าที่กำลังมองหา software


Software Quality (หรือเรียกว่า Quality Attribute) ซึ่งมีด้วยกันหลายตัว โดยระบบซอฟต์แวร์ควรจะต้องคำนึกถึง

  • Availability ความพร้อมในการให้บริการ
  • Modifiability สามารถปรับเปลี่ยนความสามารถได้
    • Customizibility customize ได้ (เช่น หน้าจอ) 
    • Extensibility เพิ่มเติมความสามารถ (feature) ภายหลังได้
    • Integrability ทำงานติดต่อกับ legacy system ได้ เน้นด้าน low level เช่น OS, network, protocol
    • Interoperability ทำงานร่วมกันได้ โดยปราศจากข้อจำกัด เน้น high level เช่นทำงานร่วมกับ function ต่างๆ
    • Manageability 
    • Maintainability
    • Portability ทำงานข้ามแพลตฟอร์มได้
    • Scalability รองรับการขยายตัวของการประมวลผลที่เพิ่มขึ้น (vertical, horizontal)
    • Supportability รองรับ เช่น OS, virtual machine, hardware
  • Performance ประสิทธิภาพ, การใช้ resource
  • Security ความปลอยภัย (hardware, network, software)
    • Safety ปลอดภัยต่อชีวิตและทรัพย์สิน สำหรับ software ที่เกี่ยวข้องกับความปลอดภัย เช่น software ควบคุมลิฟต์
  • Testability ทดสอบได้
  • Usability ใช้งานง่าย, ได้ประโยชน์ (การประมวลผล และความรู้สึก)
  • Reliability มีความน่าเชื่อถือ (การประมวลผล และความรู้สึก)
โดยในระบบหนึ่งๆ อาจจะมี Key Quality (หรือเรียกว่า Architectural Driver) ประมาณ 4 - 7 ตัว ถ้ามากกว่า 7 ตัวจะเยอะเกินไป ยกเว้นในกรณีระบบใหญ่ๆ เท่านั้น

Thailand SPIN 2013

พอดีได้มีโอกาสไปงานค่ะ ไปงานสัมมนาหลังจากไม่ได้ไปงานแบบนี้มานานมาก เพราะไปทีไรก็รู้สึกว่าไม่ได้อะไรเท่าไร แต่อยากบอกว่างานนี้เป็นงานที่คิดว่าคุ้มค่ะที่ไป ไม่เคยได้เจองานสัมมนา IT แบบเสวนาแบบนี้เลย แต่ต้องบอกว่าประทับใจค่ะ ได้อะไรมากกว่าที่คิด

และอยากแชร์บางอย่างที่ได้มาเอาไว้ค่ะ ในงานช่วงเช้ามี section ของการเสวนา Do and Don't ซึ่งจากที่ได้ฟังมาย่อยได้ดังนี้ค่ะ (ขออภัยที่ใช้ภาษาอังกฤษ เพราะว่าตอนจดมาภาษาอังกฤษมันพิมพ์ได้เร็วกว่า)

Requirement phase

- Don't collect requirement from template. หรือถ้าจะใช้ก็ต้องใช้อย่างเข้าใจค่ะ
- Find problem first before requirement.
- Don't use same practice in different project.
- Tester should involve in requirement at requirement phase (almost finish phase), don't wait until test phase
- Don't call it requirement, because customer will be afraid to commit.

Analysis phase

- Don't use much time - do analyse very short, because requirement will continuously change .
- Reuse design as much as you can.
- If testers are for testing function, don't ask technical specification.
- Don't design alone. Do it with all team, with tester, BA, PM, customer, etc.
- Don't over design.

Coding phase

- Don't forget unit test.
- Send test data to developer.
- Tester don't need to ask developer for any to-do check list.
- Do unit test or automated test at coding phase.
- Make developer and tester work together.

Test phase

- Do defect management.
- Do root cause management.
- Do video record.
- Do test case priority.

Deploy phase

- Don't wait to deploy production at last. beware load balancing or other environment change, etc.

Maintenance phase

- Revise test case from production incident.
- Log incident.
- Don't forget production life cycle, that should include maintenance.
- Don't relocate staff frequently.

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

นอกจากนี้ ยังได้ความรู้เกี่ยวกับ Agile Principles ด้วย ซึ่งหลายคนก็อาจจะรู้แล้ว ก็ข้ามไปค่ะ

Agile principles

  1. Individuals and interactions over processes and tools.
  2. Working software over comprehensive documentation.
  3. Customer collaboration over contract negotiation.
  4. Responding to change over following a plan.
ซึ่งทั้งนี้วิทยากรแนะนำว่าสำหรับใครที่จะทำ Agile ให้ดูเรื่อง TDD (Test Driven Development) ให้ดีๆ ค่ะ และควรจะหา automated test tools เพราะว่าการทำ Agile จะต้องทำ regression test บ่อยมาก


Reference: 

Definitely looping load Gmail offline

Do you have same problem with me? Chrome keep trying load Gmail Offline all time and show status message "Waiting for AppCache"

Try this. On address bar, type

chrome://appcache-internals/

and click Remove everything that you think it's related with Gmail to remove AppCache. If you're lucky as me, you can back to use Gmail Offline as normal.

I don't know how the problem came from. For me, I just used multiple logging in Gmail and I tried to switch to another account. But it didn't work, so I closed the tab and logged in to Gmail on-line and tried to back to use offline version again. Chrome (version 23.0.1271.97 m) counldn't load Gmail offline anymore, it show "Waiting for AppCache" all the time and the browser was shown trying to switch between 2 URL.

I tried to find the solution on internet, but I couldn't find. However, I found that Gmail Offline using HTML5 and AppCache. And from the status message, it might have crash on AppCache. So if I clear AppCache, it should back to normal. And yes, it works.