导航:首页 > 编程语言 > visitorjava

visitorjava

发布时间:2023-05-29 11:04:08

java常用的的设计模式和开发模式都有哪些

设计模式主要分三个类型、创建型、结构型和行为型。设计模式分:3种类型及23种模式。

JAVA中的开发模式:MVC是一个很常用的程序开发设计模式,M-Model(模型):封装应用程序的状态;V-View(视图):表示用户界面;C-Controller(控制器):对用户的输入作出反应,创建并设置模型。

(1)visitorjava扩展阅读

创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。

结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。

Ⅱ 在组合模式中实现访问者(Visitor)模式

本文从一个给定的实现了组合(Composite)模式的例子开始 说明怎么在这个数据结构上实现业务逻辑代码 依次介绍了非面向对象的方式 在组合结构中加入方法 使用访问者(Visitor)模式以及用改进后的访问者(Visitor)模式来实现相同的业务逻辑代码 并且对于每种实现分别给出了优缺点

读者定位于具有Java程序开发和设计模式经验的开发人员

读者通过本文可以学到如何在组合(Composite)模式中实现各种不同的业务方法及其优缺点

组合(Composite)模式

组合模式是结构型模式中的一种 GOF的《设计模式》一书中对使用组合模式的意图描述如下 将对象组合成树形结构以表示 部分 整体 的层次结构 Composite使得用户对单个对象和组合对象的使用具有一致性

组合模式应用广泛 根据GOF中对组合模式的定义 Composite模式一般由Component接口 Leaf类和Composite类组成 现在需要对一个软件产品管理系统的实体建模 某公司开发了一系列软件集(SofareSet) 包含了多橘正种品牌(Brand)的软件产品 就象IBM提供了Lotus WebsPhere等品牌 每个品牌下面又有各种产品(Proct) 如IBM的Lotus下面有Domino Server/Client产品等 建模后的类图如下(代码可以参见随本文带的附件中 包 test entity下所有的源文件)

如图所示

( )接口SofareComponent就是对应于组合模式中的Component接口 它定义了所有类共有接口的缺省行为

( )AbsSofareComposite类对应于Composite类 并且是抽象类 所有可以包含子节点的类都扩展这个类 这个类的主要功能是用来存储子部件 实现了接口中的方法 部分可以重用的代码写在此类中

( )SofareSet类继承于AbsSofareComposite类 对应于软件集 软件集下直接可以包含品牌(Brand) 也可以直接包含不属于任何品牌的产品(Proct)

( )Brand类继承于AbsSofareComposite类 对应于品牌 包含了品牌名属性 并且用来存储Proct类的实例

( )Proct类就是对应的Leaf类 表示叶子节点 叶子节点没有子节点

用不同的方法实现业务逻辑

数据结构建立好之后 需要在这个数据结构上添加方法实现圆氏悔业务逻辑 比如现在的这个例子中 有这样的需求 给定一些用户选择好的产品 需要计算出这些选中后软件的总价格 下面开始介绍如何使用各种不同的方法来实现这个业务逻辑

非面向对象的编程方式

这种方式下 编程思路最简单 遍历SofareSet实例中的所有节点 如果遍历到的当前对象是Proct的话就累加 否则继续遍历下一层直到全部遍历完毕 代码片断如下

    /** *取得某个SofareComponent对象下面所有Proct的价格 *@parambrand *@return */ public double getTotalPrice(){ SofareComponenttemp=sofareComponent; double totalPrice= ; //如果传入的实例是SofareSet的类型 if (temp instanceof SofareSet){ Iteratorit=((SofareSet)sofareComponent) getChilds() &erator(); while (it hasNext())核山{ //遍历 temp=(SofareComponent)it next(); //如果子对象是Proct类型的 直接累加 if (temp instanceof Proct){ Proctproct=(Proct)temp; totalPrice+=proct getPrice(); } else if (temp instanceof Brand){ //如果子对象是Brand类型的 则遍历Brand下面所有的产品并累加 Brandbrand=(Brand)temp; totalPrice+=getBrandPrice(brand); } } } else if (temp instanceof Brand){ //如果传入的实例是SofareSet的类型 则遍历Brand下面所有的产品并累加 totalPrice+=getBrandPrice((Brand)temp); } else if (temp instanceof Proct){ //如果子对象是Proct类型的 直接返回价格 return ((Proct)temp) getPrice(); } return totalPrice; } /** *取得某个Brand对象下面所有Proct的价格 *@parambrand *@return */ private double getBrandPrice(Brandbrand){ IteratorbrandIt=brand getChilds(erator(); double totalPrice= ; while (brandIt hasNext()){ Proctproct=(Proct)brandIt next(); totalPrice+=proct getPrice(); } return totalPrice; }

这段代码的好处是实现业务逻辑的时候无需对前面已经定好的数据结构做改动 并且效率比较高 缺点是代码凌乱而且频繁使用了instanceof判断类型和强制类型转换 代码的可读性不强 如果层次多了代码就更加混乱

面向对象的编程方式(将计算价格的方法加入数据结构中)

下面我们采用面向对象的方式 可以这么做 在接口SoftWareComponent中加入一个方法 名叫getTotalPrice 方法的声明如下

    /** *返回该节点中所有子节点对象的价格之和 *@return */ public double getTotalPrice();
由于类Brand和SofareSet都继承了AbsSofareComposite 我们只需在类AbsSofareComposite中实现该方法getTotalPrice方法即可 如下
    public double getTotalPrice(){ Iteratorit=erator(); double price= ; while (it hasNext()){ =(SofareComponent)it next(); //自动递归调用各个对象的getTotalPrice方法并累加 price+=sofareComponent getTotalPrice(); } return price; }
在Proct类中实现如下
    public double getTotalPrice(){ return price; }
在外面需要取得某个对象的总价格的时候只需这样写(在本文的例子 test business SofareManager中可以找到这段代码)
    //getMockData()方法返回数据 SofareComponentdata=getMockData(); //只需直接调用data对象的getTotalPrice方法就可以返回该对象下所有proct对象的价格 double price=data getTotalPrice(); //找到某个对象后直接调用其getTotalPrice方法也可以返回总价格 price=data findSofareComponentByID( id ) getTotalPrice();

现在把业务逻辑的实现都放在了数据结构中(组合模式的结构中) 好处很明显 每个类只管理自己相关的业务代码的实现 跟前面举的面向过程方式的实现方式相比 没有了instanceof和强制类型转换 但是不好的地方是如果需要增加新的业务方法的话就很麻烦 必须在接口SoftWareComponent中首先声明该方法 然后在各个子类中实现并且重新编译

使用访问者模式

使用访问者模式就能解决上面提到的问题 如果要经常增加或者删除业务功能方法的话 需要频繁地对程序进行重新实现和编译 根据面向对象设计原则之一的SRP(单一职责原则)原则 如果一个类承担了多于一个的职责 那么引起该类变化的原因就会有多个 就会导致脆弱的设计 在发生变化时 原有的设计可能会遭到意想不到的破坏 下面我们引入了一个叫做Visitor的接口 该接口中定义了针对各个子类的访问方法 如下所示

    public interface Visitor{ public void visitBrand(Brandbrand); public void visitSofareSet(SofareSetsofareSet); public void visitProct(Proctproct); }
visitBrand方法是访问Brand对象节点的时候用的 剩下的方法依次类推 并在接口SofareComponent中增加一个方法
    public void accept(Visitorvisitor);
在SofareSet中实现接口中的accept方法 首先直接调用Visitor接口中的visitSofareSet方法 传入的参数是本身对象 然后递归调用子对象的accept方法
    public void accept(Visitorvisitor){ visitor visitSofareSet( this ); Iteratorit=erator(); while (it hasNext()){ SofareComponentponent=(SofareComponent)it next(); ponent accept(visitor); } }
在Brand中实现接口中的accept方法 首先直接调用Visitor接口中的visitBrand方法 传入的参数是本身对象 然后递归调用子对象的accept方法
    public void accept(Visitorvisitor){ visitor visitBrand( this ); Iteratorit=erator(); while (it hasNext()){ SofareComponentponent=(SofareComponent)it next(); ponent accept(visitor); } }
其实在上面的两个类的实现中可以将遍历子节点并调用其accept方法的代码写到父类AbsSofareComposite中的某个方法中 然后直接调用父类中的这个方法即可 这里为了解释方便分别写在了两个子类中 在Proct中实现接口中的accept方法 直接调用Visitor接口的visitProct方法即可
    public void accept(Visitorvisitor){ visitor visitProct( this ); }
下面需要实现Visitor接口 类名是CaculateTotalPriceVisitor 实现了计算总价格的业务逻辑 实现代码如下所示
    public class CaculateTotalPriceVisitor implements Visitor{ private double totalPrice; public void visitBrand(Brandbrand){ } public void visitSofareSet(SofareSetsofareSet){ } public void visitProct(Proctproct){ //每次在组合的结构中碰到Proct对象节点的时候 就会调用此方法 totalPrice+=proct getPrice(); } public double getTotalPrice(){ return totalPrice; } }
上面那段代码中 首先在类内定义一个总价格的属性 由于Brand和SofareSet都没有价格 因此在实现中 只需在visitProct方法中累加totalPrice即可 在外面如果需要计算总价格的话这样写(在本文的例子 test business SofareManager中可以找到这段代码)
    //建立一个新的Visitor对象 = new CaculateTotalPriceVisitor(); //将该visitor对象传到结构中 data accept(visitor); //调用visitor对象的getTotalPrice()方法就返回了总价格 double price=visitor getTotalPrice();

下面是它的时序图 在类SofareManager中的main方法中 调用软件集对象(data)的accept方法 并将生成的visitor对象传给它 accept方法开始递归调用各个子对象的accept方法 如果当前的对象是SofareSet的实例 则调用visitor对象visitSofareSet方法 在visitor对象中对该节点的数据进行一些处理 然后返回 依次类推 遍历到Brand对象和Proct对象也与此类似 当前的逻辑是计算软件产品的总价格 因此当遍历到Proct对象的时候 取出产品的价格并且累加 最后当结构遍历完毕后 调用visitor对象的getTotalPrice方法返回给定软件集对象的(data)的总的价格 如果需要加入一个新的计算逻辑 只实现Visitor接口 并且将该类的实例传给data对象的accept方法就可以实现不同的逻辑方法了

点击小图看大图

我们可以看到通过访问者模式很好地解决了如何加入新的业务代码而无需重新改动 编译既有代码 但是该模式也不是没有缺点 如果在组合模式中结构加入新的子类的话会导致接口Visitor也跟着改动 导致所有Visitor的子类都需要实现新增的方法 因此这种访问者模式适合于结构不经常变动的情况

改进访问者模式

前面我们说到了如何使用Visitor模式及使用该模式后的优缺点 下面举具体的例子说明 假设现在客户提出了一个产品集(ProctSet)的概念 随着公司软件版本的增多 需要将同一个版本的产品(Proct)都放到产品集(ProctSet)中 而一个品牌包含有多个产品集 因为现在组合结构中增加了一个节点 所以在Visitor接口中也必须随之增加一个叫做visitProctSet的方法 并且会导致原有系统中所有已经实现了Visitor接口的类都需要重新实现并编译 用Java的反射机制可以解决这个问题

使用Java的Method Reflection机制实现访问者模式

首先我们需要改变一下Visitor接口 接口名叫做ReflectionVisitor 如下所示

    public interface ReflectionVisitor{ /** *定义了一个访问节点的方法 *@paramsofareComposite */ public void visitSofareComposite( Object sofareComposite); }

在现在的接口的方法里 能接受任意的对象(参数是Object)

下面实现接口ReflectionVisitor 名叫ReflectionVisitorImpl 代码如下所示

    public class ReflectionVisitorImpl implements ReflectionVisitor{ public void visitSofareComposite( Object sofareComposite){ //判断是否是null if (sofareComposite== null ){ throw new NullPointerException ( Thevisitnodeshouldnotbenull! ); } //组装class数组 即调用动态方法的时候参数的类型 Class []classes= new Class []{sofareComposite getClass()}; //组装与class数组相对应的值 Object []objects= new Object []{sofareComposite}; try { //查找visit方法 Methodm=getClass() getMethod( visit classes); //调用该方法 m invoke( this objects); } catch ( NoSuchMethodException e){ //没有找到相应的方法 System out println( : +sofareComposite getClass()); } catch ( Exception e){ //发生了别的异常 System out println( ); e printStackTrace(); } } }

这段代码首先判断传入的对象是否是空指针 然后创建class数组和object数组 然后用getMethod方法取得方法名是 visit 方法的参数是 对象sofareComposite对应的类 的方法 最后调用该方法 调用该方法的时候可能会发生NoSuchMethodException异常 发生这个异常就表明它的子类或者当前类中没有与参数中传入相对应的visit方法

下面再来写新版本Visitor类 扩展刚写好的那个ReflectionVisitorImpl类 名叫 如下所示

    public class extends ReflectionVisitorImpl{ private double totalPrice; public void visit(Proctproct){ totalPrice+=proct getPrice(); } public void visit(SofareSetsofareSet){ System out println( Nopriceforsofareset ); } public double getTotalPrice(){ return totalPrice; } }
代码中声明了两个visit方法(因为在类ReflectionVisitorImpl中 查找名为visit 参数与传进去的对象匹配的的方法) 一个是给Proct的 另外一个是给SofareSet的 在这里SofareSet中并没有价格 只需当前的对象是类Proct的实例的时候将价格累加即可 如果在组合模式的结构中增加了新的类 只需要在ReflectionVisitorImpl的扩展类中声明一个visit方法 该方法的参数是新增加的类 对于文中的例子 只需增加下面的一个方法
    public void visit(ProctSetproctSet){ //实现的代码 }

在组合结构的接口SofareComponent中改一下accept方法 参数是修改后的Visitor接口 如下所示

public void accept(ReflectionVisitor visitor);

由于在类SofareSet Brand和ProctSet中实现上面accept方法的代码都一样 因此把代码抽象到上层共有的抽象类AbsSofareComposite中 如下所示

    public void accept(ReflectionVisitorvisitor){ visitor visitSofareComposite( this ); Iteratorit=erator(); while (it hasNext()){ SofareComponentponent=(SofareComponent)it next(); //递归调用子对象的accept方法 ponent accept(visitor); } }
现在如果想在外面要调用的话 代码如下所示(在本文的例子 test business SofareManager中可以找到这段代码)
    //建立一个新的Visitor对象 reflectionVisitor = new (); //将该visitor对象传到结构中 data accept(reflectionVisitor); //调用visitor对象的getTotalPrice()方法就返回了总价格 double price=reflectionVisitor getTotalPrice();

另外由于没有实现Brand类的visit方法 在组合结构遍历到Brand的节点的时候会抛出NoSuchMethodException异常 就是没有关于该节点方法的实现 在当前的程序中会打印出一句话

You did not implement the visit method for class:class test entity Brand

如果运行程序时发生了别的异常 请参见相应的Java API文档

在现在的改进后的访问者模式中 如果在组合的结构中新增或删除节点并不会对已经实现了的Visitor产生任何影响 如果新增了业务方法 只需扩展类ReflectionVisitorImpl就可以了 因此很好地解决了访问者模式的问题

改进访问者模式实现与既有代码对接

到现在为止 改进后的访问者模式好像已经很好地解决了所有出现的问题 但是考虑到有下面的这种情况 现在需要写一个JSP的标签库(TagLib) 这个标签库还必须具有Visitor的功能(就是需要有遍历节点的功能) 可以将节点的内容根据需要打印到HTML页面中 由于标签本身需要继承相应的类(如TagSupport) 如果继续使用上面提供的方法将无法实现 因为Java不允许多重继承 不过我们可以将原有ReflectionVisitorImpl的代码再改进一下以解决这种情况 新的Visitor的实现类叫NewReflectionVisitorImpl 代码如下所示

    public class NewReflectionVisitorImpl implements ReflectionVisitor{ //实现visit方法的类 private Object targetObject; //构造方法 传入实现了visit方法的类 public NewReflectionVisitorImpl( Object targetObject){ if (targetObject== null ) throw new NullPointerException ( ! ); this targetObject=targetObject; } public void visitSofareComposite( Object sofareComposite){ //……与上个例子相同 try { //从目标的对象中查找visit方法 Methodm=targetObject getClass() getMethod( visit classes); //调用该方法 m invoke(targetObject objects); } catch ( NoSuchMethodException e){ //……与上个例子相同 } catch ( Exception e){ //……与上个例子相同 } } }
该类的实现与上面的实现差不多 多了一个构造函数 在该构造函数的参数中传入实现了visit方法的类 并且维护了指向该类的一个引用 另外最重要的地方是下面的两行代码
    //从目标的对象中查找visit方法 Methodm=targetObject getClass() getMethod( visit classes); //调用该方法 m invoke(targetObject objects);

本来的代码中从本身的类及其子类中查找visit方法 而现在是从维护的目标类中查找visit方法

现在需要写Tag类 这个类扩展了TagSupport类 如下所示(为说明的方便 随本文的例子提供了一个模拟的TagSupport类)

    public class MyTag extends TagSupport{ = null ; private double totalPrice= ; public int doEngTag(){ //创建一个visitor对象 并且将本身传入visitor对象中 ReflectionVisitorvisitor= new NewReflectionVisitorImpl( this ); //遍历结构 sofareComponent accept(visitor); //打印出价格 out println(totalPrice); return ; } //实现了针对Proct的visit方法 public void visit(Proctproct){ totalPrice+=proct getPrice(); } public void visit(Brandbrand){ out println(brand getId()+brand getDescription()); } //别的代码请参见随本文带的源程序 …… }
如果想测试上面写的那段代码 (在本文的例子 test business SofareManager中可以找到这段代码))如下所示
    //getMockData()方法返回数据 SofareComponentdata=getMockData(); MyTagmyTag= new MyTag(); myTag setSofareComponent(data); //计算总价格 并打印出来 myTag doEngTag();

可以看到通过Java的反射机制很好地解决了多重继承的问题 使该访问者模式能够更好地应用于你的应用中 另外可以看到 那些visit方法所在的类已经不是实现了接口ReflectionVisitor 可以说是访问者模式在Java语言的支持下的一种特殊实现

如果担心引入类反射机制后带来的效率问题 你可以将Method对象通过某种方式缓冲起来 这样不会每次从传入的对象中找visit方法 可以部分地提高效率

结论

lishixin/Article/program/Java/gj/201311/11152

Ⅲ java 返回用户在指定文件夹中的指定后缀的所有文件

Java实现获取指定路径下的指定格式的文件代码如下:

packagefilenameFilter;

importjava.io.File;

/*
*实现功能:
*获取指定路径下的指定格式的文件;
**/

publicclassTest{

publicstaticvoidlistPath(Filefile){
//接收筛选过后的文件对象数组
//用文件对象调用listFiles(FilenameFilterfilter);方法,
//返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录
Filefiles[]=file.listFiles(newMyFilenameFilter());

/*//遍历出指定文件路径下符合条件的文件
for(Filef:files){
System.out.println(f);
}*/

//遍历出指定文件路径下的所有符合筛选条件的文件
for(Filef:files){
if(f.isDirectory()){
listPath(f);
}else{
System.out.println(f);
}
}}

publicstaticvoidmain(String[]args){
//创建指定目录的文件对象
Filefile=newFile("F:\test");
//调用文件晒筛选的方法,并将文件对象出入,
listPath(file);
}
}

packagefilenameFilter;

importjava.io.File;

importjava.io.FilenameFilter;


//实现FilenameFilter接口,可用于过滤器文件名
//本方法实现的是筛选指定格式结尾的文件
{

/**
*@paramargs
*
*实现功能;实现FilenameFilter接口,定义出指定的文件筛选器
*
*/


@Override
//重写accept方法,测试指定文件是否应该包含在某一文件列表中
publicbooleanaccept(Filedir,Stringname){
//TODOAuto-generatedmethodstub
//创建返回值
booleanflag=true;
//定义筛选条件
//endWith(Stringstr);判断是否是以指定格式结尾的
if(name.toLowerCase().endsWith(".jpg")){

}elseif(name.toLowerCase().endsWith(".txt")){

}elseif(name.toLowerCase().endsWith(".gif")){

}else{
flag=false;
}
//返回定义的返回值

//当返回true时,表示传入的文件满足条件
returnflag;
}

}

Ⅳ 软件设计模式主要有哪几种

软件设计模式主要有以下三大类共23种:

一、创建型模式:

1、工厂方法模式工厂方法模式的创建是因为简单工厂模式有一个问题,在简单工厂模式中类的创建依赖工厂类,如果想要拓展程序,必须对工厂类进行修改,这违背了开闭原则,所以就出现了工厂方法模式,只需要创建一个工厂接口和多个工厂实现类。

2、抽象工厂模式抽象工厂模式是提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。区别于工厂方法模式的地方,工厂方法模式是创建一个工厂,可以实现多种对象;而抽象工厂模式是提供一个抽象工厂接口,里面定义多种工厂,每个工厂可以生产多种对象。

3、单例模式单例模式能保证一个类仅有一个实例,并提供一个访问它的全局访问点,同时在类内部创造单一对象,通过设置权限,使类外部无法再创造对象。单例对象能保证在一个JVM中,该对象只有一个实例存在。

4、建造者模式建造者模式是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。在程序当中就是将一些不会变的基本组件,通过builder来进行组合,构建复杂对象,实现分离。

5、原型模式:原型模式是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。其实就是将对象复制了一份并返还给调用者,对象需继承Cloneable并重写clone方法。原型模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。

二、结构型模式:

1、适配器模式适配器模式是使得原本由于接口不兼容而不能一起工作的那些类可以一起工作,衔接两个不兼容、独立的接口的功能,使得它们能够一起工作,适配器起到中介的作用。

2、装饰模式:装饰器模式是动态地给一个对象添加一些额外的职责,给一个对象增加一些新的功能,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。除了动态的增加,也可以动态的撤销,要做到动态的形式,不可以用继承实现,因为继承是静态的。

3、代理模式代理模式是为其他对象提供一种代理以控制对这个对象的访问,也就是创建类的代理类,间接访问被代理类的过程中,对其功能加以控制。

4、外观模式外观模式是为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

5、桥接模式桥接模式是将抽象部分与实现部分分离,使它们都可以独立的变化。桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化(突然联想到了mvc模式)。

6、组合模式:组合模式是将对象组合成树形结构以表示"部分-整体"的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。

7、享元模式:享元模式是运用共享技术有效地支持大量细粒度的对象。享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,重用现有的同类对象,若未找到匹配的对象,则创建新对象,这样可以减少对象的创建,降低系统内存,提高效率。

三、行为型模式:

1、策略模式:

策略模式是定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换,且算法的变化不会影响到使用算法的客户。

2、模版方法模式:

模板方法模式是定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。该模式就是在一个抽象类中,有一个主方法,再定义1...n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用。

模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,将一些固定步骤、固定逻辑的方法封装成模板方法。调用模板方法即可完成那些特定的步骤。

3、观察者模式:

观察者模式是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

也就是当被观察者状态变化时,通知所有观察者,这种依赖方式具有双向性,在QQ邮箱中的邮件订阅和RSS订阅,当用户浏览一些博客时,经常会看到RSS图标,简单来说就是当订阅了该文章,如果后续有更新,会及时通知用户。这种现象即是典型的观察者模式。

4、迭代器模式:

迭代器模式是提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

在Java当中,将聚合类中遍历各个元素的行为分离出来,封装成迭代器,让迭代器来处理遍历的任务;使简化聚合类,同时又不暴露聚合类的内部,在我们经常使用的JDK中各个类也都是这些基本的东西。

5、责任链模式:

责任链模式是避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。

6、命令模式:

命令模式是将一个请求封装成一个对象,从而使发出者可以用不同的请求对客户进行参数化。模式当中存在调用者、接收者、命令三个对象,实现请求和执行分开;调用者选择命令发布,命令指定接收者。

7、备忘录模式:

备忘录模式是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。创建一个备忘录类,用来存储原始类的信息;同时创建备忘录仓库类,用来存储备忘录类,主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,也就是做个备份。

8、状态模式:

状态模式是允许对象在内部状态发生改变时改变它的行为。对象具有多种状态,且每种状态具有特定的行为。

9、访问者模式:

访问者模式主要是将数据结构与数据操作分离。在被访问的类里面加一个对外提供接待访问者的接口,访问者封装了对被访问者结构的一些杂乱操作,解耦结构与算法,同时具有优秀的扩展性。通俗来讲就是一种分离对象数据结构与行为的方法。

10、中介者模式:

中介者模式是用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

11、解释器模式:

解释器模式是给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子,基本也就用在这个范围内,适用面较窄,例如:正则表达式的解释等。


(4)visitorjava扩展阅读:

软件设计的概念以及意义:

软件设计模式是对软件设计经验的总结,是对软件设计中反复出现的设计问题的成功解决方案的描述。为了记录这些成功的设计经验并方便以后使用,软件设计模式通常包含 4 个基本要素:模式名称、问题、解决方案以及效果。

模式名称实际上就是一个帮助记忆的名称,是用于软件设计的技术术语,有助于设计者之间的交流。

问题描述了设计者所面临的设计场景,用于告诉设计者在什么情况下使用该模式。

解决方案描述了设计的细节,通常会给出方案的原理图示(例如 UML 的类图,序列图等,也可能是一些示意图)及相关文字说明,如果可能,还会给出一些代码实例,以便对解决方案的深入理解。

效果描述了设计方案的优势和劣势,这些效果通常面向软件的质量属性,例如,可扩展性、可复用性等。

软件设计模式的重要意义在于设计复用。设计模式可以使设计者更加方便地借鉴或直接使用已经过证实的成功设计方案,而不必花费时间进行重复设计。一些设计模式甚至提供了显示的类图设计及代码实例,为设计的文档化及软件的开发提供了直接的支持。

Ⅳ java中visitor什么意思

你想说的是vector吧
Vector 类在 java 中可以实现自动增长的对象数组。
Java中,数组对象一旦庆岁创建后,其元素的个数 不能被修改。而Java.util包中的Vector类(向量)提供类似于数组的能力,且能够动态地调整自身的大小。Vector类似于一个数组,但与数组相比在使用上誉散睁有两个优点:
① 使用的时候无须声明上限,随着元素的增加,Vector的长度会自动增加;
② Vector类提供额外的方法来增加、删除元素,比数组操作掘昌高效。

Ⅵ java访问者模式中Visitor.visitor(this)中的this是什么意思举个例子详细说

this就是当前类啊
这个意思就是把当前类的当前对象传到visitor对象里面

Ⅶ java 可以动态创建 属性字段么

可以的,你用 javassist, cglib 或者更为底层的工具 ASM 都是可以。

ASM 的话相对复杂一些,参考代码:

下面这个是用 ASM 工具为 Student 类添加一个 public String 类型的 address 属性:

1,需要添加属性的原始类:Student.java

Java code?

public class Student {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

2,添加属性的适配器:AddFieldAdapter.java

Java code?

import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;

public class AddFieldAdapter extends ClassAdapter {
private int accessModifier;
private String name;
private String desc;
private boolean isFieldPresent;

public AddFieldAdapter(ClassVisitor cv, int accessModifier, String name, String desc) {
super(cv);
this.accessModifier = accessModifier;
this.name = name;
this.desc = desc;
}

@Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
if (name.equals(this.name)) {
isFieldPresent = true;
}
return cv.visitField(access, name, desc, signature, value);
}

@Override
public void visitEnd() {
if (!isFieldPresent) {
FieldVisitor fv = cv.visitField(accessModifier, name, desc, null, null);
if (fv != null) {
fv.visitEnd();
}
}
cv.visitEnd();
}
}

3,添加属性的工具 AddField.java

Java code?

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

public class AddField {

private Class clazz = null;
private ClassReader cr = null;
private ClassWriter cw = null;
private ClassAdapter ca = null;
private File classFile = null;

private final static String CLASS_FILE_SUFFIX = ".class";

public AddField(Class clazz) {
this.clazz = clazz;
}

/**
* 添加一个 public 的类成员
* @param fieldName 类成员名
* @param fieldDesc 类成员类型描述
*/
public void addPublicField(String fieldName, String fieldDesc) {
if(cr == null) {
try {
cr = new ClassReader(clazz.getCanonicalName());
} catch (IOException e) {
e.printStackTrace();
}
cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
}
if(ca == null) {
ca = new AddFieldAdapter(cw, Opcodes.ACC_PUBLIC, fieldName, fieldDesc);
} else {
ca = new AddFieldAdapter(ca, Opcodes.ACC_PUBLIC, fieldName, fieldDesc);
}
}

/**
* 将字节码写入类的 .class 文件
*
*/
public void writeByteCode() {
cr.accept(ca, ClassReader.SKIP_DEBUG);
byte[] bys = cw.toByteArray();
OutputStream os = null;
try {
os = new FileOutputStream(getFile());
os.write(bys);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

/**
* 获得类文件的 File 对象
* @return
*/
private File getFile() {
if(classFile == null) {
StringBuffer sb = new StringBuffer();
sb.append(clazz.getResource("/"))
.append(clazz.getCanonicalName().replace(".", File.separator))
.append(CLASS_FILE_SUFFIX);
classFile = new File(sb.substring(6));
}
return classFile;
}
}

Ⅷ java如何统计网站访问量

步骤一、建一个表,表名任意,这里取名为:visitorcounter,表的结构如下所示:
+-------+------------------+------+-----+------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+------------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| vdate | date | NO | | 2000-01-01 | |
| vnum | int(11) | NO | | 0 | |
+-------+------------------+------+-----+------------+----------------+
步骤二、建立一个java类,名字也为:visitorcounter,类的内容如下:
package com.hdzx.pub;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.Date;
public class VisitorCounter {
private final static String TABLE_NAME = "visitorcounter";
private static String today = null;
private static long today_num = 0;
private static long total_num = 0;
//加载访问量
public static void loadNum(){
if(total_num<1)
loadTotalNum();
if(today_num<1)
loadToadyNum();
}
//加载今日访问量
private static void loadToadyNum() {
// TODO Auto-generated method stub
DBConnect db = null;
ResultSet rs = null;
if(today==null)
today = getTodayDate();
String sql = "select vnum from "+TABLE_NAME+" where vdate='"+today+"'";
try {
db = new DBConnect();
rs = db.executeQuery(sql);
if(rs.next()){
today_num = rs.getLong("vnum");
}
else
{
sql = "insert into "+TABLE_NAME+"(vdate,vnum) values('"+today+"',0)";
db.executeUpdate(sql);
today_num = 0;
}
} catch (Exception e) {
// TODO: handle exception
today_num = 0;
System.out.println("com.hdzx.pub~VisitorCounter.incTotalCounter:获得访问人数");
}
}
//加载总访问量
private static void loadTotalNum() {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
DBConnect db = null;
ResultSet rs = null;
if(today==null)
today = getTodayDate();
String sql = "select vnum from "+TABLE_NAME+" where id=1";
try {
db = new DBConnect();
rs = db.executeQuery(sql);
if(rs.next()){
total_num = rs.getLong("vnum");
}
else
{
total_num = 0;
}
} catch (Exception e) {
// TODO: handle exception
total_num = 0;
System.out.println("com.hdzx.pub~VisitorCounter.incTotalCounter:获得访问人数");
}
}
//增加总的访问量
private static int incTotalCounter(){
int k = 0;
DBConnect db = null;
loadNum();
total_num = total_num+1;
String sql = "update "+TABLE_NAME+" set vnum="+total_num+" where id=1";
try {
db = new DBConnect();
k = db.executeUpdate(sql);
} catch (Exception e) {
// TODO: handle exception
System.out.println("com.hdzx.pub~VisitorCounter.incTotalCounter:增加访问人数");
}
return k;
}
//增加今日的访问量
public static int incTodayCounter(){
int k = 0;
DBConnect db = null;
String sql = null;
loadNum();
today_num += 1;
sql = "update "+TABLE_NAME+" set vnum="+today_num+" where vdate='"+today+"'";
try {
db = new DBConnect();
k = db.executeUpdate(sql);
if(k > 0)
incTotalCounter();
} catch (Exception e) {
// TODO: handle exception
System.out.println("com.hdzx.pub~VisitorCounter.incTotalCounter:增加访问人数");
}
return k;
}
//获得今天的日期
private static String getTodayDate(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(new Date());
}
///获得今日访问量
public static long getTodayNum(){
loadNum();
return today_num;
}
//获得总的访问量
public static long getTotalNum(){
loadNum();
return total_num;
}
}
步骤三、经过以上的步骤后,在页面中加入以下的代码,就可以实现网站访问量的统计工作:
if(session.isNew())
{
VisitorCounter.incTodayCounter();
}
%>
今日访问量:<%=VisitorCounter.getTodayNum() %><br/>
总的访问量: <%=VisitorCounter.getTotalNum() %>

阅读全文

与visitorjava相关的资料

热点内容
压缩空气喷射器 浏览:488
python提高效率 浏览:796
华为文件管理怎么样输入解压码 浏览:800
深思加密狗初始化 浏览:566
黄金崩溃pdf 浏览:309
华为特定短信息加密 浏览:375
微机原理与单片机技术李精华答案 浏览:816
pic12c508单片机 浏览:309
androidgps调用 浏览:226
金文编pdf 浏览:445
14乘87减147的简便算法 浏览:473
怎么创建edu文件夹 浏览:721
算法的基础问题 浏览:256
苹果手机怎么选择app支付 浏览:856
访问加密服务器失败怎么回事 浏览:439
程序员每天跑步5公里 浏览:789
党员对程序员有帮助么 浏览:550
慢跑穿压缩衣还是紧身衣 浏览:214
什么服务器引擎最好 浏览:497
日立制冷压缩机 浏览:777