Light Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

unityvn/clean-code-in-unity

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

7 Commits

Repository files navigation

Clean code in Unity

Clean code la gi? Tai sao can clean code?

  • Clean code (ma sach) la mot khai niem trong lap trinh phan mem, de cap den viec viet ma nguon sao cho de doc, de hieu va de bao tri.
  • Muc tieu cua clean code la giup cac lap trinh vien khac (hoac chinh ban trong tuong lai) co the nhanh chong hieu duoc y dinh cua ma nguon, giam thieu loi va tang hieu suat lam viec.

Clean code nen bat dau tu dau?

  1. Dat ten bien va ham ro rang:

    • Mot ten bien/ham duoc xem la tot khi cac lap trinh vien khac nhau doc deu co the hieu duoc bien/ham do dung de lam gi.
    • Ten bien va ten ham phai la ten co nghia
    • Chu cai dau tien cua bien se la chu thuong, cac chu cai dau tien cua cac tu tiep theo se viet hoa (vi du: string studentName = "VirtueSky";, int calculateTotal = 0).
    • Doi voi ten ham cung tuong tu tuy nhien chu cai bat dau cua ten ham se la chu in hoa, (vi du: GetDayInYear(){})
    • Khong viet tat trong ten bien hoac ten ham.
    • Su dung ten bien nhat quan trong suot project (vi du: const int DAYS_IN_WEEK = 7; or const int daysInWeek = 7;) trong 2 kieu ten bien const o vi du, neu da follow theo kieu nao se lam tuong tu xuyen suot project.
    • Luu y: Phan nay con tuy thuoc vao convention cua tung team/project co the se khac nhau, hay thong nhat voi team cua ban. Ban co the tham khao them C# Coding Conventions
  2. If-Else va Switch-case

    • Can nhac trong cac truong hop co nhieu nhanh (10-20 case) va dieu kien kiem tra la cac gia tri roi rac cua cung mot bien (enum, int, string, v.v...) thi nen su dung switch-case thay vi if-else.
    • Viec su dung switch-case se giup code de doc hon, de bao tri va mo rong hon trong tuong lai.
    • Switch-case se nhay thang vao dieu kien dung ma khong can phai kiem tra lan luot tung dieu kien nhu if-else => hieu nang cung tot hon.
  3. Noi khong voi hard code

    • Hard code la viec ban gan truc tiep mot gia tri cu the vao trong ma nguon thay vi su dung bien hoac hang so.
    • Viec su dung hard code se lam cho ma nguon tro nen doc kho hieu va kho bao tri.
    • Doi voi Unity, doi khi ban nen tao cac tuy chinh de co the thay doi de dang ngoai editor thay vi phu thuoc vao script.
    • Vi du:
      // Hard code
      void Start() {
      transform.position = new Vector3(0, 10, 0);
      }

      // Clean code
      public Vector3 startPosition = new Vector3(0, 10, 0);
      void Start() {
      transform.position = startPosition;
      }
  4. Moi ham nen thuc hien mot tinh nang duy nhat

    • Mot ham nen duoc thiet ke de thuc hien mot nhiem vu cu the va ro rang.
    • Neu mot ham thuc hien qua nhieu nhiem vu, no se tro nen kho doc va kho bao tri (vi du mot ham thuc hien xu ly dong thoi input, update animation, tinh toan vat ly).
    • Nen chia nho ham lon thanh cac ham nho hon, moi ham dam nhan mot nhiem vu cu the.
    • Vi du:
      // Bad example
      void Update() {
      // Xu ly input
      // Cap nhat animation
      // Tinh toan vat ly
      }

      // Good example
      void Update() {
      HandleInput();
      UpdateAnimation();
      CalculatePhysics();
      }

      void HandleInput() {
      // Xu ly input
      }

      void UpdateAnimation() {
      // Cap nhat animation
      }

      void CalculatePhysics() {
      // Tinh toan vat ly
      }
  5. Su dung comment mot cach hop ly

    • Comment nen duoc su dung de giai thich "tai sao" mot doan ma duoc viet nhu vay.
    • Tranh viec comment qua nhieu hoac comment nhung dieu hien nhien trong ma nguon.
    • Neu ban thay minh can phai comment qua nhieu de giai thich ma nguon, co the ma nguon do can duoc viet lai cho ro rang hon.
    • Vi du:
      ///
      /// This function calculates the sum of two integers.
      ///

      /// First integer
      /// Second integer
      ///
      int CalculateTotal(int a, int b)
      {
      return a + b;
      }
  6. Su dung enum de de dang phan loai

    • Enum la mot kieu du lieu dac biet trong C# cho phep ban dinh nghia mot tap hop cac hang so co ten.
    • Su dung enum giup ma nguon tro nen ro rang hon va de bao tri hon so voi viec su dung cac gia tri so nguyen hoac chuoi de dai dien cho cac trang thai hoac loai khac nhau.
    • Vi du:
      // Bad example
      int playerState = 1; // 1: Idle, 2: Running, 3: Jumping

      // Good example
      enum PlayerState
      {
      Idle,
      Running,
      Jumping
      }

      PlayerState playerState = PlayerState.Idle;
  7. Khong bo ngoac trong if-else, for

    • Du chi co mot dong lenh trong khoi if-else, for thi van nen su dung ngoac nhon {} de bao quanh khoi lenh do.
    • Viec nay giup tranh cac loi khong mong muon khi ban hoac nguoi khac them dong lenh moi vao khoi lenh sau nay.
    • Vi du:
      // Bad example
      if (isGameOver)
      Debug.Log("Game Over");

      // Good example
      if (isGameOver)
      {
      Debug.Log("Game Over");
      }
  8. Khong lam dung Singleton

    • Singleton la mot mau thiet ke (design pattern) de tiep can va de dung, no cho phep ban dam bao rang mot lop chi co mot the hien duy nhat va cung cap mot diem truy cap toan cuc den the hien do.
    • Mac du singleton co the huu ich trong mot so truong hop, nhung viec lam dung no co the dan den ma nguon kho doc, kho bao tri va kho kiem thu do co reference chong cheo khap noi trong project.
    • Nen su dung singleton mot cach can than va chi khi thuc su can thiet. Trong mot so truong hop, ban co the can nhac de ket hop voi mot so pattern khac nhu Observer hoac Dependency Injection de giam su phu thuoc vao singleton.
  9. Van dung tot lap trinh huong doi tuong

    • Lap trinh huong doi tuong (OOP) la mot phuong phap lap trinh dua tren viec to chuc ma nguon thanh cac doi tuong co trang thai va hanh vi rieng.
    • Su dung OOP giup ma nguon tro nen de doc, de bao tri va de mo rong hon.
    • Mot so nguyen tac co ban cua OOP bao gom:
      • Encapsulation (Dong goi): Giu trang thai va hanh vi cua doi tuong ben trong lop va chi cho phep truy cap thong qua cac phuong thuc cong khai.
      • Inheritance (Ke thua): Tao cac lop con tu lop cha de tai su dung ma nguon va mo rong chuc nang.
      • Abstraction (Truu tuong): Tao cac lop truu tuong de dinh nghia giao dien chung cho cac lop con.
      • Polymorphism (Da hinh): Cho phep cung mot hanh dong (phuong thuc) nhung co the thuc hien theo nhieu cach khac nhau, tuy thuoc vao doi tuong cu the dang su dung...
    • Vi du 1: Su dung ke thua de tai su dung ma nguon va giam su lap lai
      // Bad example
      class Player
      {
      public string name;
      public int health;
      public void Move() { /* ... */ }
      public void Attack() { /* ... */ }
      public void Defend() { /* ... */ }
      }

      // Good example
      class Character
      {
      public string name;
      public int health;
      public void Move() { /* ... */ }
      }

      class Player : Character
      {
      public void Attack() { /* ... */ }
      public void Defend() { /* ... */ }
      }
    • Vi du 2: Loi ich cua viec su dung (truu tuong) interface de giam su phu thuoc vao cac lop cu the
      • Bad example
      public class BlueMonster : MonoBehaviour
      {
      public void TakeDamage(int amount)
      {
      Debug.Log("Blue Monster took " + amount + " damage!");
      }
      }
      public class RedMonster : MonoBehaviour
      {
      public void TakeDamage(int amount)
      {
      Debug.Log("Red Monster took " + amount + " damage!");
      }
      }
      public class GreenMonster : MonoBehaviour
      {
      public void TakeDamage(int amount)
      {
      Debug.Log("Green Monster took " + amount + " damage!");
      }
      }

      public class Player : MonoBehaviour
      {
      public int damage;
      private void OnTriggerEnter(Collider other)
      {
      if (other.GetComponent<BlueMonster>() != null)
      {
      // Handle BlueMonster collision
      other.GetComponent<BlueMonster>().TakeDamage(damage);
      }
      else if(other.GetComponent<RedMonster>() != null)
      {
      // Handle RedMonster collision
      other.GetComponent<RedMonster>().TakeDamage(damage);
      }
      else if(other.GetComponent<GreenMonster>() != null)
      {
      // Handle GreenMonster collision
      other.GetComponent<GreenMonster>().TakeDamage(damage);
      }
      }
      }
      • Good example
      public interface IMonster
      {
      void TakeDamage(int amount);
      }

      public class BlueMonster : MonoBehaviour, IMonster
      {
      public void TakeDamage(int amount)
      {
      Debug.Log("Blue Monster took " + amount + " damage!");
      }
      }
      public class RedMonster : MonoBehaviour, IMonster
      {
      public void TakeDamage(int amount)
      {
      Debug.Log("Red Monster took " + amount + " damage!");
      }
      }
      public class GreenMonster : MonoBehaviour, IMonster
      {
      public void TakeDamage(int amount)
      {
      Debug.Log("Green Monster took " + amount + " damage!");
      }
      }

      public class Player : MonoBehaviour
      {
      public int damage;
      private void OnTriggerEnter(Collider other)
      {
      if (other.GetComponent<IMonster>() != null)
      {
      // Handle BlueMonster collision
      other.GetComponent<IMonster>().TakeDamage(damage);
      }
      }
      }
      • Trong vi du tren, viec su dung interface IMonster giup giam su phu thuoc cua lop Player vao cac lop cu the nhu BlueMonster, RedMonster, va GreenMonster. Dieu nay lam cho ma nguon tro nen linh hoat hon va de bao tri hon trong tuong lai. Hoac noi de hieu hon la giup ban khong phai if-else gay tay den ch*t trong OnTriggerEnter khi ban co them 20 loai monster moi...
      • Cac vi du tren chi la mot so ung dung co ban cua OOP trong viec clean code, ban hay hieu ky va van dung that linh dong cho nhieu truong hop khac.
  10. Tuan thu quy tac SOLID

    • SOLID la mot tap hop cac nguyen tac thiet ke phan mem giup tao ra ma nguon de bao tri, mo rong va tai su dung.

    • Cac nguyen tac SOLID bao gom:

      • Single Responsibility Principle (SRP): Moi lop nen chi co mot ly do de thay doi, tuc la moi lop nen chi dam nhan mot nhiem vu duy nhat.
      • Open/Closed Principle (OCP): Cac lop nen duoc mo de mo rong nhung dong de sua doi, tuc la ban nen co the them chuc nang moi ma khong can thay doi ma nguon hien co.
      • Liskov Substitution Principle (LSP): Cac doi tuong cua lop con nen co the thay the cho cac doi tuong cua lop cha ma khong lam thay doi tinh dung dan cua chuong trinh.
      • Interface Segregation Principle (ISP): Nen tao cac giao dien nho va cu the thay vi cac giao dien lon va chung chung, de cac lop chi can trien khai nhung phuong thuc ma chung thuc su can.
      • Dependency Inversion Principle (DIP): Cac lop cap cao khong nen phu thuoc vao cac lop cap thap, ca hai nen phu thuoc vao cac truu tuong. Truu tuong khong nen phu thuoc vao chi tiet, chi tiet nen phu thuoc vao truu tuong.
    • Vi du 1 (SRP): Mot class se mang mot nhiem vu duy nhat

      • Bad example: Class InvoiceService gop tinh toan va luu file
        class InvoiceService {
        public decimal CalculateTotal(IEnumerable<decimal> items) => items.Sum();
        public void SaveToDisk(string path, string content) => File.WriteAllText(path, content);
        }
      • Good example: Tach rieng tinh toan va luu file thanh hai class khac nhau
        class InvoiceCalculator {
        public decimal CalculateTotal(IEnumerable<decimal> items) => items.Sum();
        }

        class FileSaver {
        public void SaveToDisk(string path, string content) => File.WriteAllText(path, content);
        }
    • Vi du 2 (OCP): De mo rong, han che sua code cu.

      • Bad example: Moi khi them mot hinh thi phai sua switch de tinh dien
      double Area(string shape, params double[] p)
      {
      return shape switch
      {
      "circle" => Math.PI * p[0] * p[0],
      "rect" => p[0]*p[1]
      };
      }
      • Good example: Moi khi them mot hinh moi chi can tao class moi ke thua tu Shape va tinh tong thong qua truu tuong interface IShape
      interface IShape { double Area(); }

      class Circle : IShape
      {
      double r;
      public double Area() => (double)Math.PI * r * r;
      }

      class Rect : IShape
      {
      double w, h;
      public double Area() => w * h;
      }

      // them Triangle chi can class moi, khong sua code cu
      class Triangle : IShape
      {
      double b, h;
      public double Area() => b * h / 2;
      }

      // Luc nay de tinh tong dien tich thi cung chi can duyet thong qua mang IShape
      class AreaCalculator
      {
      public double TotalArea(IShape[] shapes)
      {
      double area = 0;
      foreach (var shape in shapes)
      area += shape.Area();
      return area;
      }
      }
    • Vi du 3 (LSP): Class con thay the class cha ma khong pha logic.

      • Bad example: Chim canh cut khong biet bay nhung van bi ep thua ke Fly()
      abstract class Bird
      {
      public abstract void Fly();
      }

      class Sparrow : Bird
      {
      public override void Fly() {}
      }

      // sai LSP
      class Penguin : Bird
      {
      public override void Fly() { throw new NotSupportedException(); }
      }
      • Good example: Tach kha nang bay ra interface
      abstract class Bird
      {
      public string Name { get; set; } = "";
      }

      interface IFlyable
      {
      void Fly();
      }

      class Sparrow : Bird, IFlyable
      {
      public void Fly() { /* ... */ }
      }

      class Penguin : Bird
      {
      /* khong bay, van ok */
      }
    • Vi du 4 (ISP): Tach interface lon thanh cac interface nho hon. Viec nay ban chat cung giong vi du tren de tranh implement nhung method thua va khong can thiet.

      • Bad example: Interface "da nang", class phai implement ham khong dung
      interface IMachine
      {
      void Print();
      void Scan();
      void Fax();
      }
      class SimplePrinter : IMachine {
      public void Print() {}
      public void Scan() { /* trong */ }
      public void Fax() { /* trong */ }
      }
      • Good example: Tach nho de co the tuy bien implement theo nhu cau
      interface IPrinter
      {
      void Print();
      }

      interface IScanner
      {
      void Scan();
      }

      interface IFax
      {
      void Fax();
      }

      class SimplePrinter : IPrinter
      {
      public void Print() {}
      }

      class MultiFunction : IPrinter, IScanner, IFax
      {
      public void Print() {}
      public void Scan() {}
      public void Fax() {}
      }
    • Vi du 5 (DIP): Phu thuoc abstraction (interface), khong phu thuoc class cu the.

      • Bad example: Set cung vao EmailNotifier
      class EmailNotifier
      {
      public void Send(string msg) {}
      }

      class OrderService {
      private readonly EmailNotifier _notifier = new();
      public void PlaceOrder() { /* ... */ _notifier.Send("OK"); }
      }
      • Good example: Phu thuoc interface INotifier, de dang thay doi cach thong bao khac (SMS, Push...). Cach nay nguoi ta thuong goi la Tiem qua interface.
      interface INotifier
      {
      void Send(string msg);
      }

      class EmailNotifier : INotifier
      {
      public void Send(string msg) {}
      }

      class SmsNotifier : INotifier
      {
      public void Send(string msg) {}
      }

      class OrderService
      {
      private INotifier _notifier;

      public void Initialize(INotifier notifier)
      {
      _notifier = notifier;
      }
      public void PlaceOrder() { /* ... */ _notifier.Send("OK"); }
      }
  11. Su dung partial class de mo rong

    • Partial class la mot tinh nang trong C# cho phep ban chia mot lop thanh nhieu phan trong cac tep khac nhau.
    • Su dung partial class giup ma nguon tro nen sach hon va de bao tri hon, dac biet khi mot lop co nhieu chuc nang hoac khi ban muon tach rieng cac phan cua lop de de dang quan ly.
    • Viec nay rat hieu qua khi co nhieu nguoi cung lam feature va can tach rieng code cua minh ra de tranh xung dot.
    • Vi du:
      // File Character.Movement.cs
      public partial class Character : MonoBehaviour
      {
      public void Move() { /* ... */ }
      }

      // File Character.Combat.cs
      public partial class Character : MonoBehaviour
      {
      public void Attack() { /* ... */ }
      public void Defend() { /* ... */ }
      }

      // File Character.Inventory.cs
      public partial class Character : MonoBehaviour
      {
      public void AddItem(string item) { /* ... */ }
      public void RemoveItem(string item) { /* ... */ }
      }
  12. Hay chon mot pattern chinh xuyen suot

    • Trong lap trinh, co rat nhieu design pattern khac nhau nhu Singleton, Factory, Observer, Strategy, v.v...
    • Moi pattern deu co uu diem va nhuoc diem rieng, va khong phai pattern nao cung phu hop voi moi tinh huong.
    • Viec chon mot pattern chinh de ap dung xuyen suot trong project se giup ma nguon tro nen nhat quan hon va de bao tri hon.
    • Vi du: Neu ban chon su dung pattern Observer de quan ly su kien trong game, hay co gang ap dung no cho tat ca cac he thong lien quan den su kien thay vi su dung nhieu pattern khac nhau.
  13. Su dung mot kieu format code cho toan bo project

    • Viec su dung mot kieu format code nhat quan trong toan bo project se giup ma nguon tro nen de doc va de bao tri hon. Day la mot cach hieu qua cho nhung nguoi OCD giam su kho chiu =))
    • Cac IDE bay gio deu ho tro rat tot viec nay. Co 2 kieu format pho bien trong c# la K&R style va BSD style, hay chon cho minh mot kieu phu hop
    • Dieu quan trong la tat ca cac thanh vien trong team deu phai tuan thu quy tac nay de dam bao tinh nhat quan trong ma nguon.
  14. Dung ScriptableObject thay vi hard code data

    • ScriptableObject la mot loai doi tuong trong Unity cho phep ban luu tru du lieu mot cach de dang va hieu qua.
    • Su dung ScriptableObject de luu tru du lieu thay vi hard code truc tiep trong script se giup ma nguon tro nen sach hon va de bao tri hon.
    • Thay vi hard code cac thuoc tinh cua mot nhan vat trong script, ban co the tao mot ScriptableObject de luu tru cac thuoc tinh nay va de dang chinh sua chung trong editor.
    • Vi du:
      // Tao ScriptableObject de luu tru du lieu nhan vat
      [CreateAssetMenu(fileName = "NewCharacterData", menuName = "Character Data", order = 51)]
      public class CharacterData : ScriptableObject
      {
      public string characterName;
      public int health;
      public int attackPower;
      }

      // Su dung ScriptableObject trong script
      public class Character : MonoBehaviour
      {
      public CharacterData characterData;

      void Start()
      {
      Debug.Log("Character Name: " + characterData.characterName);
      Debug.Log("Health: " + characterData.health);
      Debug.Log("Attack Power: " + characterData.attackPower);
      }
      }

About

How to clean code in Unity?

Topics

Resources

Readme

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors