#
Session:
当用户打开浏览器,访问某个网站时,服务器就会在服务器内存为该浏览器分配一个空间,该空间被该浏览器独占。
这个空间就是Session,Session默认保存时间为30min。
Session可以用来做什么:
1.网上商城购物车
2.用户登录信息
3.将某些数据放入Session中,供同一用户不同页面使用
4.防止用户非法登录到某个页面
……&……
可这样理解Session: 一个名字(String)对应一个值(Object),Session就是其中的一张由无数个名字和值对应的表。
Session的使用:
1.得到Session: HttpSession hs = request.getSession(true);
2.添加属性: setAttribute(java.lang.String name, java.lang.Object value)
3.………… 见API
Cookie:
存在于客户端,有相应时间限制
用途:
1.保存用户名和密码,一段时间内不用重新登录。
2.记录用户访问网站的喜好。
3.网站的个性化(如google的一些网站定制)
可这样理解Session: 一个名字(String)对应一个值(String),Session就是其中的一张由无数个名字和值对应的表。
ServletContext:
ServletContext生命周期从创建开始,到服务器关闭时结束。
用途:
1.网站计数器
2.网站在线用户的显示
3.简单的聊天系统
…… & ……
总之,涉及到不同用户共享数据,而这些数据量不大,且不希望写入到数据库中,就可以考虑使用ServletContext
理解C++中继承层次的关键在于理解如何确定函数调用。确定函数调用遵循以下四个步骤:
A.首先确定进行函数调用的对象、引用或指针的静态类型;
B.在该类中查找函数,如果找不到,就在直接基类中查找,如此循着类的继承链网上找,知道找到该函数或者查找完最后一个类。如果不能在类或其相关基类中找到该名字,则调用是错误的。
C.一旦找到了该名字,就进行常规类型检查,查看如果给定找到的定义,该函数调用是否合法。
D.假定函数调用合法,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个版本函数,否则,编译器生成代码直接调用函数。
代码:
基本:
/Files/jokes000/Builder.txt 建造者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样地构建过程可以创建不同的表示。如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。
使用:用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
建造模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
所以说,建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时使用的模式。
结构图:
代码:
基本:
/Files/jokes000/Facade.txt 外观模式(Facade):为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。(基金经理人与股民关系)
使用: 首先,在设计初期阶段,应该有意识的将不同的两个层分离,比如MVC模式,就应该考虑在M、V、C三层的层与层之间建立外观Facade。
其次,在开发阶段,子系统往往因为不断的重构烟花而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少他们之间的依赖。
第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,在新需求开发时可以为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作。
结构图:
迪米特法则(LoD):如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
前提:在类的结构设计上,每一个类都应当尽量降低成员的访问权限。
根本思想:强调了类之间的松耦合。类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。
实例:《大话设计模式》P101
代码:
实例:
/Files/jokes000/TempleteMethod.rar 基本:
/Files/jokes000/TempleteMethod.txt 模板方法模式(TempleteMethod):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定的步骤。
模板方法模式是通过把不变行为搬移到超类去除子类中的重复代码来体现它的优势。模板方法模式就是提供了一个很好的代码复用平台。当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复实现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。
既然用了继承,并且肯定这个继承有意义,就应该要成为子类的模板,所有重复的代码都应该要上升到父类去,而不是让每个子类去重复。
什么时候使用?当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。
模板方法模式(TempleteMethod)结构图:
转自:http://xujingli88.blog.163.com/blog/static/41178619200962410122172/
接口是一个没有被实现的特殊的类,它是一系列操作的集合,我们可以把它看作是与其他对象通讯的协议。C++中没有提供类似interface这样的关键 字来定义接口,但是Mircrosoft c++中提供了__declspec(novtable)来修饰一个类,来表示该类没有虚函数表,也就是虚函数都是纯虚的。所以利用它我们依然可以定义一 个接口。代码例子如下:
#include <IOSTREAM>
using namespace std;
#define interface class __declspec(novtable)
interface ICodec
{
public:
virtual bool Decode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen);
virtual bool Encode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen);
};
class CCodec : public ICodec
{
public:
virtual bool Decode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen)
{
cout << "解码..." << endl;
return true;
}
virtual bool Encode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen)
{
cout << "编码..." << endl;
return true;
}
};
int main(int argc, char* argv[])
{
ICodec * pCodec = new CCodec();
pCodec->Decode(NULL,0,NULL,NULL);
pCodec->Encode(NULL,0,NULL,NULL);
delete (CCodec*)pCodec;
return 0;
}
上面的ICodec接口等价于下面的定义:class ICodec
{
public:
virtual bool Decode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen)=0;
virtual bool Encode(char * lpDataSrc,unsigned int nSrcLen,char * lpDataDst,unsigned int *pnDstLen)=0;
};
代码:
实例:
/Files/jokes000/Prototype.rar 基本:
/Files/jokes000/Prototype.txt 原型模式(prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式其实就是
从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。 一般在初始化的信息不发生变化的情况下,克隆是最好的办法。这既隐藏了对象创建的细节,又对性能是大大的提高。等于是不用重新初始化对象,而是动态地获得对象运行时的状态。
结构图:
代码:
实例:
/Files/jokes000/Calculator.rar 工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体的产品的依赖。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断已到了客户端代码来进行。你想要加功能,本来是该工厂类的,而现在是修改客户端。
工厂方法模式结构图: