Home
Breakthrough on programming: How to Get Out of the Intermediate Rut
 
[Most Recent Entries] [Calendar View] [Friends]

Below are the 9 most recent journal entries recorded in programming101's LiveJournal:

    Saturday, August 25th, 2007
    10:50 pm
    Access control
    Access control

    จะว่าไป type หรือ access control ไม่ได้ เป็นสิ่งที่จำเป็นต้องมีของ OOP แต่ถ้าไม่มี มันจะเทำให้ OO system ไม่ชึบชับเท่าที่ควร
    อย่างพวก script language ที่กระแดะมี oo feature

    access control มีอยู่ใน programming language ทั่วไป ไม่ว่าจะเป็น OOP, functional หรือ procedural ตัวอย่างเช่น scope ของ variable
    ที่ variable ที่ประกาศให้เป็น local ใน function จะไม่สามารถถูก access ภายนอก function ได้ นี่ก็เป็นตัวอย่างของ access control อย่างหนึ่ง

    นอกจาก access control ปกติ ที่มีอยู่ใน concept ของ local/global variable แล้ว เนื่องจาก OOP มันมี relation ของ object มี inheritance,
    นอกจากนั้น language อย่าง java มี concept ของ package ทำให้มันสามารถมี access control เพิ่มขึ้นมาจากปกติ
    เพื่อให้เกิดสิ่งที่เรียกว่า _ encapsulation _ อย่างสมบูรณ์ ตัวอย่างเช่น public, private, protected และ package private ของ java

    คือจริงๆระบบ access control แบบนี้ของ java มองได้ว่ามันคล้ายๆกับ ระบบ permission ของ unix system

    คือจริงๆ ถ้าจะให้มี access control แบบหรู๋หร๋ากว่านี้ก็ได้ มี paper หลายอันนำเสนอ ระบบ access control แบบที่ programmer สามารถ set
    ขึ้นมาที่ compile time แล้วเกิดการ check ที่ static

    ok มาพูดถึงระบบ oo access control ของ java แล้วกัน, อย่างที่บอก java มี package, นอกจาก public กับ private มันเลยมี package-private
    ขึ้นมา

    public คือ ไม่ว่าใคร อยู่ในอยู่นอก class ก็มา access ได้
    private คือ ไม่มีใครมา access ได้ยกเว้น method ใน class เดียวกัน
    package-private ตัวนี้ใน java ไม่มี keyword คือ ถ้าไม่ประกาศ public/private หรือ protected, java มันจะ imply ว่าเป็น package-private นั่นเอง
       ความหมายของมันก็คือ ถ้าอยู่ใน package เดียวกัน access ได้ ถ้าอยู่นอก package อด access, benefit อย่างหนึ่งคือเอาไปทำ static-factory
       เพื่อ ซ่อน type ของ class ได้ดังที่เคยอธิบายไป
    protected คือ ตัวเอง และ subclass ในสายเดียวกัน access ได้
    10:50 pm
    System F
    System F

    มันคือระบบที่ทำให้ใช้ Type เป็น parameter ของ function, class, collection, 9ล9 ได้ ที่ compile time
    มันไม่ใช่ระบบ template ของ C++ ที่มา generate code ขึ้นที่ compile time โง่ๆอะไรประมาณนั้น นี่มันเป็น type system
    ไม่ต้อง generate มันมี rule ที่ทำให้ยัด parameter เข้าไปใน language แล้ว semantic มัน make sense

    language อย่าง ml/ocaml/haskell มี system f build in ตั้งแต่เริ่มเดิมที Java/C# รู้สึกจะมายัดทีหลัง

    เอาเป็นว่า ถ้าท่านอ่านมาถึงนี่แล้วคิดว่าคงจะ _ เห็นแสง _ แล้วหละ
    ไปอ่าน paper, ระบบ generic ของ Java เองแล้วกัน ขี้เกียจเขียนแล้ว ผมรู้ไม่ค่อยลึก เจออะไรหนือๆ ก็มาบอกผมด้วยละกัน
    ผมใช้แต่ generic พื้นๆ รู้สึกว่ามันยังเพียงพอกับความต้องกัน ยังไม่ค่อยเห็นแสงเหมือนกัน

    http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

    จริงๆมี paper ของ C# รู้สึกระบบจะต่างกันหน่อย

    http://research.microsoft.com/~akenn/generics/index.html
    10:49 pm
    covariance - contravariance - invariance
    covariance - contravariance - invariance

    OK จากเรื่อง subsumption ได้กล่าวถึงว่าสำหรับ function
    input argument เป็น contravariant
    return เป็น covariant

    มาดู array มั่ง ดู กรณีที่ array มี แค่ 1 element
    มันก็คล้ายๆกับ function ที่ มี method get/set ( SomeObject )
    แต่เวลา get จะได้สิ่งที่เคย set ไว้ นั่นคือ set อะไรก็ได้อย่างนั้น เวลา get

    ถ้า array เป็น covariance จะเกิดอะไรขึ้น มันก็จะเกิดเหตุการณ์แบบว่า

    (code1)

    B <: A
    C <: A

    B[] b = new B[1];
    A[] a = b;
    a[0] = new C();
    B b = b[0];  // type มันจะ error

    แล้วถ้า array เป็น contravariance หละ

    (code2)

    C <: B <: A

    B[] b = new B[2];
    b[0] = new B();
    C[] c = b;
    c[1] = new C();
    C cx = c[0]; // ไอ้นี่จะผิดแล้ว

    คือ Java/C# รู้สึกว่า Array จะเป็น covariance แบบข้างบน (code1) คือมันจะ compile ผ่าน แต่จะไปตายที่ runtime ที่บรรทัด
    assignment เลย คือ language เหล่านี้มันจะเก็บ type information เวลา มีการ assign ของผิดๆเข้า array มันจะเช็คทุกครั้ง
    นอกจากประสิทธิภาพจะไม่ดีแล้ว มันยัง check ที่ static ไม่ได้อีก

    Java/C# ไม่ support แบบ (code2) จริงๆ จะทำให้ support ก็ได้ แค่ไป check runtime ตอน read ค่าออก แต่มันจะไม่ค่อยมีประโหยดเท่าไหร่

    คือจริงๆ เนี่ย การที่ทำให้ array เป็น co หรือ contra เนี่ย มันทำให้การ check ที่ compile time เจ้ง มั่งเป็นของไม่ดี array ใน language ที่เน้นหนัก
    ด้าน static เลย treat array เป็น _ invariance _ คือ จะมา subsume collection ไม่ได้

    Java/C# มันเลยได้ออก system F (aka generic ใน java/collection template ใน C#) เอาไว้แก้ ให้ collection เป็น invariance ถ้าจะให้เป็น co
    ต้องทำ sink/source type ซึ่งจะกล่าวต่อไปในบทของ system F


    Reference หละ reference ถ้ามองเผินๆก็เหมือนกับ array ที่มีช่องเดียว ดั้งนั้น มันควรเป็น invariance ว่ามั้ย
    แต่ ทำไมมันแบบนี้ได้

    B <: A
    B b = new B();
    A a = b;

    สาเหตุก็เพราะ reference มัน write ไม่ได้ การที่เรา assign ค่าเข้า ตัว reference นั้น ค่ามันได้ถูก set มาอยู่แล้ว มันไม่เปลี่ยนแปลง
    มันจะเหมือนกับ source type คือ read only ดังนั้น เราจึงสามารถ

    B <: A
    C <: A
    B b = new B();
    A a = b;
    a = new C(); // นี่ไม่ใช่การ set ค่าเข้าไปใน reference แต่เป็นแค่การเปลี่ยน pointer ของ reference ไปชี้ยัง object อีกตัว

    คือจะสังเกตุว่าในกรณี function, input argument เป็น contra, return output เป็น co, ในกรณีของ reference เป็น co
    คือถ้าดูดีๆ การ return output กับการใช้งาน reference มันคือ การ _ read _ มันเลยคิดได้ว่า ถ้าเป็นการ _ read _ จะสามารถเป็น covariant ได้
    ส่วน array
    ถ้า array เนี่ยถ้า เป็น immutable array คืออ่านได้อย่างเดียว มันก็ OK ใช่มั้ย ที่จะเป็น covariance (ถ้าไม่มีบรรทัดสุดท้ายของ code1)
    ถ้า array สามารถ write ได้อย่างเดียว ไม่สามารถ read ได้ มันก็ OK ใช่ไหม (ถ้าไม่มีบรรทัดสุดท้ายของ code2)
    คือเนี่ย การ function ส่วนที่ input argument ซึ่งเปรียบเสมือนการ _ write _ ค่าเข้า function เป็น contra ส่วน array ถ้า write อย่างเดียว
    ก็เป็น contra ได้ เลยคิดว่าได้ว่า _ write สามารถ เป็น contra ได้ _
    แต่ array มันเสือกได้ทั้ง read/write มันเลยต้องกลายเป็น _ invariance _

    write อย่างเดียวจะเรียกว่า sink type คือ ทุกอย่างจมลงไปหมด ไม่ได้ผุดได้เกิด
    read อย่างเดียวจะเรียกว่า source type คือ ทุกอย่างเป็น source จะมาเขียนไม่ได้

    system F ได้ใช้ sink source type ทำให้ collection ทำ co-contra variance ได้
    10:49 pm
    Subsumption
    subsumption

    มันคือเรื่องที่เกิดขึ้นเนื่องจากการ subtype, subsumption คือการเปลี่ยน type ของ object จาก subtype เป็น supertype ในบาง context ของ
    program

    คือ สมมุติมี K <: N และมี function

    void AAAA (N n) {
        n.someMethod();
    }

    K k = new K();

    AAAA(k);

    คือเนี่ย k แปลงร่างไปเป็น N, ถ้า subclass = subtype ในกรณีนี้, มันยอมรับได้เพราะ K เป็น subtype ของ N ทำให้ควรจะมี behavior คล้ายๆ N

    มองง่ายๆนี่เหมือนเป็นการ upcast ซึ่งปลอดภัย

    แต่ถ้า N <: K มันจะไม่ work เพราะมันจะเป็นการ downcast ทันที ซึ่งเป็นอันตราย กล่าวคือ someMethod อาจจะมีอยู่ใน N แต่ไม่มีอยู่ใน K
    ก็เป็นได้

    Java ยอมให้มีการ downcast อาจจะเป็นเพราะแต่ก่อนยังไม่มี system F (aka generic) เวลาเก็บอะไรเข้า collection เป็น type Object
    พอเวลาเอาออกต้อง downcast กลับ ซึ่งนี่ไม่ใช่ compile time มันจึงเกิด class-cast exception ขึ้นได้ คือห่วยอะนะ อย่าไปใช้ถ้าไม่จำเป็น


    ที่นี่เรื่องวุ่นๆก็เกิด เมื่อ มีการ override method

    เนื่องจากการ subtype ทำให้ต้อง guarantee ว่า object ของ subtype สามารถเอาไป replace object ของ supertype ได้

    1. argument ของ method มันเลยจำเป็นจะต้อง มี type ที่ใหญ่กว่าหรือเท่ากับ ของ supertype เพราะถ้ามันเล็กกว่า เวลาเอาไป subsume มันจะรับ
    argument กันไม่ได้

    ตย.

    A <: K <: N

    class OldCode {
        void xxxx (K k);
    }

    OldCode oldCode = new OldCode();
    K k = new K();
    oldCode.xxxx (k);


    ถ้า subclass ไป override xxxx โดยที่ประกาศเป็น

    class NewCode extends OldCode {
        void xxxx (A a);
    }

    OldCode oldCode = new NewCode();
    K k = new K();
    oldCode.xxxx (k); // ไม่ compile เพราะ A เล็กกว่า K

    2. ส่วน return value ต้องมี type ที่เล็กกว่าหรือเท่ากับ type ของ supertype เพราะถ้า return type ที่ใหญ่กว่าออกมา มันอาจจะ conflict กับ
     type ของ variable ที่เอาไปรับ object ที่ return ออกมาก็ได้

    K yyyy ();

    แล้วโดน override เป็น

    N yyyy ();

    ถ้ามี code เก่าซึ่งเคยเรียก

    K k = someObj.yyyy ();

    แต่ yyyy โดน override ให้ return type N ออกมา เนื่องจาก K <: N มันไม่สามารถ subsume object ของ type N ไปเป็น type K ได้
    เพราะมันจะเป็นการ downcast ซึ่ง check ไม่ได้ที่ static

    ดังนั้นสรุปก็คือ แบบข้างล่างเนี๊ย OK compile ผ่าน

    A <: K <: N

    class OldCode {
        K xxxx (K k);
    }

    class NewCode extends OldCode {
        A xxxx (N n);
    }

    การที่ มีการเปลี่ยนจาก type เล็ก ไปเป็น type ใหญ่ มันมีชื่อว่า _ contravariant _
    ส่วนการเปลี่ยนจาก type ใหญ่ ไปเป็น type เล็ก มันจะมีชื่อว่า _ covariant _

    กล่าวคือ argument ของ function ถือว่าเป็น contravariant ส่วน return type ของ function เป็น covariant
    ซึ่งก็คือการที่เราสามารถถ่าง type ของ argument ให้ใหญ่ขึ้น และ หด return type ให้เล็กลง โดยที่ client ที่เรียก function
    ยังเรียกเหมือนเดิม ไม่พัง

    หรืออีกนัยหนึ่ง

    ถ้า

    B <: A

    แล้ว

    B method (A) <: A method ( B )

    นั่นเอง
    10:48 pm
    Static and dynamic dispatch
    static and dynamic dispatch

    เวลา object ถูก subsume ไปเป็น supertype ถ้ามี method อันหนึ่งถูกเรียกขึ้นมาจาก object
    จะรู้ได้ไงว่ามันเป็น method ของ actual type ของ object อันนั้น หรือเป็น method ของ supertype ของ object

    คือมันต้องดูที่ language นั้นมัน define ตรงนั้นไว้เป็นอะไร
    ส่วนมากมันจะเป็น dynamic dispatch ซึ่งก็คือ method จะถูกเรียกจาก actual type ไม่ว่ามันจะถูก subsume เป็นอะไร
    ซึ่งนี่เป็นวิธีของ java ด้วย

    ส่วน C++ โดย default แล้วก็เป็น dynamic แต่ถ้าเกิดเรียกด้วย colon ประมาณว่า object::something มันจะเป็น static dispatch ทันทีซึ่งจะไป
    เรียก method ของ type ที่กำลังเป็นอยู่ จริงๆแล้วรู้สึก C++ มั่งมีรายละเอียด dispatch อื่นๆ ที่งงมาก เอาไปว่ามันเลอะเทอะก็แล้วกัน

    สำหรับ java, this เป็น dynamic dispatch คือไม่ว่าจะเรียก this ที่ใน superclass หรือ supersuperclass
    มันก็จะ refer ถึง actual class ของ object

    ส่วน super นี่ก็คงจะเดากันได้ว่าต้องเป็น static เพราะมันสามารถใช้ information ของ class relation ที่ compile-time ได้สบายๆ
    10:47 pm
    Inheritance and delegation
    inheritance and delegation

    เมื่อพูดถึง inheritance ก็ต้องนึกถึง subclass
    เมื่อนึกถึง subclass ก็ต้องนึกถึง subtype

    subtype ใช้สัญลักษณ์ว่า <:
    คือสมมุติ A เป็น subtype ของ B จะเขียนว่า A <: B
    ความหมายของมันก็คือ สามารถนำ object type A ไปวางแทน object type B ได้แบบที่ behavior ไม่เปลี่ยนแปลง

    ส่วน subclass เป็น term ของ class-based OO ที่ทำให้ subclass มี method ของ superclass

    คงเคยอ่านกันแล้วใช่ไหมว่า subclass ไม่ใช่ subtype ซึ่งมันก็คือว่า concept ของการ subclass นั้นยังไม่สามารถ guarantee
    subtype propertyได้

    สาเหตุเนื่องจากการ override method ทำให้ behavior ของ method เปลี่ยน คือสมมุติ มี method setBalance ทำการ increaseBalance
    แต่โดน subclass override ไปเป็นการ decrease balance แทน พอเวลาเอา object ของ subclass ไป replace แทนของ superclass มันก็จะ
    ไม่ work

    วิธีแก้หรือคิดง่ายๆในการ override ไม่ให้มัน violate subtype property ก็คือ

    1. precondition ของ subclass ต้อง weak กว่าหรือเท่ากับ precondition ของ superclass

    ซึ่งก็คือ ถ้า precondition ของ subclass เกิด strong กว่ามันก็เอาไป replace ไม่ได้ ถูกมั้ย

    2. postcondition ของ subclass ต้อง strong กว่าหรือเท่ากับ postcondition ของ superclass

    ซึ่งก็คือ ถ้า postcondition ของ subclass เกิด weak กว่า มันก็แปลว่า subclass ทำงานไม่ได้เท่า superclass เลยเอาไป replace แล้วไม่ work

    คือจริงๆแล้วใน OOP นั้น inheritance = evil เพราะนอกจากเหตุผลเรื่อง override แล้ว มันยังทำให้เกิด strong coupling ระหว่าง
    superclass และ subclass. coupling นั้นเป็นสิ่งที่ไม่ค่อยดี เพราะมันทำให้เกิด dependency ขึ้น และทำให้การ maintain software
    เกิดความวุ่นวายได้ในบางอารมณ์

    คือถ้ามีคนไปแก้ superclass เปลี่ยน contract precondition/postcondition ไปลบ method เปลี่ยน signature มันก็จะเกิดความวุ่นวายขึ้น
    ต้องตามไปแก้ subclass

    จะเห็นว่าใน GOF Pattern มีแค่ Template pattern เท่านั้นที่เป็น inheritance ซึ่งจริงๆ inheritance มันก็มีประโยชน์มาก แต่ต้องใช้อย่างระวังมาก

    Delegation

    คือการ reuse อีกแบบหนึ่งที่ไม่ต้องพึ่ง inheritance เรียกง่ายว่า _ การใช้ _
    คือถ้าเปรียบ inheritance กับ delegation, inheritance มันเหมือนกับการ reuse จากภายใน, delegation คือการ reuse จากภายนอก

    delegation คือการผลักภาระไปให้ object อื่น ให้มันทำงานส่ง result กลับมา

    class KKK {
        NNN nnn;

        KKK (NNN nnn) {
            this.nnn = nnn;
        }

        void showResult () {
            System.out.println( this.nnn.getScore() );   // เนี่ยคือ delegation
        }
    }

    สาเหตุที่คนชอบ delegation มากกว่าก็เพราะ มันไม่เกิด strong coupling ระว่าง caller กับ callee

    ตัวอย่างของปัญหาคือ สมมุติ มี class A เป็นโครตพ่อ superclass มี B <: A, C <: A, D <: A

    เกิดว่า B และ D ต้องการ method เพิ่มตัวหนึ่ง เนื่องจาก ไม่อยากจะให้เกิด duplicate code เลยเอา method นั้นไปใส่ A

    ผลก็คือ C และ ได้รับ method ที่ไม่ควรจะมีอยู่ใน C เพิ่มมาด้วย มั่งก็จะเละๆ code ก็จะเริ่มเหม็นๆ

    ถ้าเป็น delegation หละ B use A, C use A, D use A, ก็จะเพิ่ม method นั่นที่ A แล้ว B กับ D ก็ไป delegate method นั้นจาก A ซะ
    คราวนี้ C ก็จะไม่มี method ที่ไม่ควรจะมีเพิ่มขึ้นมา

    คืออย่างที่บอก subclass มันคือการ reuse จากภายใน ถ้า ตกลงปลงใจไป subclass แล้ว จะไม่สามารถ _ ปิด _ อะไรที่มีใน superclass ได้

    คือถ้าเกิดกรณีนี้เกิดขึ้นแสดงว่า design เรามันเหม็นแล้ว ควรกับไปคิดใหม่ทำใหม่

    inheritance เหมาะกับ การที่ parent class มี behavior เยอะๆ เยอะๆๆๆๆๆๆ ถ้าใช้ delegation จะต้องสร้าง method มา delegate บาน
    ซึ่งการที่มี behavior บานก็แม่งๆว่ามันไม่ค่อยจะดีแล้วนะ

    แต่เนื่องจาก class ที่เราใช้ปกติๆแล้ว มันไม่มี behavior เยอะ อย่างที่บอกถ้ามีเยอะ ก็แปลกๆ ยกเว้นจำเป็นจริงๆ ดั้งนั้นเป็นเหมือนกฎว่า
    _ prefer delegation over inheritance _
    10:46 pm
    Class based
    Class-based OOP

    คือ OOP มั่งมีพวก object-based กับ class-based พวกที่เป็น object-based คือ object ไม่มี relation อะไรกับ class, ไม่มี class
    ก็สร้าง object ได้ เช่น javascript ที่เป็น prototype-based ส่วน class-based ก็มี class ซึ่งเป็น _ static _ นั่นก็แปลว่า class
    จะเป็น definition ที่ประกาศที่ compile-time

    type ก็คือ _ static _ thing มีการ declare กัน compile-time (ไม่เกี่ยวอะไรกับ dynamic type, พวก dynamic type คือ
    type ของ variable หรือ object จะเปลี่ยนแปลงได้ที่ run-time )

    static language อย่าง Java, object หรือ variable จะไม่เปลี่ยนแปลง type ที่ compile time คืออาจจะมีการ upcast หรือ
    subsume ไปเป็น Parent type แต่ type ของ object จะไม่มีการหาย ไม่มีการมา add method ที่
    runtime

    ถ้ามองง่ายๆ _ class เป็น implementation ของ type _ นั่นเอง การสร้าง class เป็นการสร้าง type ใหม่ ซึ่งการสร้าง type ใน
     java นั้น สร้างได้โดยใช้ interface นั่นเป็นที่มา ของเวลาเขียน _ classs xxx implements AnInterface _

    ดังนั้นการที่อยู่ดีๆ เขียนโปรแกรม โดยการสร้าง _ public _ class ที่ไม่ได้ implements interface ใดๆขึ้นมาลอยๆ มันคือการเสล่อ

    ดังนั้นจะเห็นว่าถ้าใช้ dynamic language โดยมากแล้วมันจะไม่มี concept ของการ declare type,
    interface ของ dynamic language ทั้งหลาย อย่าง php, python มันเลยไม่ค่อยมีความหมายอะไรเท่าไหร่

    ปล. คำว่า declare กับ define นี่ต่างกัน การ declare คือการประกาศเฉยๆ แต่ยังไม่มี definition ส่วนการ define คือการใส่ definition
    ในสิ่งที่ประกาศไปแล้ว เปรียบเสมือน implement

    โอเค เรามี type มี class แล้ว อะไรอยู่ใน type อยู่ใน class บ้างหละ

    type ถ้าตีความกัน ก็คือ ประเภท ของสิ่งๆหนึ่ง สิ่งๆนั้นทำเชี่ยอะไรได้บ้าง type จึงต้องมี method เช่น object ที่มี type Phone ควรจะ
    มีความสามารถในการ _ โทรเข้า _ และ _ โทรออก _ ได้, type ไม่ควรมี state มีแต่ behavior ดั้งนั้น type ไม่ควรมี member field หรือบางท่าน
    จะเรียกว่า member variable, member data ก็ว่ากันไปในที่นี้ใช้คำว่า _ field _

    ดังนั้นใน java เราเลยประกาศ field ลงไปใน interface ไม่ได้ (หรือได้ว่ะ แต่รู้สึกไม่ได้เอาไปใช้อะไร ?) เพราะมันไม่ make sense ใน concept ของ type, interface ใน java จึง contain
    เพียงแค่ signature ของ method ของ type นั้น

    object สามารถมี state ได้ เช่น counter object มี integer ที่เป็น counter อยู่ในภายใน ถ้า client
    มาเรียก increaseCounter, state ของ counter object ก็จะเปลี่ยน

    เนื่องจาก class เป็น implementation ของ type ดังนั้น เราจึงมี method และ field เวลา define class นั่นเอง
    เพื่อให้ _ object _ ซึ่งเป็น instance ของ class ได้รับทั้ง behavior และ state

    method ก็คือ function, function สามารถ มี input ได้หลายตัว แต่จะ return output ออกมาตัวเดียว พวก script language ที่ return output
    ออกมาได้หลายๆตัวจาก function จริงๆก็ไม่มีอะไรมาก คิดซะกว่ามัน return output ออกมาเป็น array ตัวหนึ่ง นั่นคือ function
    รับ input ได้หลายตัว return ออกมาตัวหนึ่ง

    field ก็คือ object ภายใน object, เปรียบเสมือน state ของ object, client จะใช้ method ในการเปลี่ยนแปลงหรือ access field,
    การที่ java อนุญาตให้ client access field ใน object ได้นั้นเพื่อความสะดวก จริงๆแล้ว ถ้าว่ากันด้วย concept ของ type,
    state ของ object ไม่สามารถ ถูก access ได้โดยตรง ต้อผ่าน method พวก getSomething

    คือเอาง่ายๆ สมมุติ มี class ตัวหนึ่ง NNN implement interface KKK, NNN มี field _ nnn _, เวลา object ของ NNN ถูก pass เข้า function ที่รับ
    argument เป็น type KKK เช่น _ void xxx(KKK k) _ , client จะไม่สามารถ access k.nnn ได้ ซึ่งไม่จะไม่สวย มันจะเสล่อ เหมือนกับ nnn เป็น fied
    ที่จะ access ได้เฉพาะ type NNN

    ใน java, class กับ type มันไม่ผูกขาดคือ เวลาเราสร้าง class NNN implements KKK เราจะได้ type มาสองตัวคือ KKK และ NNN ซึ่งจะว่าไป
    มันคือการเสล่อ แต่เนื่องจาก java มันมีระบบ package และ access control คนเลยสามารถ เอา class ไปเป็น private ใน package และให้ client
    access ที่ interface อย่างเดียว เช่น

    package MMM;

    public interface KKK {
    }

    class NNN implements KKK {
    }

    public class MMMFactory {
        private classMMMFactory {}

        public static KKK createKKK() {
            return new NNN();
        }
    }

    ไม่แน่ใจว่าเขียนถูกรึเปล่า แต่เท่านั้นคนภายนอก ก็ไม่สามารถ อ้างถึง NNN ได้แล้ว ที่คนจะใช้ได้คือ MMMFactory ซึ่งเป็นตัวสร้าง NNN แต่ให้คน
    refer ถึงได้แค่ KKK ซึ่งเป็น interface ของ package

    นี่บางคนเรียกว่า static factory pattern เป็น pattern ที่ต้องมี package + access control ด้วยถึงจะใช้การใช้ เป็นสิ่งที่คนทำกันใน java หรือ C#
    10:40 pm
    Object101
    Object101

    Object101 เป็น tutorial OOP ปู basic OOP เพื่อให้ไปอ่าน Pattern101
    ซึ่เงป็น tutorial ของ OOP Pattern ได้อย่างรู้เรื่องดีขึ้น

    Object101 คือการล้างสมอง เปลี่ยนความคิด ของ programmer ที่สงสัยว่าทำไมต้องเป็น OOP,
    Programmer ที่ยังไม่ใช้ OOP ในหน้าที่การงาน Programmer ที่พยายามเขียน OOP ด้วย dynamic language,
    Programmer ที่พยายามเขียน OOP แล้ว code เละกว่าเดิม หรือ reuse ลำบาก, Programmer ที่หัดเขียน Java แล้วไม่ get
    ว่ามันเหนือยังไง 9ล9

    OOP เป็น programming concept ที่มองส่วนต่างๆของโปรแกรมเป็น object หลายๆชิ้น, object เล็กๆเหล่านั้น เมื่อมา
    ทำงานร่วมกัน จะออกมาเป็นโปรแกรมที่ใหญ่ขึ้น

    ใน procedural programming เมื่อ โปรแกรมที่เขียนใหญ่ขึ้น code เยอะขึ้น การ maintain code หรือการ
     add feature เข้าไปเพิ่มให้ software จะเกิด ความยากลำบาก หรือถ้า software นั้น มีการพัฒนา ด้วย developer หลายๆ คน
    มันก็จะยิ่งว่นวายเข้าไปใหญ่

    คือการพัฒนาโปรแกรมขนาดใหญ่ ให้ดีนั้น นอกจาก OOP ยังไม่สิ่งที่ต้องทำอีกหลายอย่าง เช่น การกำหนด coding style,
     ใช้ subversion, ทำ unit test, มี automate testing system, มี code review, ใช้ AOP กับสิ่งที่ไม่ใช่ business logic,
    ใช้ data abstraction 9ล9 คือมันเป็นเรื่องที่ซับซ้อน แต่ OOP สามารถช่วยให้ความวุ่นวายในส่วนของ code ลดลงได้
    ถ้าใช้อย่างถูกวิธี

    Object101 ไม่ได้พูดถึง OOP ใน general term แต่จะพูดถึง OOP ที่อยู่ภายใต้ type system, access control, และเป็น Class based
    เพราะ OOP ในความหมายปกติ มันกว้าง อย่างเช่น การเอา dynamic language มาเขียน OOP มันเกิดความซับซ้อน
    แล้วไม่ scale เท่าที่ควร

    ทำไม OOP ถึงไม่เหมาะกับ dynamic typed language หละ  ก็เพราะ OOP มันเป็นสิ่งที่เข้าใจยาก เพราะ relation
    ของ Object/Class ต่างๆมันจะเกิดความซับซ้อนขึ้นได้ง่ายๆ ถ้าไม่มี type system มา control ก็จะเกิดความงง เช่น class นี้
    เป็น subclass ของอะไร object ของมันอยู่ object ตัวไหนใน runtime, การที่จะเข้าสิ่งเหล่านี้ได้ มันต้อง static type system
    ซึ่งจะทำให้มี editor ดีๆในการช่วย programmer เข้าใจโปรแกรม, concept ต่างๆ อย่าง interface หรือ encapsulation
    มันจะใช้การไม่ค่อยได้ ใน dynamic typed language ทำให้ OOP ด้วย language เหล่านี้ มันไม่สวย มัน guarantee property บางอย่างไม่ได้
    มันไม่ scale เท่าที่ควร ถ้า developer ทำงานร่วม project กัน แต่ใช้ dynamic typed language ก็จะแบ่งกัน code แยก
    เป็น interface ได้อย่างทุลักทุเล

    Language ที่ใช้ศึกษา object ของผู้เริ่มต้น มีหลายตัว บางคนก็สับสนว่าจะใช้อะไรดี สุดท้ายไปโหลด visual studio
    มาทำ C# .Net application ซะงั้น โดยที่ไม่ได้ยุ่งอะไรกับ OOP เลย

    คือที่แนะนำมีสามfตัวคือ Java, C# และ OCaml, Java, C# มันเหมาะกับการเรียนรู้เพราะมันง่าย และระบบของมัน มีสิ่งที่ OOP
    ควรจะมีครบ ส่วน C# อาจจะมีสิ่งที่ทำให้เขวเกินไปหน่อย, OCaml ก็จะได้ benefit ของการ infer type เข้ามาช่วย ทำให้การ
    เปลี่ยนแปลงโครงสร้างของโปรแกรมทำได้เร็วขึ้น ตราบใดที่ type ยังไม่ conflict

    OK ถ้าใช้ Java ก็ไปโหลด version 1.5 ขึ้นไป เพราะจะได้ใช้ system F แล้วไปโหลด eclipse มาด้วย
    10:08 pm
    Programming101
    focus ไปที่ programming concept, programming language,  pattern, type system, static analysis, model checking หรืออะไรก็แล้วแต่ที่เกี่ยวกับ programming

    เราจะไ่ม่กล่าวถึง library, ไม่พูดถึง algorithm, ไม่เขียนเกี่ยวกับการเริ่มหัดเขียน program หรืออะไรก็แล้วแต่ที่เราคิดว่ามันน่าเบื่อ

    เป้าหมายของเราคือการนำแสงสว่างที่เราคิดว่าสว่างสำหรับเรามาส่องหัวท่าน ให้ท่านได้เห็นว่าอะไร cool อะไร uncool อะไรเสล่อ อะไรเทพ

    เอาหละถ้าท่าน อ่านบทความแล้วเข้าใจว่าเรากำลังทำอะไรและมีอะไรที่อยากจะเขียนลงที่นี่บ้าง ให้ติดต่อเรามาโดยด่วน

    เราเขียน blog เป็นภาษาไทย เพราะคิดว่า information เทือกๆนี้ภาษาปกิตมีเยอะแล้ว แต่ยังมี thai programmer อีกมากที่ยังไม่ยอมไปอ่าน เราจึงเอานำ information เหล่านั้นมาป้อนท่าน หวังว่าท่านคงยอมรับรู้ เปิดหู เปิดตา _ ดูแสง _ เสียบ้าง
About LiveJournal.com

Advertisement