Ice

无语呀
真是摸着石头过河
啥都不知道
网上的资料竟然这么少
搞的我一个头三个大啊
不过呢
总算有那么点眉目了
开始的时候为了运行我写的程序
我在官网上下载Ice的版本
http://www.zeroc.com/download/Ice/3.3/
下载了Ice-3.3.0.zip
冤枉啊 我竟然解压没找到lib和bin目录
我当时真是相当的无语啊
然后这怎么配环境变量啊

上谷歌 啥也没弄出来 自己太笨了
之后又重新到管网上下载
这次下的是Ice-3.3.0-bin-solaris-x86.tar.gz
嘿 这下好了 什么都全了
竟然害我绕了这么大一个圈子
还浪费了那么多时间
再然后自然就是配置环境变量了
这下可没招了
竟然还是没法儿运行命令slice2java
真是欲哭无泪啊
一转进bin目录才发现原来这个根本就不是win平台的

搞了2个多小时什么都白弄了
真叫个屈啊
看了官网上的msi文件
都是针对的VC的
这就更纳闷了
然后仔细的看了看download里面的说明
然后才知道原来VC的就是应用于win平台
同时兼容各种语言的开发
索性下了个msi的文件
安装完毕之后就直接可以用了
唉 
害我走了这么大的弯道
真不知道说自己什么好了
这下好了
一个HelloWord搞出来了
可是那些该怎么运用项目中啊
还有待研究
革命尚未成功
同志仍需努力
ICE提供的集群和容错功能是很强大的


Slice描述的是接口和类型(不是实现)
它只是一种纯粹的描述性语言
你是没办法用Slice编写可执行语句的
含有Slice定义的文件必须以.ice结尾

编译器是拒绝接受其它扩展名的

Slice定位:最多一次语义(At-Most-once Semantics)
它的意思就是尽力把请求递送到正确的目的地
无法传递的时候会给出异常通知
同时也就是在确信先前的尝试已经失败的情况下才会进行重试
这样就能保证两次的请求结果会和一次的请求结果相同
Slice为Ice实现保留了标识符Ice以及Ice(无论大小写)起头的所有标识符
Slice的基本数据类型
int bool byte short long float double string
Slice串使用的是Unicode字符集
唯一不能出现在串中的字符是零字符
Slice不允许定义空枚举
不论你是在定义结构还是词典等其它类型的时候
类型定义都是不能嵌套的
除了模块(module)它是确实可以嵌套的
Slice的操作没有缺省的返回类型
如果你的操作既有输入参数
同时又有输出参数
那么输出参数必须是放在输入参数之后的
Slice是不支持一个参数同时是输入参数
又是输出参数的
在java code中接口是可以重载的
可是在Slice接口中是不支持你任何形势的重载的
在Slice中有一个关键字:nonmutating
它好像是C++里面的关键字
这个关键字是为了说明被该关键字声明的方法在操作的时候是不能改变它对象的状态的
关键字:idempotent

这个关键字代表的是当你操作这个关键字修饰的方法的时候
这个方法经过两次连续的调用会和调用一次的效果相同
一个操作可以用nomutating修饰符
当然也可以用idempotent修饰符
但是一个方法不能同时包含这两个修饰符
因为修饰符nomutating修饰符里面已经包含的有idempotent的操作了
Slice里面你可以自己定义异常在执行某个操作的时候抛出异常
同时异常也是可以继承的
但是它只支持单继承
多继承很难映射到多种的编程语言里

现在go on

Ice大多数的异常都会在客户端被检测到
但有三种特定的异常会在服务器端被检测到
①.ObjectNotExistException这个异常说明了某个请求已经发送到服务器端
可是服务器没办法找到一个对象来把请求分派给它
如果收到这个异常的话你就得清理你分配过的与这个对象有关的所有资源
②.FaceNotExistException
③.OperationNotExistException
出现第三种异常的有两种情况:
一种就是对类型不正确的代理做了不进行检查的向下转换
第二种就是在构建客户端和服务器端的时候使用了不一致的Slice接口定义
接口的多继承
Slice定义的接口是支持多继承的
但是如果一个接口使用多重继承 它就不能从不止一个基接口中继承相同的操作名称
Object是Slice中的一个关键字 可是要注意它的大小写
Slice中所有的接口都隐式的继承自Object接口
所以在定义接口的时候你不能再显式的定义一次继承的Object
Slice除了可以定义接口之外 还可以定义类
出于性能上的考虑
如果结构已经够用的话就不要再使用类
而且Slice是不能有空结构的
可是Slice却可以有空类
同时与结构不同类支持继承 可是类也只支持单继承(这点和java相同)
派生类也不能定义基类中的数据成员
Slice中定义的结构完全可以代替类来使用
可是为什么在Slice中即定义了类还有结构呢
因为类的特性 结构并不具备
通常情况下我们并不需要使用到类
运用结构就足够了
而且结构占用内存小 比类更高效
但是当你需要类的强大特性的时候
用结构就不够用了
这时就你才应该使用类

当使用的是有操作的类的时候
如果你的服务器端和客户端使用的是不用的语言和不同的操作系统
这时就会出现问题了
当然Slice替我们解决了这个问题
当遇到这种情况的时候
类的接收者会提供一个类工厂
在接收者的的地址空间里实例化这个类
同时接收者还得负责提供类的操作的实现
在线路上发送代码是不现实的
所以提供了这样一种方法
在定义的时候最好不要用到有操作的类

Slice里面的接口和类都可以提前声明
提前声明的好处就是能创建相互依赖的对象
在Slice中应用了module
在java中它会被映射成为java package
我们在做的时候可以把相关的定义放入同一个module中
这样做就会使映射出来的代码更清晰
每种Slice类型都有一个内部的类型标识符 称为类型ID
类型ID的定义:(::)开头+该类型对应的module名称+::+该类型的自身名称
Ice run time把这个类型ID都当作类型的唯一标识符
当引发某个异常时,在线路上回馈给用户的异常信息就是以类型ID开头
Object接口里面的一些实现
ice_ping()主要用于调试 测试某个对象是否能到达
ice_isA()它操作的参数是一个类型标识符,它会测试目标对象是否支持指定的这个类型 返回bool
ice_id()返回某个接口派生层次最深的类型ID
ice_ids()返回一个类型ID序列,其中也包括某个接口所支持的所有类型ID

接下来就是local关键字 它只是声明了本地的对象
而声明这样的对象是完全没有多大的必要
所以很少使用它
可是有一个地方就必须用到
servant定位器必须作为本地对象实现
如果两个标识符只有大小写不同 那么会被认为是相同的
Slice编译器还要求你在使用标识符时,始终用相同的大小写
在外层module中定义的名字可以在内层module中再重新定义
例子:
sequence<double> Seq;

module M1
{
sequence<string> Seq;  //hide ::Seq;
interface Base
{
  Seq op1;           //returns sequence of string
};
};
module M2
{
interface Derived extends ::M1::Base
{
  Seq op2;           //returns sequence of double
};
sequence<bool> Seq;    //hide ::Seq
interface I
{
  Seq op3;           //returns sequence of bool
};
};
interface I
{
Seq op4;               //returns sequence of double
};
从上面的例子就可以明显的看出来
在确定派生接口中某个类型的含义时
编译器只会在当前作用域或者是外围作用域中搜索定义
绝不会在基类或者是基接口中取得某个名字的定义

Slice具有元数据的概念
全局的元数据指令包含在两对方括号中
例如:在定义全局的包的时候(java)[["java:package:com.test(包名)"]]
而局部的元数据指令(与特定定义系在一起的元数据指令)包含在一对方括号中
例如:["java:type:java.util.LinkedList"] sequence<int> seq;
元数据指令["java:type:java.util.LinkedList"]指示把序列映射到链表中 而不是数组(缺省定义)
slice2java映射
把Slice内建类型映射到Java
Slice    to     Java
bool              boolean
byte              byte
short             short
int                  int
long               long
float               float
double          double
string            String
Slice支持用户定义的类型:枚举、结构、序列以及词典
结构在Java中映射成了一个final类 而且该类还实现了Cloneable类
也生成了惯用的hashCode()和clone()方法
序列在映射的时候如果缺省了元数据指令就会被映射成数组的形式
看下面的例子:
enum Fruit
{
Apple,Pear,orange
};
sequence<Fruit> BreakFast;                   //缺省方式
["java:type:java.util.LinkedList"] sequence<Fruit> Dessert;     //把序列转映射到LinkedList中

struct Meal1
{
BreakFast b;   //把序列映射到数组中
Dessert d;     //把序列映射到LinkedList中
};
struct Meal2
{
["java:type:java.util.LinkedList"] BreakFast b; //把序列映射到链表中
["java:type:java.util.Vector"] Dessert d;       //把序列映射到Vector中
};
从上面可以看出在结构Meal1中的结果
然后在结构Meal2中把映射之后的类型又做了更改
有一点需要注意的:只能用这种方式改换结构、类或异常成员的序列映射
(不能更改序列元素、词典值、参数或返回值的映射)
词典的映射:
所有的词典都是java.util.Map接口实现了java.util.HashMap类来映射
最关键的当然还是接口的映射喽
对于接口(<interface-name>)编译器会创建以下源文件(客户端):
①.<interface-name>.java(这个源文件声明<interface-name>java接口)
②.<interface-name>Holder.java(这个源文件为接口定义holder类型)
③.<interface-name>Prx.java(这个源文件定义<interface-name>Pr接口)
④.<interface-name>PrxHelper.java(这个源文件是为接口的代理定义助手类型)
⑤.<interface-name>PrxHolder.java(这个源文件为接口的代理定义holder类型)
⑥.<interface-name>Operations.java(这个源文件定义一个接口,其操作与Slice接口的操作相对应)
一个服务器端专用文件
①._<interface-name>Disp.java
这个文件包含的是服务器端的骨架类的定义
还有三个编译出来的文件
_<interface-name>Del.java、_<interface-name>DelD.java、_<interface-name>DelM.java
这三个文件是供java映射内部使用的代码 它们包含的功能与应用程序无关

Ice配置属性保留的前缀
Ice、IceBox、IcePack、IcePatch、IceSSL、IceStorm、Freeze、Glacier
不能使用以这些前缀开头的属性来配置应用
在没有明确设置属性值的情况下编译器默认为1
如果某个属性做了重复的设置会以最后的设置为准
默认为1是在设置属性时加=号
如果不加=号的话一样表示清空当前属性值

Ice没有为java提供等价的线程API
而是使用了java内建的线程和同步设施

记录下儿 只是为了在项目里面的运用
加了个Ice的群 可是根本没人鸟我
初次运用 太多东西不懂
甚至说不知从何下手

你可能感兴趣的:(java,多线程,数据结构,应用服务器,vc++)