我的数据库中有一个名为帖子的表。每个帖子都有名为social_network的字段
当我将所有帖子放入代码中的数组中时,我需要根据其social_network字段为每个帖子创建实例。
现在我为此使用 switch 语句,但我不喜欢它,因为它不灵活。
$posts = DataBase::getPosts(); // pseudocode
foreach($posts as $post) {
switch($post->getSocialNetwork()){
case 'Facebook':
$social = new FacebookPost($post->getId());
break;
case 'Twitter':
$social = new TwitterPost($post->getId());
break;
// .... other social networks
}
}
向 FacebookPost 和 TwitterPost 类添加一个接口(例如 SocialPostInterface),该接口定义了相同的基本必要方法,如 getId()
、postToNetwork()
然后,您可以根据需要添加任意数量的新社交网络,而无需更改这段代码。他们只需要实现接口
然后体验多歧义的力量:
foreach ($posts as $post) {
$className = $post->getSocialNetwork() . 'Post';
// lets check if such class exists
if (!class_exists($className, false /* do not attempt autoload */)) {
throw new Exception("Unknown social network post class $className");
}
$social = new $className($post->getId());
$social->doSomeStuffThatTheInterfaceHasDeclared();
}
我认为你不能避免这种代码。 但是,您可能希望将其移动到抽象工厂中,因此不必在控制器中查看它。
$posts = DataBase::getPosts(); // pseudocode
foreach($posts as $post) {
$social = SocialFactory::post($post);
}
}
$socialClass = $post->getSocialNetwork() . 'Post';
$social = new $socialClass($post->getId());
您可以从保留其名称的字符串创建新对象。