單一職責(Single-responsibility principle):一個類(class)應該只因為它負責的那件事而被更改。
注意:在單一職責中,要取得平衡,不要過度的拆分,例如拆分到一個類中只有一個方法。
拆分時可以考慮以下因素:
- 可讀性(
Readability
):簡短的類通常比較容易閱讀和理解。雖然“簡短”沒有明確的定義,但通常開發者認為200~300行的類是比較合適的。
- 擴展性(
Extensibility
):類是否容易擴展,修改或替換這些類時不應該無意破壞其他部分。
- 可重用性(
Reusability
):是否可以更方便地重新使用這些類
以下是一個將聲音,輸入,移動皆包含在一起的Player類,隨著專案的發展,這個類會越來愈難維護,例如更改聲音會動到這個類,更改移動輸入會動到這個類…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class UnrefactoredPlayer : MonoBehaviour { [SerializeField] private string inputAxisName; [SerializeField] private float positionMultiplier; private float yPosition; private AudioSource bounceSfx;
private void Start() { bounceSfx = GetComponent<AudioSource>(); }
private void Update() { float delta = Input.GetAxis(inputAxisName) * Time.deltaTime; yPosition = Mathf.Clamp(yPosition + delta, -1, 1); transform.position = new Vector3(transform.position.x, yPosition * positionMultiplier, transform.position.z); }
private void OnTriggerEnter(Collider other) { bounceSfx.Play(); } }
|
應考慮將這些行為拆分到各自的類,如 PlayerAudio、PlayerInput、PlayerMovement 等。Player 類仍然依賴這些行為,但這些行為已經被拆分到各自的類中。
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 28 29
| [RequireComponent(typeof(PlayerAudio), typeof(PlayerInput), typeof(PlayerMovement))] public class Player : MonoBehaviour { private PlayerAudio playerAudio; private PlayerInput playerInput; private PlayerMovement playerMovement;
private void Start() { playerAudio = GetComponent<PlayerAudio>(); playerInput = GetComponent<PlayerInput>(); playerMovement = GetComponent<PlayerMovement>(); } }
public class PlayerAudio : MonoBehaviour { }
public class PlayerInput : MonoBehaviour { }
public class PlayerMovement : MonoBehaviour { }
|