Bạn mới học Java và những kiến thức trên lớp chưa thực sự rõ ràng để bạn có thể hiểu ngôn ngữ lập trình OOP là gì? Nó có gì khác so với những ngôn ngữ thủ tục mà bạn đã học? Hay bạn vẫn chưa biết phải bắt đầu từ đâu để có thể học và làm việc với Java?

Trong thời gian vừa qua, do bận công việc nên tôi không đăng thêm được các bài viết mới mặc dù rất "máu" chia sẻ những hiểu biết về công nghệ cho các bạn. Tôi nhận được rất nhiều email, các comment trên blog và cả Youtube, phần lớn các bạn đều chia sẻ những khó khăn của mình khi đang học Java cũng mong muốn tôi đăng thêm các ScreenCast Tutorial và bài viết về Java. Tôi cảm ơn các bạn đã ủng hộ, đón chờ những bài viết của tôi!

Tôi định viết các bài về những công nghệ mới, kỹ thuật mới trong quá trình làm việc thực tế nhưng nhận thấy phần lớn các bạn đến với blog đều là những người mới học nên tôi viết bài này với mục đích giúp các bạn ôn lại, củng cố lại các kiến thức về OOP trước khi va chạm những bài toán khó hơn.

Nếu bạn đã xem các ScreenCast Tutorial của tôi thì bạn sẽ nhận thấy rằng học lập trình C trước là 1 lợi thế để có thể bắt đầu và tiếp tục học các ngôn ngữ cùng họ C (Java, C#, PHP,...). Tuy nhiên, học lập trình OOP không phải bắt đầu từ những câu lệnh khai báo biến, khai báo phương thức hay cách sử dụng các câu lệnh if...else, for, while, do..while.... mà học lấy tư tưởng chủ đạo của ngôn ngữ lập trình hướng đối tượng.

Ngôn ngữ lập trình hướng đối tượng có những khái niệm và kỹ thuật sau mà bạn cần phải nhớ và nắm chắc:

Tính bao đóng/đóng gói (Encapsulation)


Tôi tin rằng khi bạn va vấp vào khái niệm và kỹ thuật này lần đầu bạn sẽ không thể hiểu nổi nó là cái gì? Tại sao phải dùng nó? Tại sao phải tuân thủ?... khi mà bạn đã quen với lập trình dạng thủ tục.

Tôi cũng đã mất 1 khoảng thời gian để tìm hiểu xem tính đóng gói này nó là gì? Sử dụng như nào? Khi tôi mới bắt đầu học Java. Cuối cùng tôi nhận thấy 1 điều rằng: "It's so amazing...!".

Tính đóng gói trong ngôn ngữ lập trình hướng đối tượng thực sự rất hữu ích và nó rất quan trọng trong khi lập trình, viết các đoạn mã chuẩn OOP.

Tuân thủ và sử dụng tính đóng gói sẽ giúp bạn:
- Tổ chức mã lệnh tách biệt, độc lập, không phụ thuộc, các đoạn mã không phải "đi tìm kiếm, lấy thông tin" từ Class khác.
- Nghiệp vụ xử lý rõ ràng, minh bạch. (VD: 1 Class xử lý các nghiệp vụ bán quần áo thì nó chỉ chứa các đặc điểm và hành vi xử lý cho nghiệp vụ bán quần áo chứ không chứa bất kỳ các đoạn mã nào xử lý cho việc mua thực phẩm trong siêu thị).
- Có thể tùy chỉnh, cấp phát các tính năng cho phép để giao tiếp với các đối tượng khác. (Giới hạn thao tác với các trường dữ liêu, trạng thái của đối tượng).
- Che giấu các giá trị và trạng thái của cấu trúc dữ liệu trong 1 Class. (Có nghĩa rằng không cho phép các đối tượng khác truy xuất và chỉnh sửa trạng thái 1 cách trực tiếp)
- Giúp mã nguồn dễ bảo trì, nâng cấp do mã lệnh được sắp xếp và được đóng gói trong 1 Class có nhiệm vụ/vai trò cụ thể.

Vậy, sử dụng kỹ thuật đóng gói trong lập trình hướng đối tượng như nào?

Để sử dụng kỹ thuật đóng gói bạn phải tuân thủ quy tắc "Chỉ mở cho sự mở rộng và đóng cho sự sửa đổi". "Đóng/mở" ở đây có nghĩa là cách sử dụng hiệu quả 2 từ khóa: private, public.

Tất cả những thuộc tính/trường dữ liệu/trạng thái (gọi chung là Properties) bạn phải khai báo với từ khóa là private. Tùy thuộc vào mục đích sử dụng và mục đích cung cấp các tính năng, bạn sẽ sử dụng từ khóa public với các phương thức có nhiệm vụ sửa đổi thuộc tính của đối tượng - đây là kỹ thuật sử dụng cặp phương thức Getter/Setter. (thuộc tính có của đối tượng có thể thay đổi lúc run-time)

/**
 *
 * @author code4lifevn
 */
public class EncapsulationExample {
    private String name;
    private int age;

    public EncapsulationExample() {
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
}

Ví dụ không sử dụng kỹ thuật đóng gói:

/**
 *
 * @author code4lifevn
 */
public class EncapsulationExample {
    public String name;
    public int age;

    public EncapsulationExample() {
    }

}



/**
 *
 * @author code4lifevn
 */
public class Main {
    public static void main(String[] args) {
          EncapsulationExample example = new EncapsulationExample();
          example.name = "Do Manh";
          example.age = 23;
    }
}


Với đoạn mã trên, các thuộc tính public đều có thể dễ dàng truy xuất và giá trị bị sửa đổi từ đối tượng khác - điều này khiến cho dữ liệu không an toàn.

Lấy ví dụ 1 trường hợp, bạn chỉ muốn các đối tượng khác chỉ được phép lấy thông tin/trạng thái chứ không được phép thay đổi thông tin/trạng thái của đối tượng chẳng hạn, việc sử dụng các thuộc tính public không thể giải quyết được bài toán này và nếu có cố gắng viết các đoạn mã hạn chế sửa đổi trạng thái thì phần logic cũng nằm ở Class khác chứ không phải Class mà mình muốn xử lý.

Để khắc phục vấn đề này, bạn áp dụng kỹ thuật đóng gói (Encapsulation) để che giấu thông tin/trạng thái của đối tượng và chỉ cung cấp ra ngoài những tính năng mà các đối tượng khác được phép sử dụng trong khi giao tiếp.

/**
 *
 * @author code4lifevn
 */
public class EncapsulationExample {
    private String name;
    private int age;
    private String gender;

    public EncapsulationExample() {
        gender = "Male";
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }
    
}


Với các đoạn mã trong class EncapsulationExample, thuộc tính Gender chỉ cho phép lấy dữ liệu, ngăn cản việc thay đổi giá trị trên thuộc tính này bằng cách chỉ cung cấp 1 phương thức Getter.


/**
 *
 * @author code4lifevn
 */
public class Main {
    public static void main(String[] args) {
          EncapsulationExample example = new EncapsulationExample();
          example.setName("Do Manh");
          example.setAge(23);
          System.out.println("Name = " + example.getName());
          System.out.println("Age = " + example.getAge());
          System.out.println("Default Gender = " + example.getGender());
    }
}


Với mã ví dụ trên, bạn không thể tác động vào thuộc tính Gender từ đối tượng khác mà chỉ có thể lấy được giá trị mặc định của nó.

Khái niệm / kỹ thuật về tính Đóng Gói trong lập trình OOP khá đơn giản và rất hữu ích khi bạn muốn mô tả và thiết kế các đối tượng với các logic xử lý nghiệp vụ chi tiết với từng vai trò cụ thể.
Xem bài viết: Những khái niệm lập trình OOP cơ bản (P.1) - Ví dụ về Tính Đóng Gói

1 nhận xét:

  1. Top 10 best casinos in Atlantic City - MapyRO
    Borgata 속초 출장마사지 Hotel Casino & Spa 안양 출장샵 in Atlantic City offers 3131 rooms, plus a 강릉 출장샵 casino, a 영천 출장샵 seasonal outdoor swimming pool and a full-service 고양 출장마사지 spa. Borgata Hotel Casino & Spa

    Trả lờiXóa

 

code4lifevn team

Thanh niên nghiêm túc :)

Name: Manh Do

Age: years old

Job: Senior Java and Mobile Developer

Country: VietNam

Name: Hung Nguyen

Age: years old

Job: Android Developer

Country: VietNam

Name: Trung PH

Age: years old

Job: Senior iOS and Android Developer

Country: VietNam

Name: Điệp NT

Age: years old

Job: Senior .Net and Android Developer

Country: VietNam