Menu
Coddy logo textTech

ファクトリコンストラクタ

CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 14/110。

factory constructorは、常に新しいinstanceを作成するとは限らない特殊なconstructorです。通常のconstructorとは異なり、factory constructorは既存のinstance、サブタイプ、あるいは(nullable の場合)null さえも返すことができます。factoryキーワードを使用して宣言します。

class Logger {
  static final Logger _instance = Logger._internal();
  
  // プライベートな名前付きコンストラクタ
  Logger._internal();
  
  // ファクトリコンストラクタ
  factory Logger() {
    return _instance;
  }
}

Logger log1 = Logger();
Logger log2 = Logger();
print(identical(log1, log2)); // true

この例では、factory constructor は常に同じ instance を返します。Logger() を何度 call しても、identical なオブジェクトを取得します。このパターンは、singleton の実装によく使用されます。

Factory constructor は通常の constructor と重要な点で異なります。新しい instance をまったく作成しない場合があるため、this にアクセスできません。その代わり、object を明示的に返す必要があります。

class Shape {
  factory Shape(String type) {
    if (type == 'circle') return Circle();
    if (type == 'square') return Square();
    return Rectangle();
  }
}

class Circle extends Shape { Circle() : super._(); }
class Square extends Shape { Square() : super._(); }
class Rectangle extends Shape { Rectangle() : super._(); }

ファクトリーコンストラクターは、キャッシュされたオブジェクトの返却、オブジェクトプールの実装、入力パラメーターに基づくインスタンス化するサブタイプの決定など、インスタンスの作成を制御する必要がある場合に便利です。

challenge icon

チャレンジ

簡単

単純な文字列入力に基づいて、factory constructor を使用してさまざまな種類の通知を Create する通知システムを構築しましょう。

コードを整理するために、2つのファイルを Create します。

  • notification.dart: すべての通知タイプの base として機能する Notification class を Define します。class には次の要素を含めます。
    • String message field
    • message を initializes する private named constructor Notification._internal
    • type parameter に基づいて異なる通知サブタイプを返す factory constructor Notification(String type, String message):
      • type が 'email' の場合、EmailNotification を返す
      • type が 'sms' の場合、SMSNotification を返す
      • otherwise、PushNotification を返す
    • Sending: [message] を prints する send() method

同じファイルで、Notification を extend する3つのサブクラスを Create します。

  • EmailNotification: send() を Override して Email: [message] を prints する
  • SMSNotification: send() を Override して SMS: [message] を prints する
  • PushNotification: send() を Override して Push: [message] を prints する

各サブクラスには、message を受け取り、super._internal(message) を使用して親に渡す constructor が必要です。

  • main.dart: notification class を import し、factory constructor を使用して3つの通知を Create します。
    • 'Welcome!' を message とする email 通知
    • 'Your code is 1234' を message とする SMS 通知
    • 'New update available' を message とする push 通知
    上記の順序で各通知に対して send() を Call します。

Expected output:

Email: Welcome!
SMS: Your code is 1234
Push: New update available

自分で試してみよう

import 'notification.dart';

void main() {
  // TODO: メッセージ 'Welcome!' のメール通知を作成する
  
  // TODO: Create an SMS notification with message 'Your code is 1234'
  
  // TODO: Create a push notification with message 'New update available'
  
  // TODO: 各通知に対して順番に send() を呼び出す
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Dartオンラインコンパイラ