嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

周梦康 发表于 2015-08-30 11106 次浏览 标签 : Java

免费领取阿里云优惠券 我的直播 - 《PHP 进阶之路》

场景如下,我需要给客户端输出不同格式的用户列表,有的地方只需要3个字段(id,昵称,头像),有的地方需要4个字段(id,昵称,头像,是否关注)本来是这样写的

class UserService {

    public static List<User> userList(ArrayList<Integer> ids,int type){

        if (ids == null) {
            return null;
        }

        List<User> users = new ArrayList<>();

        Iterator<Integer> it = ids.iterator();

        if (type == 1) {
            while(it.hasNext()){
                users.add(userTemplate1(it.next()));
            }
        } else if (type == 2) {
            while(it.hasNext()){
                users.add(userTemplate2(it.next()));
            }
        }

        return users;
    }

    private static User userTemplate1(int uid){
        User user = new User();
        //....
        return user;
    }

    private static User userTemplate2(int uid){
        User user = new User();
        //....
        return user;
    }
}
但是发现这个类实现的功能很杂了,有好多模板的输出,而我这个类的定位给 Api 的做数据格式封装和业务处理的,这里混杂着大量的模板方法也觉得比较混乱,还有多人协同工作时的一些不便利性,大家新增模板的时候都要修改该类,而且要在调用模板方法的地方加上一个 else 判断。

然后做了下修改,在需要使用模板的地方用一个接口接受,然后通过不同的模板类来实现这个接口即可,也不知道这样做是否正确,可取。

class UserService {

    public interface UserTemplate{
        User createUser(int id);
    }

    public static List<User> userList(ArrayList<Integer> ids,UserTemplate userTemplate){

        if(ids == null || ids.size() < 1){
            return null;
        }

        List<User> users = new ArrayList<>();

        Iterator<Integer> it = ids.iterator();
        while(it.hasNext()){
            users.add(userTemplate.createUser(it.next()));
        }

        return users;
    }

}

public class UserTemplateImpl {

    /**
     * 只显示用户的 id/昵称/头像
     */
    public static class userInfoLite implements UserService.UserTemplate {

        @Override
        public User createUser(int id) {
            User user = new User();
            //...
            return user;
        }
    }

    /**
     * 显示用户的 id/昵称/头像/粉丝数
     */
    public static class feedMasterInfo implements UserService.UserTemplate {

        @Override
        public User createUser(int id) {
            User user = new User();
            //...
            return user;
        }
    }

}

调用的时候

List<User> users = UserService.userList(ids, new UserTemplateImpl.feedMasterInfo());
UserService.userList(ids, new UserTemplateImpl.userInfoLite());

说完 Java 说说我大 PHP,我大 PHP 来实现这个就简单很多

<?php
class UserService {

    public static function userList($ids,$templateName){

    	if (!is_array($ids)) {
    		return false;
    	}

       	$users = array();

       	foreach ($ids as $key => $value) {
       		// 多个参数则用 call_user_func_array
       		$users[] = call_user_func(array("UserTemplate",$templateName),$ids);
       	}

        return $users;
    }

}

class UserTemplate {
	public static function userInfoLite($id){
		//...
		return $userInfo;
	}
	public static function feedMasterInfo($id){
		//...
		return $userInfo;
	}
}

UserService::userList($ids,"userInfoLite");

嗨,老铁,欢迎来到我的博客!

如果觉得我的内容还不错的话,可以关注下我在 segmentfault.com 上的直播。我主要从事 PHP 和 Java 方面的开发,《深入 PHP 内核》作者之一。

[视频直播] PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 直播中我将毫无保留的分享我这六年的全部工作经验和踩坑的故事,以及会穿插着一些面试中的 考点难点加分点

评论列表