Java与模式 之 工厂单例模式

之前看过<< Head Frist 设计模式>>一书,对设计模式略有了解,但不清楚真实的Java中是怎么用到的.<< java与模式>>这本书很长,讲的非常详细,这里只摘抄了书中的例子,以此作为笔记学习.

1.工厂模式

1.1 DateFormat

public abstract class DateFormat extends Format {

DateFormat是一个抽象类,但它有静态工厂方法,如下:

private static DateFormat get(int timeStyle, int dateStyle,
                                  int flags, Locale loc) {
        if ((flags & 1) != 0) {
            if (timeStyle < 0 || timeStyle > 3) {
                throw new IllegalArgumentException("Illegal time style " + timeStyle);
            }
        } else {
            timeStyle = -1;
        }
        if ((flags & 2) != 0) {
            if (dateStyle < 0 || dateStyle > 3) {
                throw new IllegalArgumentException("Illegal date style " + dateStyle);
            }
        } else {
            dateStyle = -1;
        }
        try {
            // Check whether a provider can provide an implementation that's closer
            // to the requested locale than what the Java runtime itself can provide.
            LocaleServiceProviderPool pool =
                LocaleServiceProviderPool.getPool(DateFormatProvider.class);
            if (pool.hasProviders()) {
                DateFormat providersInstance = pool.getLocalizedObject(
                                                    DateFormatGetter.INSTANCE,
                                                    loc,
                                                    timeStyle,
                                                    dateStyle,
                                                    flags);
                if (providersInstance != null) {
                    return providersInstance;
                }
            }

            return new SimpleDateFormat(timeStyle, dateStyle, loc);
        } catch (MissingResourceException e) {
            return new SimpleDateFormat("M/d/yy h:mm a");
        }
    }

该方法最后返回一个SimpleDateFormat实例,并且将它声明为DateFormat类型.这是纯正的多态性的运用.

一个中文日期的例子:

@Test
    public void simpleFactory(){
        Locale locale = Locale.CHINA;
        Date date = new Date();
        String now = DateFormat.getDateInstance(DateFormat.DEFAULT, locale)
                .format(date);
        System.out.println(now);
    }

返回结果如下:

2015-11-27

1.2 URL与URLConnection

public final class URL implements java.io.Serializable {

transient URLStreamHandler handler;

public URLConnection openConnection() throws java.io.IOException {
        return handler.openConnection(this);
    }
}

URL对象使用了工厂方法模式,以一个工厂方法openConnection()返回一个URLCollection类型的对象.由于URLConnection是一个抽象类,因此返回的是其具体子类的实例.
handler的初始化方法在URL初始化阶段.

一个访问CSDN的例子:

@Test
    public void factory() throws IOException{
        URL baidu = new URL("http://www.csdn.com");
        URLConnection yc = baidu.openConnection();
        BufferedReader in = new BufferedReader(
                new InputStreamReader(
                        yc.getInputStream()));
        String inputLine;
        while((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        in.close();
    }

返回结果如下:

<!DOCTYPE HTML>
<html>
<head>
<script id="allmobilize" charset="utf-8" src="http://a.yunshipei.com/csdnnet/allmobilize.min.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>CSDN.NET - 全球最大中文IT社区,为IT专业技术人员提供最全面的信息传播和服务平台</title>
<link href="http://c.csdnimg.cn/www/css/csdn_common.css" rel="stylesheet" type="text/css">
<link href="css/content.css" rel="stylesheet" type="text/css">
<link href="http://c.csdnimg.cn/public/favicon.ico" rel="SHORTCUT ICON">
...
...
...
...

2.单例模式

2.1 Properties

属性是系统的一种”资源”,应当避免有多于一个的对象读取,特别是存储属性.此外,属性的读取可能会在很多地方发生,创建属性对象的地方应当在哪里不是很清楚.换言之,属性管理器应当自己创建自己的实例,并且自己向系统全程提供这一实例.
因此,属性管理器应当是由一个单例模式负责的.

properties首先要知道去哪里找key-value键值对,load方法如下:

public synchronized void load(InputStream inStream) throws IOException {
        load0(new LineReader(inStream));
    }

    private void load0 (LineReader lr) throws IOException {
        char[] convtBuf = new char[1024];
        int limit;
        int keyLen;
        int valueStart;
        char c;
        boolean hasSep;
        boolean precedingBackslash;

        while ((limit = lr.readLine()) >= 0) {
            c = 0;
            keyLen = 0;
            valueStart = limit;
            hasSep = false;

            //System.out.println("line=<" + new String(lineBuf, 0, limit) + ">");
            precedingBackslash = false;
            while (keyLen < limit) {
                c = lr.lineBuf[keyLen];
                //need check if escaped.
                if ((c == '=' ||  c == ':') && !precedingBackslash) {
                    valueStart = keyLen + 1;
                    hasSep = true;
                    break;
                } else if ((c == ' ' || c == '\t' ||  c == '\f') && !precedingBackslash) {
                    valueStart = keyLen + 1;
                    break;
                }
                if (c == '\\') {
                    precedingBackslash = !precedingBackslash;
                } else {
                    precedingBackslash = false;
                }
                keyLen++;
            }
            while (valueStart < limit) {
                c = lr.lineBuf[valueStart];
                if (c != ' ' && c != '\t' &&  c != '\f') {
                    if (!hasSep && (c == '=' ||  c == ':')) {
                        hasSep = true;
                    } else {
                        break;
                    }
                }
                valueStart++;
            }
            String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);
            String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);
            put(key, value);
        }

该方法将key-value储存在table中(该table继承自Hashtable).

2.2 Runtime

public class Runtime {
    private static Runtime currentRuntime = new Runtime();
    public static Runtime getRuntime() {
        return currentRuntime;
    }
}

很明显,RunTime类是采用”饿汉”方式实现的.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值