枫叶工作室

世界开始聆听我的声音!
posts - 6, comments - 8, trackbacks - 0, articles - 1
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

公告

2008年12月19日

摘要: 真的是很不错的软件和实现思路,可以一个地方写,多个地方发布。 只是可惜,很多国内的博客网站都不支持,包括新浪博客,搜狐博客,百度hi,饭否等常用的博客都不怎么支持!阅读全文

posted @ 2008-12-19 14:27 wjk.net 阅读(8) 评论(0) 编辑

2008年9月9日

http://map.wuhan.net.cn/
主要特点:
1、地面街景:道路上每个位置都可以查看环境街景;
2、影像功能:影像照片可以放大,可以用键盘逛街式的向前查看街景;并可直接在街景照片上做标注;
3、POI照片:每个POI都有与影像显示的照片,可直接检索;
4、全景:可360度全景方式查看某个位置的街景实景;
5、街景导航:在地图上任意选择两个位置进行导航,在导航的线路上可播放街景照片;
6、视频导航:在地图上任意选择两个位置进行导航,在导航的线路上可播放街景视频;
7、路口广告:在导航的每个路口壳设置广告位;
8、模拟驾驶:可选择步行方式或者驾驶方式查看街景,并用键盘直接在地图上行走。
9、免费短信:公交查询或者试驾驶查询的结果可免费发送到手机短信上。
10、数据量大,速度快:相对于这种大资源的地图网站,访问速度已经上了一个台阶。
 

posted @ 2008-09-09 21:21 wjk.net 阅读(819) 评论(3) 编辑

虽然目前在公司相当忙,但是仍然有必要讨论一下div+css的问题。因为它已经不再是两年前那个新鲜的名词了。它正逐渐步入广大传统Web开发、设计人员的视野。它的好、他的坏,已经逐渐开始成为前端开发工程师争论的焦点。

今天偶然看到“一个有将近两年的div + CSS 开发经验和历史,曾经是Web标准绝对拥趸的同志”在自己的blog上发表放弃div+css的申明。我更深感一种悲哀——特别是当我苦口婆心地劝说公司的前端开发人员开始学习DIV+CSS的时候。

不过看看这个“好同志”放弃的理由的其中两条,不禁让我所心冷。

公司领导及客户不关心这个,他们需要的是快速、高效的工作和花哨的页面
所费功夫与收入不成正比,利用table可以大大减少工作量 
 

确实,当今市场环境下,div+css对于一个财力一般的公司是一种奢侈。尤其是对于那种靠业务员疯狂跑业务而存活的(不打算上市)的公司,是一种莫大的浪费。我在广州曾见过许多“三天建站”的公司其中90%的人在外跑业务,然后10%的垃圾web开发设计人员把代码一遍一遍的往table里面塞。

甚至可以这么说,一个公司对div+css的认同和投入,直接决定了这个公司的期望目标,比如上市。好在我现在所在的公司在这一点上是非常愿意付出代价的。

其实,在具体商业产品实现上,并非一定要把自己拘泥于“Web标准绝对拥趸”的角色。我们似乎应该静心思考为什么使用div+css,而不是如何实现某个细节。

我们公司面临的困境则是相反的。就是太拘泥于div+css、为了DIV+CSS而DIV+CSS。这样做是毫无意义的。如果为了实现一个效果而不顾策略强行使用一种技术,是非常失败的一种做法。当然,我觉得这需要设计人员与开发人员的共同努力和让步。尤其是在B/S架构下。设计者肯定要做出更多的让步。比如某个布局中1px的差距能节省3k的HTML文件size,哪怕放弃视觉上这1px的效果,我看都值得。更何况,大多数干扰DIV+CSS布局的设计本身也是极不美观的。

movivi.com的SEO我思考了很多。我觉得最大的问题就出在我们并没有足够吃透W3C上。

当时,当w3c刚出的时候,三大门户十分不屑。清一色的table遍布整个首页。可是这样导致的问题不久就暴露出来了。搜索引擎爬虫难以解析复杂的table,而样式的改版也极为难受。

div+css,这个布局中,div承载的是内容,而css承载的是样式。内容和样式的分离对于所见即所得的传统table编辑方式确实是一个很大的冲击,尤其是设计人员很难接受设计一个他们不能立即看到的样式。不过div+css的好处实在是太明显了:

1、搜索引擎亲和力:搜索引擎不会在意一个页面的设计或者构成。搜索引擎不可能“欣赏”设计漂亮新颖的页面;也不会去“排斥”颜色搭配丑陋的页面。它们只是默默地拿到它们需要的内容就离开。如果一个页面中涵盖了大量的table来描述构架,试想搜索引擎要花多大的代价才可以拿到真正有用的信息呢?
凭我自己的经验,一般来说,table构架描述的页面,样式结构和内容信息大小比可能达到1:1甚至更高。而CSS+DIV构架的页面,虽然在客户端看来下载一个复杂的CSS也要占用差不多的带宽,然而搜索引擎可以很方便的绕过这个css,而直接抓去div中的内容。这便是div的优势所在。带宽的稍多占用,完全显得微不足道,更何况一个冗余的table设计架构如果代码写的不好会占用更多的带宽。

2、重构页面的方便性。
这个应用最经典的例子就是各大blog程序了。就如现在我用的LBS系统,以及流行的PJBLOG、php下面的WP、MT,都是采用div+css构架。内容和样式的分离导致我们在重构页面布局(更换皮肤)的时候,只用针对每一个div元素重新定义其具体位置、样式就行了。而在原来的table基础上进行改版,几乎必须改变所有的内容注入渠道,实在是太过于麻烦.
关于韩国风格网站难用div描述的问题,我个人认为在web2.0的大军冲击下,韩国的花哨流派很快会被简约派所代替。如果确实是优秀的设计,我个人认为用Flash来完成更好!

posted @ 2008-09-09 21:05 wjk.net 阅读(48) 评论(1) 编辑

2006年5月29日

最初之所以要采用插件的形式进行开发,主要是为了解决功能服务的热插拔问题,在决定采用框架+插件的方式进行设计后,我们就更进一步,打算将一个个可以分割开来的拥有完整功能的组件都做成插件的形式,并且使同类型的插件的接口兼容,这样在以后需要改变时就可以灵活的进行替换。比如,将通信部分做成通信插件、日志记录部分做成日志插件等等。

 

 

首先,我们要弄清楚,什么是插件?我给出了一个定义,可能有失偏颇。

 

 

    插件又称为扩展,是一种特殊的组件,用于增强和扩展基本框架的行为能力。插件和框架的通信协议是一组接口,插件的各种特性都可以通过该接口进行访问。插件主要有如下特点:

 

 

(1)一个插件是一个独立的物理单元。它可以独立的提供一项完整的服务(功能),而不需要依赖于其它插件。

 

 

(2)插件能自我描述 ―― 插件的所有对外的发布信息都由插件自己内部提供,而不依赖于外部文件或注册表。

 

 

(3)插件能自我管理 ―― 插件如果需要配置信息,则插件自己能读取和修改配置信息,而不是框架来完成这些事情。

(4)
插件自我独立   ―― 一个插件不得引用其它的插件。如果一个插件与另一个插件关系紧密,那么应该将这两个插件合成一个插件,或者重新分解为两个独立的插件

 

 

DataServer系统中,所有的插件从IAddin继承,IAddin接口定义如下: 

 

 

public interface IAddin
    
{
        
void Start() ; //不同类型的插件对开始和停止的解释不一样,如果一个插件没有此意义,可实现为空
        void Stop() ;
        
int ServiceKey {get ;} 
        
string ServiceName {get ;}     
        
string Description {get ;} //插件说明信息
        AddinAppendixInfo AddinAppendixInfo {get ;} 

        
string AddinType {get ;}
    }
    

 

 


接口中的所有方法属性的意义一目了然,其中,ServiceKey是插件关键字,用于区分不同的插件。我们可以把同一类型的插件的关键字限定在某个范围之内,比如,我将通信插件的关键字范围限定在20002999之间。AddinAppendixInfo用于描述插件的附加信息,如作者、创建日期、版本号等。

 

 

public class AddinAppendixInfo
    
{
        
public string Author ;
        
public string TimeCreated ;
        
public string TimeLastRevised ;
        
public string AddinVersion ;
    }

 

 

 

 

 

AddinType是插件类型,在DataServer中,有如下几种插件类型:

 

 

public class AddinTypes
    
{
        
public const string Net                = "通信插件" ;
        
public const string Function           = "功能插件" ;
        
public const string Reporter           = "报告者插件" ;
        
public const string BasicReqDealer     = "基本请求处理者插件" ;
        
public const string RespondInterceptor = "回复截获者插件" ;
    }

 

 


每种类型的插件的功用将在后面说明。

 

 

 

 

 

大部分插件都需要进行配置,我将配置部分抽象为一个公共的接口,IAddinConfig定义如下:

 

 

public interface IAddinConfig
    
{
        
//以下方法返回的控件或窗体必须实现EnterpriseServerBase.Configure.IConfigControl接口
        IConfigControl GetAddinConfigForm() ;
        IConfigControl GetAddinConfigControl() ;        
    }

 

 


这样,一个插件如果需要配置信息,则实现该接口即可。前面已经提到插件如果需要配置信息,则插件自己能读取和修改配置信息,而不是框架来完成这些事情,插件就是通过IAddinConfig接口来操作配置信息的。GetAddinConfigForm用于获取一个独立的配置窗体,通过此窗体可以完成对插件配置,而GetAddinConfigControl获取的是一个配置控件,一般其结构与功能和配置窗体一样,只不过它可以嵌入到其它任意的窗体中,比如到时,我们可以在主框架中设置一个专门用于配置的TabControl,而其中的每一页就用于加载一个GetAddinConfigControl返回的配置控件,从而实现对配置的统一管理。

 

 

IConfigControl究竟是如何操作配置信息的?其定义如下:

 

 

public interface IConfigControl
    
{
        
bool Initialize(string configPath ,string objName) ; //objName 是配置文件中的对象名
        bool SaveConfig() ;
        
bool ReDisplayConfigInfo() ; //显示更新后的配置信息

        
event EventHandler ConfigChanged ; 
    }
    

 

 


一般,配置信息保存于配置文件中,所以初始化时要给出配置路径,而objName参数的作用,可以参见前面的《如何使用XCodeFactory自动生成XML配置文件和对应的解析类?》这篇文章,我的所有于配置文件相关的解析类和配置窗体都是通过XCodeFactory自动生成的。XCodeFactory接口的其它几个方法的意思很明显,就不用解释了。

 

 

接下来,我们看看如何将插件加载到系统中。

 

 

我们都知道,一个插件是一个独立的物理单元,我们如何获得该插件的类型了?有很多办法可以解决,比如,我们访问插件目录下的每个插件,通过Assembly.LoadFrom加载一个插件,然后Type. IsSubclassOf查看其是否实现了某种插件类型的接口,从而判断其类型。我采用了更直观的方式,用插件的名字来标志其类型,比如所有的通信插件都以NetAddin.dll结尾。

 

 

可以用一个特定的模块来加载插件,我称之为插件加载器,插件加载器用于加载某目录下的所有特定类型的插件,"特定"表现在两个方面:(1)插件的名字以[addinSign].dll结尾;(2)插件中的主类是从[baseAddinType]继承。插件加载器的接口定义如下:

 

 

public interface IAddinLoader
    
{            
        ArrayList LoadAddins(
string addinFolderPath ,string addinSign ,Type baseAddinType) ;
    }

 

 


很简单,只有一个方法,该方法加载某目录下的所有某特定类型的插件,而返回的列表中的每个元素就引用着一个插件。

 

 

插件加载器仅仅负责将某种类型的插件加载进来,但是如何实现将所有的插件加载进来、并动态的加载/移除插件了?我们需要一个管理器组件来完成这件事情,它就是IAddinManagement,其接口定义如下:

 

 

public interface IAddinManagement
    
{
        
void LoadAllAddins(string addin_FolderPath ) ;
        
bool ReLoadAddins(out int increment) ;
        
void UnloadAllAddins() ;
        
bool DynRemoveAddin(int serviceKey) ;
        
bool DynRemoveAddin(string serviceName) ;
        
void StartAllAddin() ;
        
void StopAllAddin() ;

        ArrayList AddinBoxList 
{get ;}        
        Hashtable GetAllServiceList() ; 
//key - name

        
event CallBackSimple AddinsChanged ;
    }

 

 


可以看到,IAddinManagement实现了对所有插件的全部管理,其还发布了一个事件AddinsChanged,就是当插件列表发生变化的时候用于通知外部。

 

 

关于插件的基础部分,就先介绍这么多,在后面的章节中,我们将深入到各种类型的插件的内部。

文章来源:http://tb.blog.csdn.net/TrackBack.aspx?PostId=427354

posted @ 2006-05-29 18:56 wjk.net 阅读(146) 评论(1) 编辑

2006年5月23日

 现在LBS的应用真是太多了。
间隔两天就可以看到一个新的应用出炉。
今天同事一个诺基亚N60的手机下载了一个导航软件,到路口有语音提示,还可外接GPS。真的很酷!

 

posted @ 2006-05-23 21:40 wjk.net 阅读(322) 评论(0) 编辑

2006年5月17日

今天落户了。

posted @ 2006-05-17 12:40 wjk.net 阅读(79) 评论(2) 编辑