`
guafei
  • 浏览: 323229 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

亨元模式

阅读更多
翻译为亨元模式,或直译为轻量级模式。所谓亨元,就是被其它对象共享使用的
对象。通过这种方式,系统减少了内存的占用。比如一个系统有一个成百上千、
成千上万的小对象,这些小对象可能拥有着共同的信息,那么这些共同的信息就
没有必要也重复成千上万次。把这些共同信息抽取出来,形成一个对象,即是亨
元。这些成千上万的其它对象只需要引用这个亨元即可。

举个例子,在棋类程序中,有时候我们会把一个棋子当成为一个对象。这个对象
包含着位置信息、字体信息、颜色信息、样式信息等。如下所示,

class 棋子{
  public 名字(车、马、炮等)
  public 位置信息
  public 字体信息
  public 颜色信息
  public 样式信息
}

如果我们每次new一个这样的对象,它所占用的内存是这些信息所占内存的和。
new 10个这样的对象就需要10倍的内存占用。实际上,在象棋中,除了象棋棋子
的名字不同、位置不同外,其它的字体信息、样式信息一般都是一样的。比如红
方的棋子是红色、隶书、字体有阴影效果,黑方的棋子是黑色、隶书、有阴影效
果。

这些字体信息、颜色信息、样式信息都可以做成亨元。拿颜色信息来说,如果不
使用亨元,则每一个棋子都要分别创建一个颜色对象,10个棋子就创建10个颜色
对象,而这10个颜色对象很可能是一样的,比如都是红色。这样就太浪费内存了。
使用亨元,则可以避免这种重复创建相同对象的问题。

我们只需要创建一个红色信息的对象,而让所有红色棋子都引用这个红色对象。
同理,让所有黑色棋子都引用黑色对象。这样就减少了内存使用。

比如,我们在new 一个红色棋子对象时,要先去一个颜色信息池中区查找是否已
经有这么一个红色对象,有则,直接引用它,没有则先创建它再引用它。所谓颜
色信息池,一般都用Map来实现。比如

Map h = new HashMap();
if(h.get("red")!=null){
    h.pub("red",new Color对象);
}else{
    取出这个Color对象(我们叫它objectC)。
}

然后你在另一个地方把这个objectC赋给棋子对象,比如用这种方式:
棋子对象.颜色信息=objectC;

实际上,针对象棋这个例子也没有必要用一个pool来保存Color对象,也没有必要
判断这个对象是不是在pool中存在,也没必要在判断完是否存在后再进行是否生
成一个新对象的工作。因为象棋中无非两种对象,红和黑,这是确定的。所以我
们完全可以把这两个对象提前生成出来,放到一个地方保存着,别人都对它们进
行引用即可,可以这样做,

class 棋子{
    private static Color redColor = new Color("red");
    private static Color blackColor = new Color("black");
...
...     
}

这好像有点单态模式的感觉。实际上,一个class会共享很多实例而不像单态那样
只允许共享一个实例,也不像象棋这样只有红、黑两种颜色对象。假如一个应用
中,class共享的颜色对象可能除了红、黑,还有其它上百种颜色,而且颜色种类
的增减,依赖于用户的操作,那么用一个pool把它们存放起来就比较好。

一般亨元的获取都是通过一个工厂类来实现,例子如下:

class A{
    private B b;
    private C c;
    private Flyweight f;
    public A(B b,C c,Flyweight f){
        this.b = b;
        this.c = c;
        this.f = f;
    }
}

class Factory{
    private static Factory f = new Factory();
    private static Map m = new HashMap();
    private Factory(){};
    public Factory getInstance(){return f;}
    public void getFlyweight(Object key){
        Flyweight fly;
        if(m.get(key)==null){
             fly = new Flyweight(key);
             f.put(key,fly);
        }else{
             fly = (Flyweight)f.get(key);
        }
        return fly;
     }
}

class Client{
    public static void main(String args[]){
        B b = new B();
        C c = new C();
        Flyweight f = Factory.getInstance().getFlyweight(key);
        A a = new A(b,c,f);
    }
}

下面3个类的具体内容不重要,略
class B
class C
class Flyweight

当用户new一个A的实例,A中的Flyweight对象只是指向共享对象的一个引用。在
这个例子中,使用HashMap来保存共享对象,随着程序的运行,HashMap存的对象
会越来越多,HashMap自己会变的越来越大。有的时候,因为用户的操作也可能会
使对象被杀掉(比如棋子被吃掉),以至于有的亨元没有被任何对象引用,这个
时候,如果本身已经有点臃肿的HashMap能瘦身,自动释放亨元,对系统性能的提
升也非常有好处。比较简单的一个办法就是用WeakHashMap代替HashMap.

Flyweight模式是一种Cache技术,站在更高的层面看,它是一种资源使用技术。
这种技术更多的见于对性能要求比较高的底层开发领域。Java语言中的某县内置
对象可能就是用Flyweight模式实现的。比如最常用的String对象就可能是如此,
可以做一个简单测试,如下,

public class Test {
public static void main(String[] args) {
    String a1 = "aaa"
    String b1 = "bbb";
    String a2 = "aaa";
    String b2 = "bbb";
    System.out.println(a1 == a1);
    System.out.println(b1 == b2);                                    
    String c = a + b;
    System.out.println(c == "aaabbb");
    String flyweight = (a + b).intern();//这里用到了亨元模式. 返回"aaabbb"的一个引用。
    System.out.println(flyweight == "aaabbb");
  }
}
程序分别返回 true,true,false,true.  (==用来测试两者是不是引用同一个实例).

String在java中的应用甚为频繁,所以使用Flyweight模式以提高性能理所当然,
但事实上String很多地方并未使用该模式,比如

String a =new String("aaa");
String b = new String("bbb");
System.out.println(a == b);

程序打印出false.

或许这是Java为开发者故意提供的一个让同一个字符串有多个实例的选择。

最后要注意的一点是,这些共享的对象有可能在途中被改变。你要根据不同的应
用来决定是不是允许共享对象改变,如果不允许就把它们设计成不可变对象
(immutable)。如果允许变,则要考虑是不是创建个新的亨元同时保留老亨元,或
者通知那些使用亨元的对象亨元已经改变了。根据你的具体情况具体分析具体设





版本二:

1、亨元模式的用意
亨元模式是对象的结构模式。亨元模式以共享的方式高效地支持大量的细粒度对象。
亨元模式能做到共享的关键是区分内蕴状态和外蕴状态

一个内蕴状态是存储在亨元对象内部的,并且是不会随环境改变而有所不同的。因此,一个亨元可以具有内蕴状态并可以共享。

一个外蕴状态是随环境改变而改变的、不可以共享的状态。亨元对象的外蕴状态必须由客户端保存,并在亨元对象被创建之后,
在需要使用的时候再传入到亨元对象内部。

外蕴状态不可以影响亨元对象的内蕴状态的,它们是相互独立的。

2、亨元模式的种类
根据所涉及的亨元对象的北部表象,亨元模式可以分为单纯亨元模式和复合亨元模式两种形式。

3、亨元模式的实现:
1)单纯亨元模式涉及的角色
1-抽象亨元角色:此角色是所有的具体亨元类的超类,为这些规定出需要实现的公共接口,那些需要外蕴状态的操作
   可以通过方法的参数传入。抽象亨元的接口使得亨元变得可能,但是并不强制子类实行共享,因此并非所有的亨元
   对象都是可以共享的
2-具体亨元角色:实现抽象亨元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。
   亨元对象的内蕴状态必须与对象所处的周围环境无关,从而使得亨元对象可以在系统内共享。有时候具体亨元角色
   又叫做单纯具体亨元角色,因为复合亨元角色是由单纯具体亨元角色通过复合而成的
3-复合亨元角色:复合亨元角色所代表的对象是不可以共享的,但是一个复合亨元对象可以分解成为多个本身是单纯亨元
   对象的组合。复合亨元角色又称做不可共享的亨元对象。
4-亨元工厂角色:本角色负责创建和管理亨元角色。本角色必须保证亨元对象可以被系统适当地共享。
   当一个客户端对象请求一个亨元对象的时候,亨元工厂角色需要检查系统中是否已经有一个符合要求的亨元对象,
   如果已经有了,亨元工厂角色就应当提供这个已有的亨元对象;如果系统中没有一个适当的亨元对象的话,
   亨元工厂角色就应当创建一个新的合适的亨元对象。
5-客户端角色:本角色还需要自行存储所有亨元对象的外蕴状态。

//抽象亨元角色
public abstract class Flyweight{
public abstract void operation(String state);
}

//具体亨元角色
具体亨元角色的主要责任:
1)实现了抽象亨元角色所声明的接口,也就是operation()方法。operation()方法 接收一个外蕴状态作为参量。
2)为内蕴状态提供存储空间,在本实现中就是intrinsicState属性。亨元模式本身对内蕴状态的存储类型并无要求
   这里的内蕴状态是Character类型,是为了给符合亨元的内蕴状态选做String类型提供方便。
public class ConcreteFlyweight extends Flyweight{
private Character intrinsicState = null;

public ConcreteFlyweight(Character state){
this.intrinsicState = state;
}

//外蕴状态作为参量传入到方法中
public void operation(String state){
System.out.print("\nInternal State = " + intrinsicState + "Extrinsic State = " +
state);
}
}

//具体复合亨元角色
具体复合亨元角色的责任:
1)复合亨元对象是由单纯的亨元对象通过复合而成,因此它提供了add()这样的聚集管理方法。
   由于一个复合亨元对象具有不同的聚集元素,这些聚集元素在复合亨元对象被创建之后加入,这本身就意味着
   亨元对象的状态是会改变的,因此复合亨元对象是不能共享的。
2) 复合亨元角色实现了抽象亨元角色所规定的接口, 也就是operation()方法。这个方法有一个参量,
   代表复合亨元对象的外蕴状态,。一个复合亨元对象的所有单纯亨元对象元素的外蕴状态都是与复合亨元对象的
   外蕴状态相等的,而一个复合亨元对象所含有的单纯亨元对象的内蕴状态一般是不相等的,不然就没有使用价值了。

import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

public class ConcreteCompositeFlyweight extends Flyweight{
private HashMap flies = new HashMap(10);
private Flyweight flyweight;

public ConcreteCompositeFlyweight(){}

//增加一个新的单纯亨元对象到聚集中
public void add(Character key, Flyweight fly){
flies.put(key,fly);
}

//外蕴状态作为参量传入到方法中
public void operation(String extrinsicState){
Flyweight fly = null;
for(Iterator it = flies.entrySet().iterator()); it.hasNext();){
Map.Entry e = (Map.Entry)it.next();
fly = (Flyweight)e.getValue();
fly.operation(extrinsicState);
}

}
}

//亨元工厂角色
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

public class FlyweightFactory{
private HashMap flies = new HashMap();

public FlyweightFactory(){}

//复合亨元工厂方法,所需状态以参量形式传入,这个参量恰好可以使用String类型
public Flyweight factory(String compositeState){
ConcreteCompositeFlyweight compositeFly = new ConcreteCompositeFlyweight();
int length = compositeState.length();
Character state = null;
for(int i = 0; i < length; i ++){
state = new Character(compositeState.charAt(i));
System.out.println("factory(" + state +")");
compositeFly.add(state,this.factory(state));
}
return compositeFly;
}

//单纯亨元工厂方法
public Flyweight factory(Character state){
//检查具有此状态的亨元是否已经存在
if(flies.containsKey(state)){
//具有此状态的亨元已经存在,因此直接将它返回
retun (Flyweight)flies.get(state);
}else{
//具有此状态的亨元不存在,因此创建新实例
Flyweight fly = new ConcreteFlyweight(state);
//将实例存储到聚集中
flies.put(state,fly);
//将实例返回
return fly;
}
}

public void checkFlyweight(){
Flyweight fly;
int i = 0;
System.out.println("\n==========CheckFlyweight()==============");
for(Iterator it = flies.entrySet().iterator(); it.hasNext();){
Map.Entry e = (Map.Entry) it.next();
System.out.println("Item" + (++i) + ";" + e.getKey());
}
System.out.println("\n==========CheckFlyweight()==============");
}
}

4、模式的实现
1)使用不变模式实现亨元角色
   亨元模式里的亨元对象不一定非得是不变对象,但是很多的亨元对象确实被设计成了不变对象。
   由于不变对象的状态之后就不再变化,因此不变对象满足亨元模式对亨元对象的要求。

2)使用备忘录模式实现亨元工厂角色
   亨元工厂负责维护一个表,通过这个表把很多全同的实例与代表它们的一个对象联系起来。这就是备忘录模式的应用。

3)使用单例模式实现亨元工厂角色
   系统往往只需要一个亨元工厂的实例,所以亨元工厂可以设计成为单例模式。

在单纯的共享模式中使用单例模式实现共享工厂角色
   import java.util.Map;
   import java.util.HashMap;
   import java.util.Iterator;
   public class FlyweightFactorySingleton{
   private HashMap flies = new HashMap();
   private static FlyweightFactorySingleton myself = new FlyweightFactorySingleton();
  
   private FlyweightFactorySingleton(){}
  
   public static FlyweightFactorySingleton getInstance(){
   return myself;
   }
  
   //工厂方法,向外界提供含有指定内蕴状态的对象
   public synchronized Flyweight factory(Character state){
   //检查具有此状态的亨元是否已经存在
   if(flies.containsKey(state)){
   //具有此状态的亨元对象已经存在,因此直接返还此对象
   return (Flyweight)flies.get(state);
   }else{
   Flyweight fly = new ConcreteFlyweight(state);
   flies.put(state,fly);
   return fly
   }
   }
  
   //辅助方法,打印所有已经创建的亨元对象清单
   public void checkFlyweight(){
   Flyweight fly;
   int i = 0;
   System.out.println("\n===========checkFlyweight===============");
   for(Iterator it = flies.entrySet().iterator(); it.hasNext();){
   Map.Entry e = (Map.Entry)it.next();
   System.out.println("Item" + (++i) + ":" + e.getKey());
   }
   System.out.println("\n===========checkFlyweight===============");
   }
  
   }
  
   //客户端代码
   public class ClientSingleton{
   private static FlyweightFactorySingleton factory;
  
   public static void main(String args[]){
   factory = FlyweightFactorySingleton.getInstance();
   Flyweight fly = factory.factory(new Character('a'));
   fly.operation("First Call");
   fly = factory.factory(new Character('b'));
   fly.operation("Second call");
   Flyweight fly = factory.factory(new Character('a'));
   fly.operation("Third Call");
   factory.checkFlyweight();
  
   }
   }
  
   //将一个共享工厂角色用单例模式实现
   import java.util.Map;
   import java.util.HashMap;
   import java.util.Iterator;
  
   public class FlyweightFactorySingleton{
   private static FlyweightFactorySingleton myself = new FlyweightFactorySingleton();
   private HashMap flies = new HashMap();
   private Flyweight inkFlyweight;
  
   private FlyweightFactorySingleton(){}
  
   public static FlyweightFactorySingleton getInstance(){
   return new FlyweightFactorySingleton();
   }
  
   public Flyweight factory(String complexState){
   ConcreteCompositeFlyweight complexFly = new ConcreteCompositeFlyweight();
   int length = complexState.length();
   Character state = null;
  
   for(int i = 0; i < length; i ++){
   state = new Character(complexState.charAt(i));
   System.out.println("factory(" + state + ")");
   complexFly.add(state,this.factory(state));
   }
   return complexFly;
   }
  
   public synchronized Flyweight factory(Character state){
   //检查具有此状态的亨元是否已经存在
   if(flies.containsKey(state)){
   return (Flyweight)flies.get(state);
   }else{
   Flyweight fly = new ConcreteFlyweight(state);
  
   flies.put(state,fly);
   return fly;
   }
   }
  
   public void checkFlyweight(){
   Flyweight fly;
   int i = 0;
   System.out.println("\n===========checkFlyweight===============");
   for(Iterator it = flies.entrySet().iterator(); it.hasNext();){
   Map.Entry e = (Map.Entry)it.next();
   System.out.println("Item" + (++i) + ":" + e.getKey());
   }
   System.out.println("\n===========checkFlyweight===============");
   }
   }
  
   //一个应用亨元模式的咖啡摊例子
  
   //抽象亨元角色,serve()它没有参量是因为没有外蕴状态
   public abstract class Order{
   //将咖啡卖客人
   public abstract void serve();
   //返还咖啡的名字
   public abstract String getFlavor();
   }


//具体亨元角色
public class Flavor extends Order{
private String flavor;

public Flavor(String flavor){
this.flavor = flavor;
}

public String getFlavor(){
return this.flavor;
}

//将咖啡卖给客人
public void serve(){
System.out.println(System.out.println("Serving flavor " + flavor);
}
}

//工厂角色
public class FlavorFactory{
private Order[] flavors = new Flavor[10];
private int ordersMade = 0;
private int totalFlavors = 0;

//工厂方法,根据所需的风味提供咖啡
public Order getOrder(String flavorToGet){
if(ordersMade > 0){
for(int i  = 0 ; i < ordersMade; i ++){
if(flavorToGet.equals(flavors[i].getFlavor())){
return flavors[i];
}
}
}
flavors[ordersMade] = new Flavor(flavorToGet);
totalFlavors++;
return flavors[ordersMade++];
}

//辅助方法,返还创建过的风味对象的个数
public int getTotalFlavorsMade(){
return totalFlavors;
}
}

//客户端代码,代表咖啡摊侍者
public class ClientFlavor{
private static Order[] flavors = new Flavor[20];
private static int ordersMade = 0;
private static FlavorFactory flavorFactory;

//提供一杯咖啡
private static void takeOrders(String aFlavor){
flavors[ordersMade++] = flavorFactory.getOrder(aFlavor);
}

public static void main(String args[]){
flavorFactory = new FlavorFactory();

takeOrders("Black Coffee");
takeOrders("Capucino");
takeOrders("Espresso");
takeOrders("Espresso");
takeOrders("Capucino");
takeOrders("Capucino");
takeOrders("Black Coffee");
takeOrders("Espresso");
takeOrders("Capucino");

//将所创建的对象卖给客人
for(int i = 0; i < ordersMade; i ++){
flavors[i].serve();
}
System.out.println("\nTotal teaFlavor objects made: " +
flavorFactor.getTotalFlavorsMade() );
}
}

//如果这个例子再大点,可以增加一个外蕴状态,也就是说可以增加桌子号,建立一个桌子类,将桌子号作为
参数传给serve(Table table).


5、亨元模式的使用情况
当以下所有的条件都满足时,可以考虑使用亨元模式:
(1)一个系统有大量的对象。
(2)这些对象耗费大量的内存
(3)这些对象的状态中大部分都可以外部化
(4)这些对象可以按照内蕴状态分成很多的组,当把外蕴对象从对象中剔除时,每一个组都可以仅用一个对象代替。
(5)软件系统不依赖于这些对象的身份,换言之,这些对象可以是不可分辨的。
应当在有足够多的亨元实例可供共享时才值得使用亨元模式。

6、怎样做到共享
一个亨元对象之所以可以被很多的用户端共享,是因为它只含有可以共享的状态,而没有不可以共享的状态,
这就是使用亨元模式的前提。

要做到符合亨元模式这一点,需要分两步走:
(1)将可以共享的状态和不可以共享的状态从此常规类中区分开来,将不可共享的状态从类里剔除出去。
那些对所有客户端都去相同的值的状态是可以共享的状态;而那些对不同的客户端有不同值的状态是不可以共享的状态

(2)这个类的创建过程必须由一个工厂对象加以控制。
    这个工厂对象应当使用一个内部列表保存所有的已经创建出来的对象。当客户端请求一个新的对象时,
    工厂对象首先检查列表,看是否已经有一个对象。如果已经有了,就直接返还此对象,如果没有就创建一个新对象。
亨元模式要求将可以共享的状态设置为内蕴状态,而将不可以共享的状态设置成外蕴状态,将它们外部化。

7、亨元模式的优缺点
亨元模式的优点在于它大幅度降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的:
(1)亨元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化
(2)亨元模式将亨元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
分享到:
评论

相关推荐

    Java24种设计模式,Java24种设计模式,24种设计模式,学会了这24种设计模式,可以打遍天下无敌手,设计模式非常重要

    1、策略模式STRATEGY PATTERN 2、代理模式PROXY PATTERN 3、单例模式SINGLETON PATTERN 4、多例模式MULTITION PATTERN 5、工厂方法模式FACTORY METHOD PATTERN 6、抽象工厂模式ABSTRACT ...23、亨元模式 24、备忘录模式

    24种设计模式与6大设计原则

    策略模式[STRATEGY PATTERN] 代理模式[PROXY PATTERN] 单例模式[SINGLETON PATTERN] ...亨元模式 备忘录模式 模式大PK 六大设计原则:单一职责原则,里氏替换原则,依赖倒置原则,接口隔离原则,迪米特法则,开闭原则。

    24个设计模式与6大设计原则

    第 23 章 亨元模式【FLYWEIGHT PATTERN】 287 第 24 章 备忘录模式【MEMENTO PATTERN】 288 第 25 章 模式大PK 289 第 26 章 六大设计原则 290 26.1 单一职责原则【SINGLE RESPONSIBILITY ...

    .NET 23种常用设计模式

    23种常用设计模式,包括单例模式、工厂模式、桥接模式、适配器模式、亨元模式、抽象工厂模式等。

    java设计模式

    java设计模式 策略模式 代理模式 单例模式 多例模式 工厂方法模式 抽象工厂模式 门面模式 适配器模式 模板方法模式 亨元模式

    Java设计模式

    Java设计模式 ...第 23 章 亨元模式【FLYWEIGHT PATTERN】 ............................................................................................. 258 第 24 章 备忘录模式【MEMENTO PATTERN

    validnumberleetcode自动机-coderjia-to-architect:JiA同学的代码人生,各种优秀语言、框架、中间件、神

    valid number leetcode 自动机 前言 JiA同学的代码人生,梦想成长为一名优秀的Architect(a7t)。成长一名优秀的a7t之前,需要不断提升自己的技术广度及深度。...亨元模式 关系模式 父类与子类 策略模式 模板方式模式

    23种设计模式入门到精通详解.txt

    亨元(蝇量)模式:通过共享技术来有效的支持大量细粒度的对象。 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。 模板...

    电源技术中的沛亨推出PFM模式升压型DC/DC转换器

    沛亨半导体(AIC)推出一系列PFM模式升压型DC/DC转换器AIC1610、AIC1611及AIC1612。其中AIC1610/11限流为1A/0.65A、采用MSOP8封装的转换器,而AIC1612则可选择限流值为1A或0.65A采用MSOP10封装的转换器。 具有10个接脚...

    电源技术中的沛亨半导体的低噪声DC/DC转换器针对便携式应用

    沛亨半导体公司推出一款低噪声同步降压DC/DC转换器IC——AIC1554。该款芯片可支持700mA的输出电流,输入电压从2.5V至6.5V,输出电压为0.75V至输入电压(100%占空比)。最小尺寸为1.1×3.0×4.9mm的8引脚MSOP封装。 ...

    控制功能介绍

    屏幕监控功能有两种控制模式:监视模式和控制模式。 2.视频监控功能 远程开启摄像头功能 2. 窗口监控功能 窗口监控功能列举出被控主机当前正在运行的窗口的名称。 3. 进程监控功能 进程监控功能包括...

    绿箭远程控制软件2012

    屏幕监控功能有两种控制模式:监视模式和控制模式。 2.视频监控功能 远程开启摄像头功能 2. 窗口监控功能 窗口监控功能列举出被控主机当前正在运行的窗口的名称。 3. 进程监控功能 进程监控功能包括...

    智能行为的发展 VI:J. McV。 打猎

    亨特有感知运动问题的读者的人格模式 123 HARRIS, TL, OTTO, W., &amp; BARRETT, TC 对与 ILQ、FL 和 AMES、LB ScJIool 准备情况相关的调查的总结和审查。 纽约:Harper dc Row, 1964. KLOPFER, B., AINSWORTH, ND, ...

    henrietta_wiki

    #Henriettapedia ###A wiki 是为满足由无情的大亨亨丽埃塔本人掌舵的无名的贪婪触手的大型公司的办公室内需求而定制的。 ####1。 应用规范根目录用户会看到最近活跃文章的列表。 用户可以从文章的下拉菜单中选择一个...

    UNIX 高级教程系统技术内幕

    10.11 远程文件共亨(RFS)文件系统 10.12 RFS 结构 10.12.1 远程消息协议 10.12.2 有状态操作 10.13 RFS 实现 10.13.1 远程安装 10.13.2 RFS 客户和服务器 10.13.3 崩溃恢复 10.13.4 其他问题 10.14 客户端高速缓存 ...

    家居无忧系统设计方案.doc

    4 系统功能模块 功能模块包括:登录认证、智能家居无忧模块、家庭视频监控模块、家庭安防 系统、告警处理模块、情景模式设置模块、日志和报表管理模块、用户管理模块、设备 管理模块、权限管理模块、业务开通模块、...

    教师信息技术培训资料.doc

    臀吩旦文粟阎丁昼葫臭绵绥眷契集窥踌梆率姜童喂亩庐揍门次豫鲜房朋灿阁寐转豁屈犊 匀巩角宰省掩欲并孩岂扯臂酮扼吝檄钾的筏赚窒掖斌垄埠曝谰亨扣 教师信息技术培训资料 2013-2014学年度 城坨小学 2013年12月 教师...

    美萍足浴软件1010v2

    (注:①区:用来显示当前结账手牌的账单号、手牌编号、消费金额,②区:如果结账的宾客是本店的会员用来指定此会员的编号,可亨受相应的打折比率,打折比率可在系统设置中进行设置,③区:中分别有付款方式、信用卡...

Global site tag (gtag.js) - Google Analytics