TypeScriptのクラス設計まとめ!柔軟かつ堅牢なコードを書く秘訣
生徒
「TypeScriptでクラスを設計するときに、どうすれば柔軟で壊れにくいプログラムが作れるんですか?」
先生
「クラス設計では、現実世界の物事をうまく表現することが大切です。例えば、車や動物といった身近な例を考えると分かりやすいですよ。」
生徒
「なるほど!でも実際にどうやってクラスを書けばいいのかイメージが湧きません。」
先生
「それでは、TypeScriptでクラスを設計する基本から一緒に見ていきましょう!」
1. クラスとは?
クラスとは、設計図のようなものです。例えば「自動車」という設計図があれば、そこから「トヨタの車」や「ホンダの車」といった具体的な車を作り出せます。プログラミングでも同じで、クラスは設計図、そこから作られる具体的なものをオブジェクト(実体)と呼びます。
TypeScriptでは、クラスを使うことでデータ(プロパティ)と処理(メソッド)をひとまとめにして表現できます。
class Car {
brand: string;
constructor(brand: string) {
this.brand = brand;
}
drive() {
console.log(this.brand + "が走ります!");
}
}
let myCar = new Car("トヨタ");
myCar.drive();
トヨタが走ります!
2. プロパティとメソッドの役割
クラスにはプロパティ(性質やデータ)とメソッド(行動や処理)を定義できます。プロパティは車の「色」や「速度」といった特徴で、メソッドは「走る」「止まる」といった動作です。これを組み合わせることで、現実世界のイメージをそのままコードに表現できます。
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak() {
console.log(this.name + "が鳴きます!");
}
}
let dog = new Animal("犬");
dog.speak();
犬が鳴きます!
3. アクセス修飾子で守る設計
プログラムが壊れにくくなる秘訣のひとつはアクセス修飾子です。アクセス修飾子とは、クラスの中のデータを「外から触れるかどうか」を制御する仕組みです。
public:どこからでもアクセスできる(基本の設定)private:クラスの中だけで使える(外からは触れない)protected:そのクラスと、継承したクラスからアクセスできる
これを使うことで、必要以上に外部からデータをいじられないように守ることができます。
class BankAccount {
private balance: number;
constructor(balance: number) {
this.balance = balance;
}
deposit(amount: number) {
this.balance += amount;
}
getBalance() {
return this.balance;
}
}
let account = new BankAccount(1000);
account.deposit(500);
console.log(account.getBalance()); // 1500
4. 継承でコードを再利用する
継承(けいしょう)を使うと、あるクラスの機能を引き継いで、新しいクラスを作ることができます。これにより、重複したコードを書かずにすみ、効率よくプログラムを組み立てられます。
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak() {
console.log(this.name + "が鳴きます!");
}
}
class Dog extends Animal {
bark() {
console.log(this.name + "がワンワン吠えます!");
}
}
let dog = new Dog("ポチ");
dog.speak();
dog.bark();
ポチが鳴きます!
ポチがワンワン吠えます!
5. コンストラクタで初期設定する
コンストラクタとは、クラスからオブジェクトを作るときに最初に呼ばれる特別なメソッドです。これを使えば、必要なデータを最初から設定できます。たとえば「名前」や「年齢」を必ず登録してから人物を作る、といった使い方ができます。
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
introduce() {
console.log("私は" + this.name + "、" + this.age + "歳です。");
}
}
let person = new Person("太郎", 25);
person.introduce();
私は太郎、25歳です。
6. 柔軟かつ堅牢な設計のポイント
TypeScriptでクラスを設計する際に大切なのは「柔軟さ」と「堅牢さ」です。柔軟さとは、新しい機能を追加しやすいこと。堅牢さとは、間違って壊れにくいことです。そのために次のような工夫をしましょう。
- アクセス修飾子を使って、必要なデータだけ公開する
- コンストラクタで必須のデータを初期化する
- 継承でコードの重複を減らす
- メソッドを使って「データの操作方法」を統一する
こうした工夫をすることで、規模の大きなシステムでも安心して使えるクラス設計ができるようになります。
まとめ
TypeScriptのクラス設計を総合的に振り返る
TypeScriptのクラス設計では、柔軟で壊れにくい構造をつくるために、さまざまな概念や記述方法をバランスよく取り入れることが重要です。 この記事で扱った「クラス」「プロパティ」「メソッド」「アクセス修飾子」「継承」「コンストラクタ」といった基本的な仕組みは、どれも現実の物事を整理しながら分かりやすくコードに落とし込むうえで欠かせない要素です。 例えば、乗り物や動物や銀行口座などの具体例を使うことで、クラスがどのようにデータと処理をまとめ、オブジェクトとして扱いやすい形にしているのかを自然な流れで理解できます。特に、アクセス修飾子を活用することで外部から触れられたくない情報を守れる点や、継承によって共通部分をまとめて再利用できる点は、規模が大きい開発になるほど効果を発揮します。 さらに、コンストラクタを用いて初期化を確実に行うことで、オブジェクト生成時点から必要な情報を安全に整えることができ、後々のエラーを防ぐ設計にもつながります。これらの要素を丁寧に組み立てることで、拡張性があり、変更に強く、可読性の高いTypeScriptコードを実現できます。 また、クラス設計を意識したサンプルコードを書くことで、実際の動作イメージがつきやすく、具体的なプロパティやメソッドの関連性が自然に見えてきます。特にメソッドを使い統一的な操作を提供することで、データの扱いが一貫し、予期せぬ動作を防ぐことができます。これらの積み重ねが、柔軟で堅牢な設計を生み出す大きなポイントとなります。
サンプルプログラムで理解を深める
以下のように、アクセス修飾子やコンストラクタを組み込んだクラス設計を行うことで、用途に応じた安全な処理を記述できます。
class UserProfile {
private name: string;
private age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
introduce() {
console.log("私は" + this.name + "、" + this.age + "歳です。");
}
updateAge(newAge: number) {
if (newAge > 0) {
this.age = newAge;
}
}
}
let user = new UserProfile("花子", 30);
user.introduce();
user.updateAge(31);
user.introduce();
このようなクラス設計では、外部から直接年齢を変更させないようにしつつ、メソッドを通じてルールに沿った更新ができるようにしています。クラス内部の状態を守りながら、必要な機能だけを公開する構造は、 TypeScript で堅牢なプログラムを作る基礎となります。
生徒
「クラスの仕組みって、思ったより現実のイメージそのままで使えるんですね!」
先生
「そうなんです。設計図のように考えると理解しやすいでしょう?プロパティで特徴を、メソッドで動作をまとめて表現します。」
生徒
「アクセス修飾子で守るっていうのも大事なんですね。勝手に変更されたら困りますもんね。」
先生
「その通りです。特に大規模な開発になるほど、データを守る仕組みが重要になります。継承も再利用性を高める役割がありますよ。」
生徒
「コンストラクタで最初の設定を強制できるのも便利ですね!間違いが減りそうです。」
先生
「総合して考えると、TypeScript のクラス設計は柔軟で堅牢なプログラムを書くための核となります。これから色々な例で試しながら慣れていきましょう。」