非侵入式开发与接口开发的随笔感想(一)

博主遇到一个程序拓展的问题,现有一种解决思路以做记录 欢迎网友提出不同的想法与解决方式

现有基础jar包类Query部分代码如下

Query类由于是老代码,想不破坏原有调用方法的基础上(不好随便改源码)对其进行增强或者说是简化开发

由于Query类的构造函数为私有的无法简单粗暴的继承实现拓展,直接排除这个想法

/**
 * 查询基础类
 */
public class Query<T> {
    private Class<?> entityClass;
    private List<FilterItem> filterItems;

    private Query() {
        this.init();
    }

    private Query(Class<?> entityClass) {
        this.entityClass = entityClass;
    }
}

解决方式一:常用工具类

每次需要就调用下

至于为什么要这三个方法文末再提

public class QueryUtil {
    private Class clazz;
    QueryUtil(Class clazz){
        this.clazz = clazz;
    }

    /**
     * 创建一个新query查询,并直接传入查询map(首先知道需要新建query对象)
     * @param conditions 查询条件
     * @return
     */
    public Query getSimpleQuery(Map<String, Object> conditions) {
        Query query = Query.from(clazz);
        return getSimpleQuery(query,conditions);
    }

    /**
     *  创建一个默认查询(无需了解query对象是否为空)
     *  如果query为空则新建
     * @param query
     * @param conditions 查询条件
     * @return
     */
    public Query getDefaultQuery(@Nullable Query query, Map<String, Object> conditions) {
        query = query==null?getSimpleQuery(conditions):getSimpleQuery(query,conditions);
        return query;
    }

    /**
     * 对已有query对象进行加工
     * @param query
     * @param conditions 查询条件
     * @return
     */
    public static Query getSimpleQuery(@NotNull Query query, Map<String, Object> conditions) {
        query.filter(conditions, null, FilterOperator.LIKE);
        try {
            CommonHelper.getQueryFilter(query, conditions);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return query;
    }
}

有了这个工具类每次需要对query对象简单添加一些查询条件只需要实例化一下QueryUtil接方法,或者有query对象时直接调静态方法QueryUtil.getSimpleQuery(...,...,...)即可

Query query = new QueryUtil(Object.class).getSimpleQuery(conditions);

方式二 提取接口

在方法一中每次想获得一个query基本得实例化一个工具类,稍显复杂,所以准备提取一个接口类实现其功能

以下为jdk1.8实现方式

public interface CommonQueryInterface {
    /**
     * 创建一个新query查询,并直接传入查询map(首先知道需要新建query对象)
     */
    Query getSimpleQuery(Map<String, Object> conditions);

    /**
     * 创建一个默认查询(无需了解query对象是否为空)
     * 如果query为空则新建
     */
    default Query getDefaultQuery(@Nullable Query query, Map<String, Object> conditions){
        query = query==null?getSimpleQuery(conditions):getSimpleQuery(query,conditions);
        return query;
    }

    /**
     * 对已有query对象进行加工
     */
    default Query getSimpleQuery(@NotNull Query query, Map<String, Object> conditions) {
        query.filter(conditions, null, FilterOperator.LIKE);
        try {
            CommonHelper.getQueryFilter(query, conditions);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return query;
    }
}

以及其实现类

public class CommonQuery implements CommonQueryInterface {

    private Class clazz;

    public CommonQuery(Class clazz){
        this.clazz = clazz;
    }

    @Override
    public Query getSimpleQuery(Map<String, Object> conditions) {
        Query query = Query.from(clazz);
        return getSimpleQuery(query,conditions);
    }
    @Override
    public Query getDefaultQuery(@Nullable Query query, Map<String, Object> conditions) {
        query = query==null?getSimpleQuery(conditions):getSimpleQuery(query,conditions);
        return query;
    }

    //ToDo
   /* public Query getSimpleQuery(@NotNull Query query, Map<String, Object> conditions) {

    }*/
}

这种方式的好处是

想实现时可以让类实现下CommonQueryInterface接口的getSimpleQuery(Map<String, Object> conditions)方法就能直接调用该功能,并且可以选择性的重写默认实现。如CommonQuery类只是重写了一个getDefaultQuery方法

而CommonQuery类只是一个案例作用,实际开发中CommonQuery类的通过构造函数传参也可省去,如下

public class CmsServiceImpl implements CmsService, CommonQueryInterface {
    @Override
	public Query getSimpleQuery(Map<String, Object> conditions) {
		Query query = Query.from(Object.class);
		return getSimpleQuery(query,conditions);
	}
}

该类由于是具体业务类专项处理一个类,所以直接可以指定Object.class作为参数,无需外部传参,从而更加简化了方法一中的实例化再调用,同时方法的重写也能提升代码的扩展性。

方式三 jdk1.8以下环境的接口

由于博主开发的项目中还有是1.6版本的,所以思考了下没有1.8特性的实现方式

在方法一的基础上

首先是1.6中的接口

public interface CommonQueryInterface {
    /**
     * 创建一个新query查询,并直接传入查询map(首先知道需要新建query对象)
     */
    Query getSimpleQuery(Map<String, Object> conditions);

    /**
     * 创建一个默认查询(无需了解query对象是否为空)
     */
    Query getDefaultQuery(@Nullable Query query, Map<String, Object> conditions);
}

缺少了默认实现只能将方法一中的静态方法砍掉,由实现类CommonQuery实现

public class CommonQuery implements CommonQueryInterface {

    private Class clazz;

    public CommonQuery(Class clazz){
        this.clazz = clazz;
    }

    @Override
    public Query getSimpleQuery(Map<String, Object> conditions) {
        Query query = Query.from(clazz);
        return getSimpleQuery(query,conditions);
    }
    @Override
    public Query getDefaultQuery(@Nullable Query query, Map<String, Object> conditions) {
        query = query==null?getSimpleQuery(conditions):getSimpleQuery(query,conditions);
        return query;
    }

    public static Query getSimpleQuery(@NotNull Query query, Map<String, Object> conditions) {
        query.filter(conditions, null, FilterOperator.LIKE);
        try {
            CommonHelper.getQueryFilter(query, conditions);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return query;
    }
}

此时的CommonQuery必须实现两个方法,再加入一个静态方法完成对方法一中工具类的替代

而调用这个功能又分为继承CommonQuery与重新实现CommonQueryInterface接口两种

继承CommonQuery

由于java是单继承的语言,选用类继承CommonQuery,一定程度上代码量较少,但是如果有其他类需要继承需要就麻烦了如下

public class CmsServiceImpl extends CommonQuery {
    public CmsServiceImpl(Class clazz) {
        super(clazz);
    }
    
    public void test(){
        super.getSimpleQuery(new HashMap<String, Object>());
    }
}

重新实现CommonQueryInterface接口

重新实现就要copy CommonQuery类的代码了

此处第三个方法可以直接调用下CommonQuery类的静态方法,或者手动补上。其他两个方法实现即可,同样拥有方法二中免构造函数传参的优点与接口实现重写的扩产性优点。

public class CmsServiceImpl implements CommonQueryInterface {
    

    public void test(){
        getSimpleQuery(new HashMap<String, Object>());
    }

    @Override
    public Query getSimpleQuery(Map<String, Object> conditions) {
        Query query = Query.from(Object.class);
        return CommonQuery.getSimpleQuery(query,conditions);
    }

    @Override
    public Query getDefaultQuery(@Nullable Query query, Map<String, Object> conditions) {
        query = query==null?getSimpleQuery(conditions):CommonQuery.getSimpleQuery(query,conditions);
        return query;
    }
}

最后

关于为啥这个工具类要三个方法

博主是这么认为的 在以上三个工具类的方法中

单参方法(getSimpleQuery) 调用简单,但是必须知道需要新建Query对象

静态双参方法(getSimpleQuery) 只面向于Query的加工,但是必须知道是对已有Query对象的加工

动态双参方法(getDefaultQuery) 无论这个query对象是否存在,他都能顺利调用中间过程 产出一个符合条件的Query对象

三个方法都致力于解决query对象的形成与加工,但是面向的开发需要与侧重不相同,所以这么设计

通过代理来解决这个功能拓展

待博主的下一篇博文记录下

 

以上内容仅博主今日一思路,欢迎网友提出其他思路与解决方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值