🐾
【Dart】簡単なユーザクラスを利用してNamed,Redirecting,Factoryコンストラクタ理解
【Dart】コンストラクタ関連
-
【参考】公式のConstructors学習サイト
-
Language tour | Dart > Constructors
- 全体的な知識を身に着けたい場合は、上記を参照
-
Language tour | Dart > Constructors
-
利用するサンプルクラス
- SNSアプリが持つようなUserクラス
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
}
Named constructors
- Named constructorsは、特定の目的のために特定の値を格納するためのコンストラクタ
基本例①
- anonymous(匿名)ユーザを作成する用のコンストラクタ
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Named constructors
User.anonymous()
: id = 'anonymousId',
username = 'anonymousUsername',
email = 'anonymousEmail';
}
void main() {
User user = User.anonymous();
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
anonymousUsername
anonymousEmail
基本例②
- 引数をとる場合
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Named constructors
User.anonymous({String username})
: id = 'anonymousId',
username = username,
email = 'anonymousEmail';
}
void main() {
User user = User.anonymous(username: 'TestUser');
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
TestUser
anonymousEmail
Redirecting constructors
- Redirecting constructorsは、他のコンストラクタを流用するためのコンストラクタ
基本例①
- 通常のコンストラクタを利用し、anonymous(匿名)ユーザを作成する用のコンストラクタ
- ※書き方が違うのみで、Named constructorとほぼ同様
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Redirecting constructors
User.anonymous()
: this(
id: 'anonymousId',
username: 'anonymousUsername',
email: 'anonymousEmail',
);
}
void main() {
User user = User.anonymous();
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
anonymousUsername
anonymousEmail
基本例②
- 引数をとる場合
- ※これも書き方が違うのみで、Named constructorとほぼ同様
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Redirecting constructors
User.anonymous({String username})
: this(
id: 'anonymousId',
username: username,
email: 'anonymousEmail',
);
}
void main() {
User user = User.anonymous(username: 'TestUser');
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
TestUser
anonymousEmail
基本例③
- コンストラクタに初期値がある場合に、コード量を節約可能
- ※Named constructorsでは、エラーとなる(メインコンストラクタに初期値があった場合も、記載が必要)
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username = 'TestUser',
this.email,
});
// Redirecting constructors
User.anonymous()
: this(
id: 'anonymousId',
email: 'anonymousEmail',
);
}
void main() {
User user = User.anonymous();
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
TestUser
anonymousEmail
基本例④
- Named constructorも簡単に流用可能
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Named constructors
User.anonymous({String username})
: id = 'anonymousId',
username = username,
email = 'anonymousEmail';
// Redirecting constructors
User.anonymousTestUser() : this.anonymous(username: 'TestUser');
}
void main() {
User user = User.anonymousTestUser();
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
TestUser
anonymousEmail
Factory constructors
- Factory constructorsは、インスタンスを必要な際に作成するコンストラクタ(returnでインスタンスを返す)
- ※Factoryと通常コンストラクタは同じ名前のコンストラクタ不可
基本例①
- anonymous(匿名)ユーザをその場で作成し、return
- ※書き方が違うのみで、Named constructor、Redirecting constructorsとほぼ同様
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Factory constructors
factory User.anonymous() {
return User(
id: 'anonymousId',
username: 'anonymousUsername',
email: 'anonymousEmail',
);
}
}
void main() {
User user = User.anonymous();
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
anonymousUsername
anonymousEmail
基本例②
- 引数をとる場合
- ※これも書き方が違うのみで、Named constructor、Redirecting constructorsとほぼ同様
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Factory constructors
factory User.anonymous({String username}) {
return User(
id: 'anonymousId',
username: username,
email: 'anonymousEmail',
);
}
}
void main() {
User user = User.anonymous(username: 'TestUser');
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
TestUser
anonymousEmail
基本例③
- ユーザ情報が入ったドキュメント(ここではdocというMap)を引数とし、anonymous(匿名)ユーザを作成することを想定
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Factory constructors
factory User.fromDocument(Map doc) {
return User(
id: doc['id'],
username: doc['username'],
email: doc['email'],
);
}
}
void main() {
User user = User();
final doc = {'id': 'anonymousId', 'username': 'anonymousUsername', 'email': 'anonymousEmail'};
user = User.fromDocument(doc);
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
anonymousUsername
anonymousEmail
基本例④
- ユーザ情報が入ったドキュメント(ここではdocというMap)を引数とし、ユーザを作成することを想定
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Factory constructors
factory User.fromDocument(Map doc) {
return User(
id: doc['id'],
username: doc['username'],
email: doc['email'],
);
}
}
void main() {
User user = User();
final doc = {'id': '001', 'username': 'TestUser', 'email': 'test@email.com'};
user = User.fromDocument(doc);
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
001
TestUser
test@email.com
基本例⑤
- 一度anonymous(匿名ユーザ)等でインスタンス作成後に、中身を入れなおすことが可能
class User {
final String id;
final String username;
final String email;
User({
this.id,
this.username,
this.email,
});
// Named constructors
User.anonymous()
: id = 'anonymousId',
username = 'anonymousUsername',
email = 'anonymousEmail';
// Factory constructors
factory User.fromDocument(Map doc) {
return User(
id: doc['id'],
username: doc['username'],
email: doc['email'],
);
}
}
void main() {
User user = User.anonymous();
print(user.id + '\n' + user.username + '\n' + user.email);
final doc = {'id': '001', 'username': 'TestUser', 'email': 'test@email.com'};
user = User.fromDocument(doc);
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
anonymousId
anonymousUsername
anonymousEmail
001
TestUser
test@email.com
基本例⑥
-
User.fromDocument
を利用したユーザ作成を一度のみに制限- ※returnでインスタンスを返すでインスタンスを返す書き方のため、必ずしもインスタンスを作成しない
class User {
final String id;
final String username;
final String email;
static bool _isCreated = false;
User({
this.id,
this.username,
this.email,
});
// Named constructors
User.anonymous()
: id = 'anonymousId',
username = 'anonymousUsername',
email = 'anonymousEmail';
// Factory constructors
factory User.fromDocument(Map doc) {
if (_isCreated) {
print('正規ユーザを作成済みです。');
} else {
_isCreated = true;
return User(
id: doc['id'],
username: doc['username'],
email: doc['email'],
);
}
}
}
void main() {
User user = User.anonymous();
print(user.id + '\n' + user.username + '\n' + user.email);
final doc = {'id': '001', 'username': 'TestUser', 'email': 'test@email.com'};
user = User.fromDocument(doc);
print(user.id + '\n' + user.username + '\n' + user.email);
user = User.fromDocument(doc);
}
実行結果
anonymousId
anonymousUsername
anonymousEmail
001
TestUser
test@email.com
正規ユーザを作成済みです。
基本例⑦(備考)
- Private constructorとFactory constructorを利用
-
User user = User(doc);
と呼んだ際に、以下のFactory constructor→Private constructorと実行される
-
class User {
final String id;
final String username;
final String email;
// Private constructor
User._({
this.id,
this.username,
this.email,
}) {
print('TEST:A');
}
// Factory constructors
factory User(Map doc) {
print('TEST:B');
return User._(
id: doc['id'],
username: doc['username'],
email: doc['email'],
);
}
}
void main() {
final doc = {'id': '001', 'username': 'TestUser', 'email': 'test@email.com'};
User user = User(doc);
print(user.id + '\n' + user.username + '\n' + user.email);
}
実行結果
TEST:B
TEST:A
001
TestUser
test@email.com
Discussion