Vì sao phải sử dụng get / set

Chào mọi người, mình xem video thứ 15 của anh Đạt, có giải thích về việc vì sao phải sử dụng get và set trong class, qua cách giải thích của anh mình hiểu là cần làm như vậy để tránh người khác tự tiện truy cập vào được chương trình của mình và thay đổi nó + tránh phải sửa đi sửa lại nhiều lần khi muốn sửa cái gì đó liên quan đến biến.
Tuy nhiên, nếu chỉ mang những ý nghĩa như vậy, tại sao lại phải tốn đến 2 hàm get và set, trong khi chỉ cần một hàm có trả về giá trị luôn là có thể giải quyết được vấn đề, khi đó việc gọi ra thay vì phải gọi 2 lần thì ta sẽ chỉ cần gọi 1 lần thôi?
Vì dụ:

    string getName(string name){
         tenCanDat = name;
         return tenCanDat;
    }

Như vậy, ta đã tiết kiệm được 1 hàm void không cần thiết, đúng không các bạn?

1 Like

Hàm này có 2 vấn đề

int getName(string name){
         tenCanDat = name;
         return tenCanDat;
}

Thứ nhất tenCanDat phải là std::string, sao lại return kiểu int được?

Thứ hai, hàm tên là getName, getname có nghĩa là lấy tên. Hàm tên là lấy tên, nhưng lại có tính năng của setName, tức là đặt tên. Thế có phải treo đầu dê bán thịt chó không?

Tiết kiệm được gì đâu :slight_smile: chỉ có 3, 4 dòng code thôi, nhưng nó giải quyết được cái vấn đề là hàm nào, tên nấy. Cần gì, có nấy.

7 Likes

Ok anh, rõ ràng là em nhầm phần kiểu giá trị của hàm, là string chứ không phải int . Tuy vậy thì em vẫn thắc mắc ở chỗ là:

  1. Về mặt ngôn ngữ mà nói thì tiếng Anh phân rõ ràng như vậy, nhưng giả sử tiếng Việt thì chỉ cần 1 hàm là datTen (đặt tên) và vừa đưa vào 1 cái tên, vừa nhận ra cái tên đó là đủ đúng không anh?
  2. Về chuyện 3, 4 dòng cho hàm void đó thì với 1 biến là đúng, nhưng giả sử chương trình phức tạp có đến 10, thậm chí hàng chục biến thì không phải là tiết kiệm thêm được nhiều chứ ạ?
    Em có tham gia 1 vài dự án java, mới chuyển qua tìm hiểu C++, ở java cũng thấy người ta tốn kém như vậy mà không hiểu tại sao, không lẽ chỉ vì làm cho đúng ý nghĩa của get vs set và đồng bộ với ngôn ngữ trong cả chương trình là dùng tiếng Anh nên làm như vậy?
2 Likes

Không nên đặt tên tiếng Việt trong trường hợp get/set. Bởi vì nó đã trở thành “chuẩn” rồi.

Em tiết kiệm được cái gì khi cắt bớt 3, 4 dòng code? Nếu em muốn nói tới kích thước của chương trình thì 3,4 dòng code trên 100-200 dòng code của một class thì chỉ tầm 1-3% của số lượng code. theo anh đây là con số nhỏ, không đáng kể.

Nhưng việc code bị thiếu rõ ràng thì sẽ nhanh chóng tạo ra hàng tá lỗi, dẫn đến việc sửa lỗi trở nên rất đau đầu. Có đáng tiết kiệm không?

Anh không thấy có gì gọi là tốn kém ở đây cả. Có lẽ em quá lo lắng về việc số lượng dòng code mà không quan tâm cái quan trọng hơn là logic của chương trình rồi. Số lượng dòng code không thể hiện được chất lượng của một chương trình.

Cái quan trọng là cấu trúc, thiết kế, logic của chương trình đó.

5 Likes

Anh không thấy có gì gọi là tốn kém ở đây cả. Có lẽ em quá lo lắng về việc số lượng dòng code mà không quan tâm cái quan trọng hơn là logic của chương trình rồi. Số lượng dòng code không thể hiện được chất lượng của một chương trình.

Cái quan trọng là cấu trúc, thiết kế, logic của chương trình đó.

Đúng là những cái đó là chuẩn rồi, em chỉ hỏi vậy vì chưa ai phân tích rõ với em như anh vậy, những câu trích này giá trị của một người chuyên nghiệp này :smiley: . Cảm ơn anh nhiều ạ :smile:

4 Likes

Cơ bản lập trình hướng đối tượng thôi.

  1. Các thành phần bên trong cần giới hạn truy cập, vì thế sinh ra việc sử dụng hàm.

  2. Quy luật bất biến của module hoá, S trong SOLID , mỗi hàm chỉ làm và thực hiện một việc duy nhất. Vậy thì hàm SET thì chỉ có SET giá trị vào, còn GET thì chỉ GET giá trị ra. Không thể nhét cả GET/SET vô trong một hàm.

  3. Trong lập trình, hàm viết càng nhỏ càng tốt, càng ít logic càng tốt. Vẫn theo quy tắc cũ 80 cột / 25 hàng tối đa cho một hàm.

Với một số ngôn ngữ lập trình bậc cao như C#, thì việc GET/SET được quy về một cái gọi là ĐẶC TÍNH (hay tiếng Anh là PROPERTY), chỉ cần khai báo 1 lần trong code thôi. Nhưng về bản chất code sinh ra trước khi biên dịch thì sẽ tách ra thành 2 hàm, một GET, một SET cả thôi.

9 Likes

I moved 2 posts to a new topic: 25 dòng code cho mỗi hàm có quá ngắn?

đây là topic c++ , nhưng mình dùng PHP cũng có thể góp ý cho vui

Khi bạn không dùng get and set class bạn như thế này

class Robots extends \Phalcon\Mvc\Model
{
    public $id;

    public $name;

    public $price;
}

Còn khi dùng nó

class Robots extends \Phalcon\Mvc\Model
{
    protected $id;

    protected $name;

    protected $price;
    public function getId()
    {
        return $this->id;
    }

    public function setName($name)
    {
        //The name is too short?
        if (strlen($name) < 10) {
            throw new \InvalidArgumentException('The name is too short');
        }
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setPrice($price)
    {
        //Negative prices aren't allowed
        if ($price < 0) {
            throw new \InvalidArgumentException('Price can\'t be negative');
        }
        $this->price = $price;
    }

    public function getPrice()
    {
        //Convert the value to double before be used
        return (double) $this->price;
    }
}

Như bạn thấy mình đã ràng buộc các thuộc tính của các class đó.,do đó nó có thể tăng testability, mở rộng và bảo trì các ứng dụng. Tùy thuộc vào sự lựa chọn của bạn , bạn tin tôi đi PHP dựa trên idea C++ do đó không có lý do gì bạn không nên dùng nó

4 Likes

Cho mình hỏi nếu bạn muốn lấy Name nhưng không muốn đổi Name thì bạn lấy nó như thế nào ???

1 Like

Thì chỉ có hàm GET thôi chứ không có hàm SET. Việc SET sẽ thực hiện một lần duy nhất ở constructor hoặc tại một điểm nào đó xử lý mà phát sinh ra.

3 Likes

em xin mượn đề tài để xin trả lời thắc mắc của em về get,set.
em vẫn không hiểu tại sao mình phải dùng get,set, nếu để dễ sửa chữa giúp em minh họa qua bài dưới đây với ạ: http://codepad.org/4JoriSr3
nếu em muốn sửa f__HoanhDo bên //.h vậy nó đâu có tự thay đổi bên //.cpp đâu ạ.

Đây là 1 trong 4 đặt trưng của OOP (Encapsulation), bạn có thể search thêm bằng tiếng anh để hiểu rõ hơn.
Do đa sô chúng ta điều tự viết tự gọi nên thấy nó dư thừa so với yêu cầu của mình.
Bạn thử nghỉ bạn viết cái class đó và một người khác (cũng là coder) sử dụng class bạn viết xem.
Lúc đó bạn sẽ nghĩ rằng : nếu sau này bạn có thay đổi chỉnh sửa (convert type chăng hạn) thì người sử dụng cái class của bạn khôngcần phải sửa gi hoặc chỉnh sửa là ít nhất

2 Likes

Bạn nói rõ hơn được không ? file .h chỉ là file để khai báo lớp không phải file dùng để định nghĩa các phương thức

Thế lúc chỉ cần get để lấy giá trị thì kiếm cái gì để truyền vào hàm khi mà không biết giá trị hiện tại trong class là bao nhiêu.
Truyền bừa tham số thì sao ?

1 Like

Mình xin đóng góp ít ý kiến, thứ nhất tại sao phải có set/get: Các bạn lập trình trên C/C++ cũng biết C thao tác trực tiếp với bộ nhớ thông qua con trỏ. Vậy nếu bạn khai báo mảng có n phần tử mà bạn trỏ đến phần tử thứ n+1 thì sao. Đa phần là lỗi segmentation fault, nhưng đây là việc dễ xử lý vì nó báo ngay rồi, lỗi hiếm gặp hơn là nếu vùng nhớ đó đã đuợc alloc, C vẫn truy cập vào đuợc và khi câu lệnh thực thi như ghi đè, hệ quả biến trong vùng nhớ đó sẽ có những ứng xử không luờng trước đuợc dẫn đến cả hệ thống sụp đỗ mà nguời lập trình không biết tại sao. Do đó phuơng thức set/get ra đời, mục đích là bạn truy cập biến qua một phuơng thức mà không thể ảnh huởng đến những vùng nhớ liền kề của nó. Tiếp theo là dùng chung set/get đuợc không. Hoàn toàn đưọc, bạn có thể đặt tên hàm là IO(), vừa set vừa get. Nhưng biết khi nào set, khi nào get. Thêm một tham số IO(bool i_or_o,…), tức là trở thành vấn đề hai hàm thành một hàm nhưng thêm một tham số. Thế nhưng mọi nguời vẫn thích kiểu hàm nào ra hàm đó, cái tên nói lên tất cả, và ít tham số thôi. Thế là SET, GET đành phải chia tay nhau

6 Likes

Đặc trưng oop
lấy hoặc thay đổi gía trị của biến private nội bộ lớp thông qua phương thức get, set

1 Like

Trong C# thì Get và Set nhập chung làm một thành Properties.


int Properties{
   get{.....}
   set{.....}
}


var val = object.Properties; // get
object.Properties = val; // set

Java không biết có thế không.

2 Likes

không :joy: Toán tử cộng trừ nhân chia còn ko overload được nữa mà :joy:

Java bashing time à :kissing:

Có thể sau 5 năm nữa Java sẽ có operator overloading, 10 năm nữa sẽ có properties kiểu này. Như lambda expression thì sau khi C# có khoảng 5 năm rồi Java mới bắt đầu cho vào :kissing_closed_eyes:

4 Likes

A post was split to a new topic: Học it năm 2 nhưng kiến thức nền tảng không ổn định cả về c lẫn java thì phải làm gì?

Trong OOP thì Object là trung tâm và có khả năng tự quản :smiley: nên get/set nhiều thì nên xem lại.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?