栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【从优秀源码中学习设计模式】--- 建造者模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【从优秀源码中学习设计模式】--- 建造者模式

前言

本文以Java语言为主,分析包括JDK、Spring、MyBatis、Guava等一些优秀的开源代码、项目,在这些开源代码、项目中都包含了大量的设计模式,通过对它们进行分析,能够快速帮助我们学会设计模式的使用方式,由理论过渡到实践中,进而真正了解设计模式的思想,由于内容较多,所以每个设计模式单独写一篇文章,需要了解其他模式请点击对应链接跳转。

装饰器模式
适配器模式

建造者模式 JDK

Calendar这个类提供了通过建造者模式构建对象的方式

public Calendar build() {
    if (locale == null) {
        locale = Locale.getDefault();
    }
    if (zone == null) {
        zone = TimeZone.getDefault();
    }
    Calendar cal;
    if (type == null) {
        type = locale.getUnicodeLocaleType("ca");
    }
    if (type == null) {
        if (locale.getCountry() == "TH"
            && locale.getLanguage() == "th") {
            type = "buddhist";
        } else {
            type = "gregory";
        }
    }
    switch (type) {
    case "gregory":
        cal = new GregorianCalendar(zone, locale, true);
        break;
    case "iso8601":
        GregorianCalendar gcal = new GregorianCalendar(zone, locale, true);
        // make gcal a proleptic Gregorian
        gcal.setGregorianChange(new Date(Long.MIN_VALUE));
        // and week definition to be compatible with ISO 8601
        setWeekDefinition(MONDAY, 4);
        cal = gcal;
        break;
    case "buddhist":
        cal = new BuddhistCalendar(zone, locale);
        cal.clear();
        break;
    case "japanese":
        cal = new JapaneseImperialCalendar(zone, locale, true);
        break;
    default:
        throw new IllegalArgumentException("unknown calendar type: " + type);
    }
    cal.setLenient(lenient);
    if (firstDayOfWeek != 0) {
        cal.setFirstDayOfWeek(firstDayOfWeek);
        cal.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek);
    }
    if (isInstantSet()) {
        cal.setTimeInMillis(instant);
        cal.complete();
        return cal;
    }
    if (fields != null) {
        boolean weekDate = isSet(WEEK_YEAR)
                               && fields[WEEK_YEAR] > fields[YEAR];
        if (weekDate && !cal.isWeekDateSupported()) {
            throw new IllegalArgumentException("week date is unsupported by " + type);
        }
        // Set the fields from the min stamp to the max stamp so that
        // the fields resolution works in the Calendar.
        for (int stamp = MINIMUM_USER_STAMP; stamp < nextStamp; stamp++) {
            for (int index = 0; index <= maxFieldIndex; index++) {
                if (fields[index] == stamp) {
                    cal.set(index, fields[NFIELDS + index]);
                    break;
                }
            }
        }
        if (weekDate) {
            int weekOfYear = isSet(WEEK_OF_YEAR) ? fields[NFIELDS + WEEK_OF_YEAR] : 1;
            int dayOfWeek = isSet(DAY_OF_WEEK)
                            ? fields[NFIELDS + DAY_OF_WEEK] : cal.getFirstDayOfWeek();
            cal.setWeekDate(fields[NFIELDS + WEEK_YEAR], weekOfYear, dayOfWeek);
        }
        cal.complete();
    }
    return cal;
}
MyBatis

MyBatis中有很多构建对象的方式都使用到了建造者模式

比如缓存对象,这个对象的生成又包含了建造者模式,又包含了前面看到的装饰器模式。

public Cache useNewCache(Class typeClass,
      Class evictionClass,
      Long flushInterval,
      Integer size,
      boolean readWrite,
      boolean blocking,
      Properties props) {
    Cache cache = new CacheBuilder(currentNamespace)
        .implementation(valueOrDefault(typeClass, PerpetualCache.class))
        .addDecorator(valueOrDefault(evictionClass, LruCache.class))
        .clearInterval(flushInterval)
        .size(size)
        .readWrite(readWrite)
        .blocking(blocking)
        .properties(props)
        .build();
    configuration.addCache(cache);
    currentCache = cache;
    return cache;
  }

MappedStatement对象

  public MappedStatement addMappedStatement(
      String id,
      SqlSource sqlSource,
      StatementType statementType,
      SqlCommandType sqlCommandType,
      Integer fetchSize,
      Integer timeout,
      String parameterMap,
      Class parameterType,
      String resultMap,
      Class resultType,
      ResultSetType resultSetType,
      boolean flushCache,
      boolean useCache,
      boolean resultOrdered,
      KeyGenerator keyGenerator,
      String keyProperty,
      String keyColumn,
      String databaseId,
      LanguageDriver lang,
      String resultSets) {

    if (unresolvedCacheRef) {
      throw new IncompleteElementException("Cache-ref not yet resolved");
    }

    id = applyCurrentNamespace(id, false);
    boolean isSelect = sqlCommandType == SqlCommandType.SELECT;

    MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType)
        .resource(resource)
        .fetchSize(fetchSize)
        .timeout(timeout)
        .statementType(statementType)
        .keyGenerator(keyGenerator)
        .keyProperty(keyProperty)
        .keyColumn(keyColumn)
        .databaseId(databaseId)
        .lang(lang)
        .resultOrdered(resultOrdered)
        .resultSets(resultSets)
        .resultMaps(getStatementResultMaps(resultMap, resultType, id))
        .resultSetType(resultSetType)
        .flushCacheRequired(valueOrDefault(flushCache, !isSelect))
        .useCache(valueOrDefault(useCache, isSelect))
        .cache(currentCache);

    ParameterMap statementParameterMap = getStatementParameterMap(parameterMap, parameterType, id);
    if (statementParameterMap != null) {
      statementBuilder.parameterMap(statementParameterMap);
    }

    MappedStatement statement = statementBuilder.build();
    configuration.addMappedStatement(statement);
    return statement;
  }
Guava

看起来构建缓存对象非常适合使用建造者模式,在Guava中也和MyBatis一样,选择了建造者模式。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/389730.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号