ສະຫຼຸບ SOLID Principles ແບບ dartlang

xangnam phiasakha
LaoITDev
Published in
3 min readOct 24, 2022

ຊ່ວງນີ້ຜູ້ຂຽນກຳລັງສຶກສາ clean architecture ສຳລັບ flutter ເພື່ອວ່າງມາດຕະຖານການພັດທະນາ app ໃຫ້ທີມ mobile dev ໃນບໍລິສັດ. ເຊິ່ງມັນກໍ່ມີການກ່າວເຖິງ solid ທີ່ຜູ້ຂຽນເຄີຍສຶກສາມາກ່ອນຕັ້ງແຕ່ຮຽນມະຫາໄລແຕ່ກໍ່ບໍ່ຄ່ອຍຈະໃຊ້ແລະລະເລີຍຍກັບມັນມາເນີນນານກໍ່ເລີຍໄປທົບທວນຄວາມຈຳໃຫມ່ ແລະ ມາຂຽນສະຫຼຸບສັ້ນໆໄວ້.

S.O.L.I.D ຄືຫຍັງ?

SOLID Principles ຄື best practices ໃນການອອກແບບການຂຽນ code ແບບ OOP ທີ່ສະເໜີໂດຍໜຶ່ງໃນມະຫາເທບໃນວົງການ programing ຂອງໂລກນັ້ນຄື Robert J. Martin ຫຼື Uncle Bob ນັ້ນເອງເຊິ່ງມັນກໍ່ໄດ້ກາຍເປັນພື້ນຖານທີ່ OOP programmer ຕ້ອງຮູ້ ແລະ ປະຕິບັດຕາມພື່ອໃຫ້ code ສາມາດ maintenance ໄດ້ງ່າຍນັ້ນເອງ.

SOLID rules ປະກອບມີ:

  • The Single Responsibility Principle
  • The Open-Closed Principle
  • The Liskov Substitution Principle
  • The Interface Segregation Principle
  • The Dependency Inversion Principle

The Single Responsibility Principle (SRP)

A class should do one thing and therefore it should have only a single reason to change

class ຫຼື ທຸກຢ່າງທີ່ປະກອບເປັນ software ບໍ່ວ່າຈະເປັນ method, module, …etc ຕ້ອງມີເຫດຜົນດຽວເທົ່ານັ້ນທີ່ເຮົາຈະແກ້ໄຂມັນ.

ກົດຂໍ້ນີ້ຟັງແລ້ວອາດຈະເປັນຄຳເວົ້າງ່າຍໆແຕ່ວ່າໃນທາງປະຕິບັດແລ້ວຍາກກວ່າກົດທຸກຂໍ້ເລີຍກໍ່ວ່າໄດ້ເວລາອ່ານແລ້ວອາດຕີຄວາມໝາຍໄປວ່າໃນໜຶ່ງ class ຕ້ອງມີໜຶ່ງ method ແຕ່ບໍ່ແມ່ນແນວນັ້ນ Uncle Bob ເລີຍໃຫ້ຄວາມໝາຍທີ່ຊັດເຈນຂຶ້ນຕື່ມວ່າ:

Gather together the things that change for the same reasons. Separate those things that change for different reasons.

ລວມສິ່ງທີ່ເຮັດວຽກເພື່ອຈຸດປະສົ່ງດຽວກັນໄວ້ບ່ອນດຽວກັນແລ້ວແຍກສິ່ງທີ່ເຮັດວຽກເພື່ອຈຸດປະສົງອື່ນໄປລວມກັນໄວບ່ອນອື່ນ.

ແຮງງົງກັນໄປຕື່ມອີກລຸງ ຮະຮະຮະ ເອົາເປັນວ່າເບິ່ງໂຕຢ່າງເລີຍແລ້ວກັນ

ບໍ່ເປັນໄປຕາມ SRP

ສັງເກດເຫັນວ່າ class Rectangle ມີ method ທີ່ໄວ້ຄຳນວເນື້ອທີ່ ແລະ ສະແດງເນື້ອທີ່ທີຄຳນວນອອກມາເຊິ່ງມັນບໍ່ກ່ຽວຂອງກັນເລີຍຍເຮັດໃຫ້ class ນີ້ມີສອງເຫດຜົນທີ່ຕ້ອງແກ້ໄຂ້ຄື: ການຄຳນວນ ແລະ ການສະແດງເນື້ອທີ່.

ເປັນໄປຕາມ SRP

ຈະເຫັນວ່າເຮົາຈະແຍກອອກມາເປັນສອງ class ແລະແຕ່ລະ class ມີຈຸດປະສົ່ງດຽວທີ່ຕ້ອງແກ້ໄຂຖ້າຕ້ອງການແກ້ໄຂ້ການຄຳນວນກໍ່ໄປແກ້ຢູ່ class Rectangle ແລະ ຖ້າຕ້ອງການແກ້ໄຂ້ການສະແດງຜົນອອກສູ່ໜ້າຈໍກໍ່ໄປແກ້ຢູ່ class PrintArea.

The Open-Closed Principle (OCP)

classes should be open for extension and closed to modification.

class, module, function …etc ຕ້ອງໃຫ້ສາມາດເພີ່ມຄວາມສາມາດໃຫມ່ໆເຂົ້າໄປໄດ້ໂດຍທີ່ບໍ່ໄປເຕະຕ້ອງກັບ code ເກົ່າທີ່ມັນໃຊ້ງານດີຢູ່ແລ້ວ

ຟັງແລ້ວອາດຈະຂັດແຍ່ງຢູ່ເພີ່ມຄວາມສາມາດໃຫມ່ໆເຂົ້າໄປແຕ່ບໍ່ໃຫ້ແກ້ໄຂ້ code ເພື່ອໃຫ້ມັນກະທົບກັບໂຕເກົ່າເຊິ່ງຈິນຕະນາການບໍ່ອອກເລີຍວ່າຈະເຮັດແນວໃດ. ເອົາເປັນວ່າໄປເບິ່ງຕົວຢ່າງກັນເລີຍ

ບໍ່ເປັນໄປຕາມ OCP

class CalculateArea ເບິ່ງແບບບໍ່ຄິດຫຍັງຫຼາຍກໍ່ປົກກະຕິດີແຕ່ເມື່ອເຮົາຢາກເພີ່ມ method ຄຳນວນເນື້ອທີ່ວົງມົນເຂົ້າໄປຕ້ອງໄດ້ເຂົ້າໄປແກ້ໄຂ class CalculateArea ໂດຍຕ້ອງຮັບຄ່າລັດສະໝີເຂົ້າໄປອີກແລ້ວລອງຄິດວ່າເຮົາຢາກເພີ່ມ method ຄຳນວນເນື້ອທີ່ຮູບອື່ນໆເຮົາກໍ່ຕ້ອງໄດ້ມາແກ້ class ນີ້ໃຫ້ຮັບຄ່າຕ່າງໆເຂົ້າມາອີກເຮັດໃຫ້ມັນ maintenance ຍາກແລະໃຊ້ງານຍາກໄປນຳອີກ.

ເປັນໄປຕາມ OCP

ແຍກອອກເປັນ abstract ແລ້ວໃຫ້ແຕ່ລະ class implement ເພື່ອນຳໄປໃຊ້ງານພຽງເທົ່ານີ້ກໍ່ເປັນໄປຕາມ OCP ແລ້ວ.

The Liskov Substitution Principle (LSP)

subclasses should be substitutable for their base classes

class ລູກຕ້ອງສາມາດເຮັດໜ້າທີ່ແທນ class ແມ່ໄດ້ໂດຍບໍ່ກະທົບກັບຄຸນສົມບັດໃດໆຂອງ class ແມ່ທີ່ມີແຕ່ເດີມຢູ່ແລ້ວ.

ຟັງແລ້ວກໍ່ງົງອີກຕາມເຄີຍໄປເບິ່ງຕົວຢ່າງປະກອບດີກວ່າ.

ບໍ່ເປັນໄປຕາມ LSP

function getFruitColor() ຮັບ type ເປັນ Apple ແຕ່ເມື່ອໂຍນຄ່າເປັນ Orange type ທີ່ສືບທອດ Apple class ເຂົ້າໄປພັດດຶງຄ່າສີອອກມາແຕກຕ່າງກັນເພາະ Orange class ໄປແກ້ໄຂ getColor ເຊິ່ງຜິດກົດຂອງ LSP ທີ່ບໍ່ໃຫ້ class ລູກໄປແກ້ໄຂຄຸນສົມບັດໃດໆຂອງ class ແມ່ທີ່ມີຢູ່ແລ້ວ. ແຕ່ວ່າ class Orange ຈຳເປັນຕ້ອງມີ method getColor ຄືກັນແລ້ວແບບນີ້ເຮົາຈະເຮັດແນວໃດ? ເຊີນທາງລຸ່ມໄດ້ເລີຍ.

ເປັນໄປຕາມ LSP

ແທນທີ່ຈະໂຍນ base class ເຂົ້າໄປກົງໆກໍ່ໃຫ້ປ່ຽນມາເປັນໂຍນ abstract class ແລ້ວໃຫ້ class Apple ແລະ Orange implement abstract class ນັ້ນແລ້ວໂຍນເຂົ້າໄປແທນພຽງເທົ່ານີ້ກໍ່ເປັນໄປຕາມ LSP ແລ້ວ.

The Interface Segregation Principle (ISP)

Clients should not be forced to depend on methods they do not use.

class ບໍ່ຄວນຖືກບັງຄັບໃຫ້ implement method ທີ່ບໍ່ໄດ້ໃຊ້

ການສ້າງ class ແລ້ວ implement interface ຫຼື abstract class ເຊິ່ງມີ method ທີ່ບໍ່ຈຳເປັນຕ້ອງມີໃນ class ນັ້ນໆກໍລະນີແບບນີ້ຈະຖືວ່າຜິດກົດ ISP ແລະ ເຮັດໃຫ້ class ມີຂະໜາດໃຫຍ່ສະນັ້ນ implement method ເທົ່າທີ່ຈຳເປັນຕ້ອງໃຊ້ກໍ່ພໍແລ້ວ

ບໍ່ເປັນໄປຕາມ ISP

ຈະເຫັນວ່າ IOS class ບໍ່ຈຳເປັນຕ້ອງ implement method getGoogleServiceSDKVersion, getPackageName ເຊັ່ນດຽວກັນ Android class ກໍ່ບໍ່ຈຳເປັນຕ້ອງ implement getBundleID ເຮັດໃຫ້ class ມັນບວມຂຶ້ນ ແລະ ໃນອານາຄົດຖ້າມີ merhod ອື່ນໆເພີ່ມເຂົ້າມາກໍ່ຕ້ອງໄດ້ນຳໄປແກ້ແຕ່ລະ class ຊີວິດຄົງລຳບາກກາກກຳ.

ເປັນໄປຕາມ ISP

ແຍກ interface ຫຼື abstract class ອອກເປັນຍ່ອຍໆແລ້ວ impelemnt ໄປຕາມຄວາມຕ້ອງການຈະໃຊ້ງານພຽງເທົ່ານີ້ກໍ່ເປັນໄປຕາມກົດຂອງ ISP ແລ້ວ.

The Dependency Inversion Principle (DIP)

High level modules should not depend on low level modules; both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions.

High level modules ບໍ່ຄວນຂຶ້ນກັບ low level module ໂດຍກົ່ງແຕ່ຕ້ອງຂຶ້ນກັບ Abstraction ແທນແລະ Abstraction ບໍ່ຄວນຮູ້ລາຍລະອຽດຂອງການເຮັດວຽກແຕ່ class ຫຼື modules ທີ່ເຮັດວຽກຈິງຕ້ອງເຮັດຕາມ Abstraction.

DIP ເປັນກົດທີ່ນິຍົມກັນໃຊ້ແພ່ຫຼາຍເອົາເປັນວ່າຢ່າງໜ້ອຍ code ເຮົາກໍ່ຕ້ອງ implement DIP ນີ້ຢູ່ສ່ວນໃດສ່ວນໜຶ່ງເພາະຖ້າບໍ່ເຮັດຕາມບໍ່ຢາກຈະຄິດເຖິງຕອນ maintaince ເລີຍ!

ບໍ່ເປັນໄປຕາມ DIP

ສັງເກດເຫັນວ່າ class CalculateRectangle ມັນຜູ້ຕິດກັບ CalculateArea ເກີນໄປເມືອສ້າງ object CalculateRectangle ກໍ່ຕ້ອງໄດ້ສ້າງ object ຂອງ CalculateArea ໄປພ້ອມກັນແລະເມື່ອມີການປ່ຽນແປງ class CalculateArea ມັນມີໂອກາດທີ່ class CalculateRectang ຈະເຮັດວຽກຜິດພາດໄດ້. ນອກນັ້ນການເພີ່ມ method ຄຳນວນພື້ນທີຮູບອື່ນໆກໍ່ຍິງເຮັດໃຫ້ code ເຮົາມັນສັບຊ້ອນ ແລະ ແກ້ຍາກຂຶ້ນໄປຕື່ມອີກ.

ເປັນໄປຕາມ DIP

ຈະເຫັນວ່າ class CalculateArea ຈະຂຶ້ນກັບ abstract class ແທນເຊິ່ງຈະເຮັດໃຫ້ສາມາດໂຍນ class ຕ່າງໆທີ່ implement abstract class ນັ້ນໆເຂົ້າມາເຮັດວຽກໄດ້ເລີຍ.

ມາຮອດນີ້ກໍ່ຫວັງວ່າ blog ນີ້ຈະເຮັດໃຫ້ເຂົ້າໃຈ ຫຼື ມີແນວທາງໃນການສຶກສາ SOLID Principle ກັນຕໍ່ໄປ. ເຊິ່ງກໍ່ເປັນພື້ນຖານທີ່ programer ຕ້ອງເຂົ້າໃຈແລະໃຊ້ເປັນກ່ອນທີ່ຈະລົງມື code program ແບບ OOP.

ຈົບໄວ້ເທົ່ານີ້ລະໄດ້ເຈີກັນບົດຄວາມໜ້າ

--

--