我的数据库中有一个名为帖子的表格。每个帖子都有一个名为 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
}
}
答案 0 :(得分:7)
为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();
}
答案 1 :(得分:4)
我不认为你可以避免这种代码。但是您可能希望将其移动到抽象工厂中,因此您无需在控制器中查看它。
$posts = DataBase::getPosts(); // pseudocode
foreach($posts as $post) {
$social = SocialFactory::post($post);
}
}
答案 2 :(得分:1)
$socialClass = $post->getSocialNetwork() . 'Post';
$social = new $socialClass($post->getId());
您可以从保存其名称的字符串中创建一个新对象。