SOLID

What is SOLID

SOLID is an acronym for a set of five design principles for writing maintainable and scalable software. These principles were introduced by Robert C. Martin (also known as “Uncle Bob”) and have become widely accepted as best practices in software development.

Here’s a brief overview of each principle:

Single Responsibility Principle (SRP): A class should have only one reason to change. This means that a class should have only one responsibility or job. This principle helps in reducing complexity and making the code easier to maintain.

Open/Closed Principle (OCP): Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. This means that you should be able to add new functionality without changing the existing code. This principle helps in making the code more modular and flexible.

Liskov Substitution Principle (LSP): Subtypes must be substitutable for their base types. This means that any object of a class should be able to be replaced with an object of its subclass without affecting the correctness of the program. This principle helps in ensuring the correct behavior of the code when using polymorphism.

Interface Segregation Principle (ISP): Clients should not be forced to depend on interfaces they do not use. This means that a class should not be forced to implement methods it doesn’t need. This principle helps in making the code more modular and preventing unnecessary dependencies.

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 on abstractions. This means that the high-level modules should be independent of the low-level modules and should instead depend on abstractions. This principle helps in making the code more flexible and easier to maintain.

Together, these five principles form SOLID, a set of guidelines that can help you write more maintainable and scalable software.

SOLID 是什麼

SOLID原則是一組關於撰寫可維護性和可擴展性軟體的五個設計原則。這些原則由Robert C. Martin(也稱為"Uncle Bob")所提出,已成為軟體開發中廣泛接受的最佳實踐。

以下是每個原則的簡要概述:

單一職責原則(SRP):一個類別應該只有一個變更的原因。這意味著一個類別只應該有一個職責或工作。這個原則有助於減少複雜性,使程式碼更容易維護。

開放/封閉原則(OCP):軟體實體(類別、模組、函式等)應該對擴展開放,但對修改封閉。這意味著您應該能夠添加新功能而不更改現有的程式碼。這個原則有助於使程式碼更模組化和靈活。

里氏替換原則(LSP):子類別必須能夠替換其基類別。這意味著一個類別的任何物件都應該能夠被其子類別的物件替換,而不會影響程式的正確性。這個原則有助於確保使用多型時程式碼的正確行為。

介面隔離原則(ISP):客戶端不應被迫依賴它們不使用的介面。這意味著一個類別不應被迫實現它不需要的方法。這個原則有助於使程式碼更模組化並防止不必要的相依性。

依賴反轉原則(DIP):高層模組不應依賴於低層模組。兩者都應該依賴於抽象。抽象不應該依賴於細節。細節應該依賴於抽象。這意味著高層模組應該獨立於低層模組,而應該依賴於抽象。這個原則有助於使代碼更具靈活性和易於維護。

這五個原則組成了SOLID,是一套指南,可幫助您撰寫更具可維護性和可擴展性的軟體。

  1. 單一職責原則 (Single Responsibility Principle, SRP)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class User
  def initialize(name, email)
    @name = name
    @email = email
  end

  def save
    # save user to database
  end
end

上面的 User 類別只負責儲存使用者資料,而不負責其他的功能。

  1. 開放封閉原則 (Open-Closed Principle, OCP)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Payment
  def process
    raise NotImplementedError, "Subclass must implement abstract method"
  end
end

class CreditCardPayment < Payment
  def process
    # process credit card payment
  end
end

class PayPalPayment < Payment
  def process
    # process PayPal payment
  end
end

上面的 Payment 類別是一個抽象類別,其中包含一個抽象方法 process,並且 CreditCardPayment 和 PayPalPayment 兩個子類別都繼承了 Payment 類別,並實作了 process 方法。這樣可以在不修改 Payment 類別的情況下,新增其他的付款方式。

  1. 里氏替換原則 (Liskov Substitution Principle, LSP)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Animal
  def make_sound
    raise NotImplementedError, "Subclass must implement abstract method"
  end
end

class Dog < Animal
  def make_sound
    "Woof"
  end
end

class Cat < Animal
  def make_sound
    "Meow"
  end
end

上面的 Animal 類別是一個抽象類別,其中包含一個抽象方法 make_sound,並且 Dog 和 Cat 兩個子類別都繼承了 Animal 類別,並實作了 make_sound 方法。由於 Dog 和 Cat 都能替代 Animal,因此可以在使用 Animal 的地方使用 Dog 或 Cat。

  1. 介面隔離原則 (Interface Segregation Principle, ISP)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Order
  def initialize(payment_method)
    @payment_method = payment_method
  end

  def process_payment
    @payment_method.process_payment
  end
end

class CreditCardPayment
  def process_payment
    # process credit card payment
  end
end

class PayPalPayment
  def process_payment
    # process PayPal payment
  end
end

上面的 Order 類別需要依賴於一個付款方式,並且透過該付款方式來進行付款。因此,CreditCardPayment 和 PayPalPayment 兩個類別必須實作一個名為 process_payment 的方法,以便讓 Order 類別使用。

  1. 依賴反轉原則 (Dependency Inversion Principle, DIP)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Order
  def initialize(payment_method)
    @payment_method = payment_method
  end

  def process_payment
    @payment_method.process_payment
  end
end

class PaymentMethod
  def process_payment
    raise NotImplementedError, "Subclass must implement abstract method"
  end
end

class CreditCardPayment < PaymentMethod
  def process_payment
    # process credit card payment
  end
end

class PayPalPayment < PaymentMethod
  def process_payment
    # process PayPal payment
  end
end

上面的 Order 類別需要依賴於一個付款方式,並且透過該付款方式來進行付款。然而,Order 類別不應該依賴於具體的付款方式,而應該依賴於一個抽象的付款方式,因為具體的付款方式可能會變更,而抽象的付款方式則是不會變更的。

因此,我們新增了一個 PaymentMethod 類別,其中包含一個抽象的方法 process_payment,並且 CreditCardPayment 和 PayPalPayment 兩個子類別都繼承了 PaymentMethod 類別,並實作了 process_payment 方法。這樣,Order 類別就可以依賴於 PaymentMethod 類別,而不是依賴於具體的付款方式。如果需要新增其他的付款方式,只需要繼承 PaymentMethod 類別並實作 process_payment 方法即可。這樣,就符合依賴反轉原則。

More examples

updatedupdated2023-03-142023-03-14