worldwind学习笔记-9-从头开始,单例模式

来源:互联网 发布:linux查看登录失败日志 编辑:程序博客网 时间:2024/06/10 02:00

        我突然发现我想错了,我想要把worldwind搞清楚,为啥要单单把这个程序搞清楚呢,我玩了一段时间,开了一段时间的大差,读了其他的一些源代码,又搞了搞python,搞了搞arcgis,然后还文艺的读了读一些与程序代码完全无关的东西。


其中在一个街边发的杂志上看到过一篇文章,写的是绿花匠和金花匠,大体就是说两个花匠都想培育出黑色的一种花,其中绿花匠是通过每年都把颜色深的花继续培育,其他的舍弃掉,最后培育出了黑色的花,然后获得了绿花匠的称号,然后金花匠则不同,他在种花的同时,把每一种颜色的花都相互搭配,最终,他中出了各种颜色的花,所以他获得了金花匠的称号。


我这个不靠谱的程序员,从来就没想过要在气象上成为很深入的码农,我知道优秀的程序员一定是在用户的行业同样精通的,但是我觉得,我不太想精通行业,尤其是气象行业。所以我想着,我刚刚毕业,我还有其他的路可走,所以我只想增加我的代码能力。所以说,worldwind对我来说,应该是一款促进我代码能力提高的源码,我从他身上,学到的应该是编码的各种方法,规范等。


之前看一个伙计对worldwind的学习,他认为org.codehaus.jackson这个包下面的东西是基础,然后研究这个代码去了。。。我觉得他可能也跑偏了,然后有人出书了,没钱买不起,要不也可以读一读。


我觉得要学他里面的东西,不应该只看代码或者只看局部,应该学的是他整个的思想,以及对架构的应用,总之就是,可以学的东西很多。我先把我看懂的列出来。

首先就是,ApplicationTemplate的代码中main中,有static部分,这里一定是优先执行的,这里就有一个知识点:类中各个模块的执行顺序。找了个相关的文档给大家:http://www.cnblogs.com/panjun-Donet/archive/2010/08/10/1796209.html  java中静态代码块的用法 static用法详解。事实上,在我读过的一本语言设计者访谈记录里面,印象里c#的作者对java中math的做法嗤之以鼻,因为math居然全部是static的,把java引以为傲的面向对象的概念完全无视,这是糊自己熊脸的节奏啊。这个类对于面向对象编程似乎是一个很奇怪的存在。


System.setProperty方法,这个是我觉得的第二个知识点,初学java的时候长期使用system.out和system.in,system.error,但是,大部分情况下指示用它来打印下,它还有很多很多功能,却基本上没有在java教程里介绍到。然后,它包含了不少常用类的常用方法,以及标准输入流,标准输出流,标准错误流,外部配置文件,他还能控制类加载器去load文件,去loadLibrary,还能执行arraycopy方法,功能确实强大。这里,wwj(worldwind java的简写,不少研究wwj的人都这么简写他,我也沿用了)用它来做配置,进行项目启动时的简单配置。


Configuration,又一个知识点,和设计模式相关的,这个Configuration用的就是设计模式里所谓的单例模式,public class Configuration // Singleton好吧,他的注释里,类名后直接表上了单例模式的英文,此类上方的注释里就把啥事单例模式说了下,不过如果对英文不感兴趣,去http://baike.baidu.com/link?url=Ev2hyHRUXufcj_OcQbiMl9F-oGHNRq3UTauymlNc78I0BfRCWk08piVCwSTbPw9rYwgPHwRn1_Jt2ifs36PDyK#6_1 百度百科看看吧,其中有java的事例。


再来看看Configuration的构造方法,先来一个initializeDefaults(),这里利用时区计算经纬度并初始化,是不是很神奇,来看看怎么算的。。。。。


似乎很简单啊,翻译出来就是180°*(当前时间(单位毫秒)-当前时区(单位毫秒))/(12小时*60分*60秒*1000毫秒)=单前时区的经度。比如我现在是下午四点,我的时区是北京+8时区(东八区),所以,我的经度就是180°*(16-8)/12=120°,bingo,然后就初始化我的位置了。Calendar和TimeZone就不介绍了,虽然用的很多,但是也只是使用。


不过这个知识点不在这,而是在Properties,这是java中用来存储系统变量的,是键值对的形式,extends Hashtable<Object,Object>,这玩意是早起java项目里的神器,功能强大,只要看到项目里有xxx.properties,差不多就有用这个类。此类功能强大,在《Java2核心技术第I卷.基础知识》最后的部分就单独的几页来讲解他,因为版本不一样,第七版里一部分在第八版移动到卷2去了,我看的第八版,再付一个地址吧,写怎么用这个文件的,感兴趣的同学们学一学。http://www.cnblogs.com/panjun-Donet/archive/2009/07/17/1525597.html


然后,返回到Configuration的构造方法这里,他在initializeDefaults之后紧接着调用了String appConfigLocation = System.getProperty(CONFIG_APP_DOCUMENT_KEY);这里就是刚刚说的第二个知识点,去读取CONFIG_APP_DOCUMENT_KEY对应的配置数据,由于我执行的是ApplicationTemplate,没有设置这个值,所以if判断直接失败了,到第二个try中,执行了这个this.loadConfigDoc(System.getProperty(CONFIG_WW_DOCUMENT_KEY, CONFIG_WW_DOCUMENT_NAME));,我觉得这个实在不值得说是知识点,重载。。System.getProperty被重载了,public static String getProperty(String key),public static String getProperty(String key, String def),第一个是读取键值对,失败的话他就会..The method returnsnull if the property is not found.然后第二个,则是对第一个的补充,第一个失败没有,就是null,第二个,如果为null,就返回def值。


我觉得这里有个值得学习的东西,就是xml文件的读取,用到了Document,来自于java标准包中的rt.jar中的org.w3c.dom,这个应该是和xml的dom编程有关,来个地址吧:http://www.w3school.com.cn/xmldom/index.aspjava对xml文档的操作教程蛮多的,这个用的是基础包,所以通用性应该会好点吧。。。话说,貌似现在很少有通用性差的jar包了。


然后,WWXML.openDocument(configLocation);他的代码我要不要贴呢,算了,不贴了,我比较懒,自己看到就好。还是贴一下吧。

/**     * Open and XML document from a general source. The source type may be one of the following: <ul> <li>a {@link     * URL}</li> <li>an {@link InputStream}</li> <li>a {@link File}</li> <li>a {@link String} containing a valid URL     * description or a file or resource name available on the classpath.</li> </ul>     *     * @param docSource the source of the XML document.     *     * @return the source document as a {@link Document}, or null if the source object is a string that does not     *         identify a URL, a file or a resource available on the classpath.     */    public static Document openDocument(Object docSource)    {        if (docSource == null || WWUtil.isEmpty(docSource))        {            String message = Logging.getMessage("nullValue.DocumentSourceIsNull");            throw new IllegalArgumentException(message);        }        if (docSource instanceof URL)        {            return openDocumentURL((URL) docSource);        }        else if (docSource instanceof InputStream)        {            return openDocumentStream((InputStream) docSource);        }        else if (docSource instanceof File)        {            return openDocumentFile(((File) docSource).getPath(), null);        }        else if (!(docSource instanceof String))        {            String message = Logging.getMessage("generic.UnrecognizedSourceType", docSource.toString());            throw new IllegalArgumentException(message);        }        String sourceName = (String) docSource;        URL url = WWIO.makeURL(sourceName);        if (url != null)            return openDocumentURL(url);        return openDocumentFile(sourceName, null);    }

这个东西的这种写法,我觉得很像

public class Factory{public static Sample creator(int which){//getClass 产生Sample 一般可使用动态类装载装入类。if (which==1)return new SampleA();else if (which==2)return new SampleB();}}那么在你的程序中,如果要实例化Sample时.就使用Sample sampleA=Factory.creator(1);

工厂模式,设计模式里面的东东,工厂模式定义:实例化对象,用工厂方法代替new操作。


所以说这里的话,也是一个类似工厂的东西,按照Object的不同实例,调用不同的方法,不过最后产生的是相同的Document。

他代码里还用到了一个东东instanceof,相当于c#中的is,我一直觉得c#比java牛逼,因为他更统一更好学,用起来也更方便,代码蓝领的实现用c#更快。

然后就得到doc了。。继续回构造函数,他要把xml文件中的值存放到property里面去了,所以使用了这样的代码

for (int i = this.configDocs.size() - 1; i >= 0; i--)
            {
                this.loadConfigProperties(this.configDocs.get(i));
            }

之所以这样子做,是因为CONFIG_APP_DOCUMENT_KEY和CONFIG_WW_DOCUMENT_KEY,当用户自己有配置文件时,会产生两个doc对象,通过逆序的方式,保证property里面存储的值是用户定义的。


然后读的时候就简单了,loadConfigProperties里面不断的吧@name和@value按照键值对的形式读出来。


这里的话,wwj是为了照顾早起的wwj版本吧,所以xml文件才会要求键值对的形式存在,这样子有不好的地方,就是会限制xml文件的功能,导致文档的格式比较固定,不能表达更多的数据。


再然后,config里面的不少静态方法,提供了很多的功能,用于后面程序使用的支持。


光一个Configuration就让我看到了不少java的知识点,我觉得wwj确实牛。