java装饰设计模式代码 java装饰设计模式代码有哪些
Java设计模式之Decorator模式
JDK为程序员提供了大量的类库 而为了保持类库的可重用性 可扩展性和灵活性 其中使用到了大量的设计模式 本文将介绍JDK的I/O包中使用到的Decorator模式 并运用此模式 实现一个新的输出流类
目前创新互联已为上千多家的企业提供了网站建设、域名、雅安服务器托管、网站托管、服务器租用、企业网站设计、上虞网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
Decorator模式简介
Decorator模式又名包装器(Wrapper) 它的主要用途在于给一个对象动态的添加一些额外的职责 与生成子类相比 它更具有灵活性
有时候 我们需要为一个对象而不是整个类添加一些新的功能 比如 给一个文本区添加一个滚动条的功能 我们可以使用继承机制来实现这一功能 但是这种方法不够灵活 我们无法控制文本区加滚动条的方式和时机 而且当文本区需要添加更多的功能时 比如边框等 需要创建新的类 而当需要组合使用这些功能时无疑将会引起类的爆炸
我们可以使用一种更为灵活的方法 就是把文本区嵌入到滚动条中 而这个滚动条的类就相当于对文本区的一个装饰 这个装饰(滚动条)必须与被装饰的组件(文本区)继承自同一个接口 这样 用户就不必关心装饰的实现 因为这对他们来说是透明的 装饰会将用户的请求转发给相应的组件(即调用相关的方法) 并可能在转发的前后做一些额外的动作(如添加滚动条) 通过这种方法 我们可以根据组合对文本区嵌套不同的装饰 从而添加任意多的功能 这种动态的对对象添加功能的方法不会引起类的爆炸 也具有了更多的灵活性
以上的方法就是Decorator模式 它通过给对象添加装饰来动态的添加新的功能 如下是Decorator模式的UML图
Component为组件和装饰的公共父类 它定义了子类必须实现的方法
ConcreteComponent是一个具体的组件类 可以通过给它添加装饰来增加新的功能
Decorator是所有装饰的公共父类 它定义了所有装饰必须实现的方法 同时 它还保存了一个对于Component的引用 以便将用户的请求转发给Component 并可能在转发请求前后执行一些附加的动作
ConcreteDecoratorA和ConcreteDecoratorB是具体的装饰 可以使用它们来装饰具体的Component
Java IO包中的Decorator模式
JDK提供的java io包中使用了Decorator模式来实现对各种输入输出流的封装 以下将以java io OutputStream及其子类为例 讨论一下Decorator模式在IO中的使用
首先来看一段用来创建IO流的代码
以下是代码片段
try {
DataOutputStream out = new DataOutputStream(new FileOutputStream(
test txt ));
} catch (FileNotFoundException e) {
e printStackTrace();
}
这段代码对于使用过JAVA输入输出流的人来说再熟悉不过了 我们使用DataOutputStream封装了一个FileOutputStream 这是一个典型的Decorator模式的使用 FileOutputStream相当于Component DataOutputStream就是一个Decorator 将代码改成如下 将会更容易理解
以下是代码片段
try {
OutputStream out = new FileOutputStream( test txt );
out = new DataOutputStream(out);
} catch(FileNotFoundException e) {
e printStatckTrace();
}
由于FileOutputStream和DataOutputStream有公共的父类OutputStream 因此对对象的装饰对于用户来说几乎是透明的 下面就来看看OutputStream及其子类是如何构成Decorator模式的
OutputStream是一个抽象类 它是所有输出流的公共父类 其源代码如下
以下是代码片段
public abstract class OutputStream implements Closeable Flushable {
public abstract void write(int b) throws IOException;
}
它定义了write(int b)的抽象方法 这相当于Decorator模式中的Component类
ByteArrayOutputStream FileOutputStream 和 PipedOutputStream 三个类都直接从OutputStream继承 以ByteArrayOutputStream为例
以下是代码片段
public class ByteArrayOutputStream extends OutputStream {
protected byte buf[];
protected int count;
public ByteArrayOutputStream() {
this( );
}
public ByteArrayOutputStream(int size) {
if (size 〈 ) {
throw new IllegalArgumentException( Negative initial size: + size);
}
buf = new byte[size];
}
public synchronized void write(int b) {
int newcount = count + ;
if (newcount 〉 buf length) {
byte newbuf[] = new byte[Math max(buf length 〈〈 newcount)];
System arraycopy(buf newbuf count);
buf = newbuf;
}
buf[count] = (byte)b;
count = newcount;
}
}
它实现了OutputStream中的write(int b)方法 因此我们可以用来创建输出流的对象 并完成特定格式的输出 它相当于Decorator模式中的ConcreteComponent类
接着来看一下FilterOutputStream 代码如下
以下是代码片段
public class FilterOutputStream extends OutputStream {
protected OutputStream out;
public FilterOutputStream(OutputStream out) {
this out = out;
}
public void write(int b) throws IOException {
out write(b);
}
}
同样 它也是从OutputStream继承 但是 它的构造函数很特别 需要传递一个OutputStream的引用给它 并且它将保存对此对象的引用 而如果没有具体的OutputStream对象存在 我们将无法创建FilterOutputStream 由于out既可以是指向FilterOutputStream类型的引用 也可以是指向ByteArrayOutputStream等具体输出流类的引用 因此使用多层嵌套的方式 我们可以为ByteArrayOutputStream添加多种装饰 这个FilterOutputStream类相当于Decorator模式中的Decorator类 它的write(int b)方法只是简单的调用了传入的流的write(int b)方法 而没有做更多的处理 因此它本质上没有对流进行装饰 所以继承它的子类必须覆盖此方法 以达到装饰的目的
BufferedOutputStream 和 DataOutputStream是FilterOutputStream的两个子类 它们相当于Decorator模式中的ConcreteDecorator 并对传入的输出流做了不同的装饰 以BufferedOutputStream类为例
以下是代码片段
public class BufferedOutputStream extends FilterOutputStream {
private void flushBuffer() throws IOException {
if (count 〉 ) {
out write(buf count);
count = ;
}
}
public synchronized void write(int b) throws IOException {
if (count 〉= buf length) {
flushBuffer();
}
buf[count++] = (byte)b;
}
}
这个类提供了一个缓存机制 等到缓存的容量达到一定的字节数时才写入输出流 首先它继承了FilterOutputStream 并且覆盖了父类的write(int b)方法 在调用输出流写出数据前都会检查缓存是否已满 如果未满 则不写 这样就实现了对输出流对象动态的添加新功能的目的
下面 将使用Decorator模式 为IO写一个新的输出流
自己写一个新的输出流
了解了OutputStream及其子类的结构原理后 我们可以写一个新的输出流 来添加新的功能 这部分中将给出一个新的输出流的例子 它将过滤待输出语句中的空格符号 比如需要输出 java io OutputStream 则过滤后的输出为 javaioOutputStream 以下为SkipSpaceOutputStream类的代码
以下是代码片段
import java io FilterOutputStream;
import java io IOException;
import java io OutputStream;
/**
* A new output stream which will check the space character
* and won t write it to the output stream
* @author Magic
*
*/
public class SkipSpaceOutputStream extends FilterOutputStream {
public SkipSpaceOutputStream(OutputStream out) {
super(out);
}
/**
* Rewrite the method in the parent class and
* skip the space character
*/
public void write(int b) throws IOException{
if(b!= ){
super write(b);
}
}
}
它从FilterOutputStream继承 并且重写了它的write(int b)方法 在write(int b)方法中首先对输入字符进行了检查 如果不是空格 则输出
以下是一个测试程序
以下是代码片段
import java io BufferedInputStream;
import java io DataInputStream;
import java io DataOutputStream;
import java io IOException;
import java io InputStream;
import java io OutputStream;
/**
* Test the SkipSpaceOutputStream
* @author Magic
*
*/
public class Test {
public static void main(String[] args){
byte[] buffer = new byte[ ];
/**
* Create input stream from the standard input
*/
InputStream in = new BufferedInputStream(new DataInputStream(System in));
/**
* write to the standard output
*/
OutputStream out = new SkipSpaceOutputStream(new DataOutputStream(System out));
try {
System out println( Please input your words: );
int n = in read(buffer buffer length);
for(int i= ;i〈n;i++){
out write(buffer[i]);
}
} catch (IOException e) {
e printStackTrace();
}
}
}
执行以上测试程序 将要求用户在console窗口中输入信息 程序将过滤掉信息中的空格 并将最后的结果输出到console窗口 比如
以下是引用片段
Please input your words:
a b c d e f
abcdef
总 结
lishixinzhi/Article/program/Java/gj/201311/27433
急求java设计模式,要求用到两种设计模式 求详细代码
.饿汉式单例类
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton1 {
//私有的默认构造子
private Singleton1() {}
//已经自行实例化
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
2.懒汉式单例类
//懒汉式单例类.在第一次调用的时候实例化
public class Singleton2 {
//私有的默认构造子
private Singleton2() {}
//注意,这里没有final
private static Singleton2 single=null;
//静态工厂方法
public synchronized static Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}
//对懒汉式单例的改进(错误的改进)
//实际上,只有在第一次创建对象的时候需要加锁,之后就不需要了 ,这样可以提升性能
public synchronized static Singleton2 getInstance() {
if (instance == null) {
synchronized(instance){ //锁住当前实例对象
if(instance == null){
instance = new Singleton2();
}
}
}
return instance;
}
错误原因:
aA、B线程同时进入了第一个if判断
bA首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();
c由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后A离开了synchronized块。
dB进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。
e此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。
正确改进(使用内部类):
JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的,JVM能够帮我们保证instance只被创建一次,
并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心上面的问题。
同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题
public?class?Singleton?{??
??
/*?私有构造方法,防止被实例化?*/??
private?Singleton(){
}
/*?此处使用一个内部类来维护单例?*/??
private?static?class?SingletonFactory?{??
private?static?Singleton?instance?=?new?Singleton();??
}
/*?获取实例?*/??
public?static?Singleton?getInstance()?{??
return?SingletonFactory.instance;??
}
/*?如果该对象被用于序列化,可以保证对象在序列化前后保持一致?*/??
public?Object?readResolve()?{??
return?getInstance();??
}
}
其实说它完美,也不一定,如果在构造函数中抛出异常,实例将永远得不到创建,也会出错????
第二种改进:
因为我们只需要在创建类的时候进行同步,所以只要将创建和getInstance()分开,
单独为创建加synchronized关键字,也是可以的
public class Singleton {
private static Singleton instance=null;
private Singleton(){}
private static synchronized void Init(){
if(instance==null)
instance=new Singletion();
}
public static Singleton getInstance(){
if(instance==null){
Init();
}
return instance;
}
}
3.登记式单例类
import java.util.HashMap;
import java.util.Map;
//登记式单例类.
//类似Spring里面的方法,将类名注册,下次从里面直接获取。
public class Singleton3 {
private static MapString,Singleton3 map = new HashMapString,Singleton3();
static{
Singleton3 single = new Singleton3();
map.put(single.getClass().getName(), single);
}
//保护的默认构造子
protected Singleton3(){}
//静态工厂方法,返还此类惟一的实例
public static Singleton3 getInstance(String name) {
if(name == null) {
name = Singleton3.class.getName();
System.out.println("name == null"+"---name="+name);
}
if(map.get(name) == null) {
try {
map.put(name, (Singleton3) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//一个示意性的商业方法
public String about() {
return "Hello, I am RegSingleton.";
}
public static void main(String[] args) {
Singleton3 single3 = Singleton3.getInstance(null);
System.out.println(single3.about());
}
}
java写一套漂亮的代码,哪些设计模式比较常用
策略模式,单例模式,装饰模式,简单工厂模式这几种模式个人感觉在实际开发过程中用的比较多,开发的多了对模式的概念反而会渐渐模糊
JAVA23种设计模式
设计模式主要分三个类型:创建型、结构型和行为型。
其中创建型有:
一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点
二、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。
四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。
五、Prototype,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。
行为型有:
六、Iterator,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。
七、Observer,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。
八、Template Method,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。
九、Command,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。
十、State,状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。
十一、Strategy,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。
十二、China of Responsibility,职责链模式:使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系
十三、Mediator,中介者模式:用一个中介对象封装一些列的对象交互。
十四、Visitor,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。
十五、Interpreter,解释器模式:给定一个语言,定义他的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
十六、Memento,备忘录模式:在不破坏对象的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
结构型有:
十七、Composite,组合模式:将对象组合成树形结构以表示部分整体的关系,Composite使得用户对单个对象和组合对象的使用具有一致性。
十八、Facade,外观模式:为子系统中的一组接口提供一致的界面,fa?ade提供了一高层接口,这个接口使得子系统更容易使用。
十九、Proxy,代理模式:为其他对象提供一种代理以控制对这个对象的访问
二十、Adapter,适配器模式:将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。
二十一、Decrator,装饰模式:动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。
二十二、Bridge,桥模式:将抽象部分与它的实现部分相分离,使他们可以独立的变化。
二十三、Flyweight,享元模式
23种设计模式要在这里详细的都说一遍内容实在太多了啊,推荐你一本好书《软件秘笈:设计模式那点事》,里面讲解的23中设计模式例子很生动,容易理解,还有JDK中设计模式应用情况,看了收获挺大的!百度里面搜“设计模式”,第一条中设计模式百度百科中就有首推该图书,浏览量在20几万以上的,不会错的。
祝你早日学会设计模式!
分享题目:java装饰设计模式代码 java装饰设计模式代码有哪些
转载来源:http://ybzwz.com/article/ddedccg.html