JAVA基础10 设计模式:结构型模式(适配器 代理模式 桥接模式 享元模式 组合模式 装饰器模式)
2015-08-27 19:51
716 查看
结构型模式:
核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题
分类: 适配器模式 代理模式 桥接模式 装饰模式 组合模式 外观模式 享元模式
我们在学习中见过的场景
java.io.InputStreamReader(InputStream)
java.io.OutputStreamWriter(OutputStream)
分类: 静态代理(静态定义代理类)
动态代理(动态代理生成代理类)
JDK自带的动态代理
javaassist字节码操作库实现
CGLIB
ASM(底层使用指令 可维护性较差)
JDK自带的动态代理
1.java.lang.reflect.Proxy :动态生成代理类和对象
2.java.lang.reflect.InvocationHandler(处理器接口)
可以通过invoke方法实现对真实角色的代理访问
每次通过Proxy生产代理类对象对象时都要指定对应的代理器对象
享元模式
内存属于稀缺资源,不要随便浪费, 如果有多个完全相同或相似的对象,我们可以通过享元模式,节省内存
核心:
享元模式以共享的方式高效地支持大量细粒度对象的重用
享元对象能做到共享的关键是区分了内部状态和外部状态
内部状态:可以共享 不会随环境变化而改变
外部状态:不可以共享,会随环境变化而改变
优点:减少内存中对象的数量
相同或相似对象内存中只存一份, 极大的节约资源,提高系统性能
外部状态相对独立 不影响内部状态
缺点
模式较复杂, 使程序逻辑复杂化
为了节省内存 共享了内部状态 分离出外部状态,而读取外部状态使时间变长,用时间换取了空间
使用组合模式的场景:
把部分和整体的关系用树形结构来表示, 从而使客户端可以使用统一的方式处理部分对象和整体对象
组合模型核心:
抽象构件角色:定义了叶子和容器构件的共同点
叶子构件角色:无子节点
容器构件角色:有容器特征 可以包含子节点
开发中的应用场景
操作系统的资源管理器
GUI中的容器层次图
XML文件解析
OA系统中,组织结构的处理
Junit单元测试框架
为子系统提供统一的入口,分装子系统的复杂性 便于客户端调用
核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题
分类: 适配器模式 代理模式 桥接模式 装饰模式 组合模式 外观模式 享元模式
我们在学习中见过的场景
java.io.InputStreamReader(InputStream)
java.io.OutputStreamWriter(OutputStream)
案例 适配器模式
<span style="font-size:14px;">public class Client { public void test1(Target t){ t.handleReq(); } public static void main(String[] args) { Client c = new Client(); Adaptee a = new Adaptee(); // Target t = new Adapter(); Target t = new Adapter2(a); c.test1(t); } } /** * 被适配的类 * @author Administrator * */ public class Adaptee { public void request(){ System.out.println("可以完成客户请求的需要的功能!"); } } public interface Target { void handleReq(); } /** * 适配器 (类适配器方式) * (相当于usb和ps/2的转接器) * @author Administrator * */ public class Adapter extends Adaptee implements Target { @Override public void handleReq() { super.request(); } } /** * 适配器 (对象适配器方式,使用了组合的方式跟被适配对象整合) * (相当于usb和ps/2的转接器) * @author Administrator * */ public class Adapter2 implements Target { private Adaptee adaptee; @Override public void handleReq() { adaptee.request(); } public Adapter2(Adaptee adaptee) { super(); this.adaptee = adaptee; } }</span>
代理模式
通过代理,控制对对象的访问!可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理分类: 静态代理(静态定义代理类)
动态代理(动态代理生成代理类)
JDK自带的动态代理
javaassist字节码操作库实现
CGLIB
ASM(底层使用指令 可维护性较差)
案例 静态代理
<span style="font-size:14px;">public interface Star { /** * 面谈 */ void confer(); /** * 签合同 */ void signContract(); /** * 订票 */ void bookTicket(); /** * 唱歌 */ void sing(); /** * 收钱 */ void collectMoney(); } public class RealStar implements Star { @Override public void bookTicket() { System.out.println("RealStar.bookTicket()"); } @Override public void collectMoney() { System.out.println("RealStar.collectMoney()"); } @Override public void confer() { System.out.println("RealStar.confer()"); } @Override public void signContract() { System.out.println("RealStar.signContract()"); } @Override public void sing() { System.out.println("RealStar(周杰伦本人).sing()"); } } public class ProxyStar implements Star { private Star star; public ProxyStar(Star star) { super(); this.star = star; } @Override public void bookTicket() { System.out.println("ProxyStar.bookTicket()"); } @Override public void collectMoney() { System.out.println("ProxyStar.collectMoney()"); } @Override public void confer() { System.out.println("ProxyStar.confer()"); } @Override public void signContract() { System.out.println("ProxyStar.signContract()"); } @Override public void sing() { star.sing(); } } public class Client { public static void main(String[] args) { Star real = new RealStar(); Star proxy = new ProxyStar(real); proxy.confer(); proxy.signContract(); proxy.bookTicket(); proxy.sing(); proxy.collectMoney(); } }</span>
JDK自带的动态代理
1.java.lang.reflect.Proxy :动态生成代理类和对象
2.java.lang.reflect.InvocationHandler(处理器接口)
可以通过invoke方法实现对真实角色的代理访问
每次通过Proxy生产代理类对象对象时都要指定对应的代理器对象
案例 动态代理
<span style="font-size:14px;">public class Client { public static void main(String[] args) { Star realStar = new RealStar(); StarHandler handler = new StarHandler(realStar); Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler); proxy.sing(); } } public interface Star { /** * 面谈 */ void confer(); /** * 签合同 */ void signContract(); /** * 订票 */ void bookTicket(); /** * 唱歌 */ void sing(); /** * 收钱 */ void collectMoney(); } public class RealStar implements Star { @Override public void bookTicket() { System.out.println("RealStar.bookTicket()"); } @Override public void collectMoney() { System.out.println("RealStar.collectMoney()"); } @Override public void confer() { System.out.println("RealStar.confer()"); } @Override public void signContract() { System.out.println("RealStar.signContract()"); } @Override public void sing() { System.out.println("RealStar(周杰伦本人).sing()"); } } public class StarHandler implements InvocationHandler { Star realStar; public StarHandler(Star realStar) { super(); this.realStar = realStar; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object object = null; System.out.println("真正的方法执行前!"); System.out.println("面谈,签合同,预付款,订机票"); if(method.getName().equals("sing")){ object = method.invoke(realStar, args); } System.out.println("真正的方法执行后!"); System.out.println("收尾款"); return object; } }</span>
案例 桥接模式
<span style="font-size:14px;">public interface Brand { void sale(); } class Lenovo implements Brand { @Override public void sale() { System.out.println("销售联想电脑"); } } class Dell implements Brand { @Override public void sale() { System.out.println("销售Dell电脑"); } } } public class Computer2 { protected Brand brand; public Computer2(Brand b) { this.brand = b; } public void sale(){ brand.sale(); } } class Desktop2 extends Computer2 { public Desktop2(Brand b) { super(b); } @Override public void sale() { super.sale(); System.out.println("销售台式机"); } } class Laptop2 extends Computer2 { public Laptop2(Brand b) { super(b); } @Override public void sale() { super.sale(); System.out.println("销售笔记本"); } } public class Client { public static void main(String[] args) { //销售联想的笔记本电脑 Computer2 c = new Laptop2(new Lenovo()); c.sale(); //销售神舟的台式机 Computer2 c2 = new Desktop2(new Shenzhou()); c2.sale(); } }</span>
享元模式
内存属于稀缺资源,不要随便浪费, 如果有多个完全相同或相似的对象,我们可以通过享元模式,节省内存
核心:
享元模式以共享的方式高效地支持大量细粒度对象的重用
享元对象能做到共享的关键是区分了内部状态和外部状态
内部状态:可以共享 不会随环境变化而改变
外部状态:不可以共享,会随环境变化而改变
优点:减少内存中对象的数量
相同或相似对象内存中只存一份, 极大的节约资源,提高系统性能
外部状态相对独立 不影响内部状态
缺点
模式较复杂, 使程序逻辑复杂化
为了节省内存 共享了内部状态 分离出外部状态,而读取外部状态使时间变长,用时间换取了空间
案例 享元模式
<span style="font-size:14px;">public class Client { public static void main(String[] args) { ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色"); ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色"); System.out.println(chess1); System.out.println(chess2); System.out.println("增加外部状态的处理==========="); chess1.display(new Coordinate(10, 10)); chess2.display(new Coordinate(20, 20)); } } public class Coordinate { private int x,y; public Coordinate(int x, int y) { super(); this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } } public interface ChessFlyWeight { void setColor(String c); String getColor(); void display(Coordinate c); } class ConcreteChess implements ChessFlyWeight { private String color; public ConcreteChess(String color) { super(); this.color = color; } @Override public void display(Coordinate c) { System.out.println("棋子颜色:"+color); System.out.println("棋子位置:"+c.getX()+"----"+c.getY()); } @Override public String getColor() { return color; } @Override public void setColor(String c) { this.color = c; } } public class ChessFlyWeightFactory { //享元池 private static Map<String,ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>(); public static ChessFlyWeight getChess(String color){ if(map.get(color)!=null){ return map.get(color); }else{ ChessFlyWeight cfw = new ConcreteChess(color); map.put(color, cfw); return cfw; } } }</span>
使用组合模式的场景:
把部分和整体的关系用树形结构来表示, 从而使客户端可以使用统一的方式处理部分对象和整体对象
组合模型核心:
抽象构件角色:定义了叶子和容器构件的共同点
叶子构件角色:无子节点
容器构件角色:有容器特征 可以包含子节点
开发中的应用场景
操作系统的资源管理器
GUI中的容器层次图
XML文件解析
OA系统中,组织结构的处理
Junit单元测试框架
案例 组合模式 非常适合处理树形结构
public interface AbstractFile { void killVirus(); //杀毒 } class ImageFile implements AbstractFile { private String name; public ImageFile(String name) { super(); this.name = name; } @Override public void killVirus() { System.out.println("---图像文件:"+name+",进行查杀!"); } } class TextFile implements AbstractFile { private String name; public TextFile(String name) { super(); this.name = name; } @Override public void killVirus() { System.out.println("---文本文件:"+name+",进行查杀!"); } } class VideoFile implements AbstractFile { private String name; public VideoFile(String name) { super(); this.name = name; } @Override public void killVirus() { System.out.println("---视频文件:"+name+",进行查杀!"); } } class Folder implements AbstractFile { private String name; //定义容器,用来存放本容器构建下的子节点 private List<AbstractFile> list = new ArrayList<AbstractFile>(); public Folder(String name) { super(); this.name = name; } public void add(AbstractFile file){ list.add(file); } public void remove(AbstractFile file){ list.remove(file); } public AbstractFile getChild(int index){ return list.get(index); } @Override public void killVirus() { System.out.println("---文件夹:"+name+",进行查杀"); for (AbstractFile file : list) { file.killVirus(); } } } public class Client { public static void main(String[] args) { AbstractFile f2,f3,f4,f5; Folder f1 = new Folder("我的收藏"); f2 = new ImageFile("老高的大头像.jpg"); f3 = new TextFile("Hello.txt"); f1.add(f2); f1.add(f3); Folder f11 = new Folder("电影"); f4 = new VideoFile("笑傲江湖.avi"); f5 = new VideoFile("神雕侠侣.avi"); f11.add(f4); f11.add(f5); f1.add(f11); // f2.killVirus(); f1.killVirus(); } }
案例 装饰器模式
动态的为一个对象增加新的功能 是一种代替继承的技术,无需通过继承增加子类就能扩张对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀 public interface ICar { void move(); } //ConcreteComponent 具体构件角色(真实对象) class Car implements ICar { @Override public void move() { System.out.println("陆地上跑!"); } } //Decorator装饰角色 class SuperCar implements ICar { protected ICar car; public SuperCar(ICar car) { super(); this.car = car; } @Override public void move() { car.move(); } } //ConcreteDecorator具体装饰角色 class FlyCar extends SuperCar { public FlyCar(ICar car) { super(car); } public void fly(){ System.out.println("天上飞!"); } @Override public void move() { super.move(); fly(); } } //ConcreteDecorator具体装饰角色 class WaterCar extends SuperCar { public WaterCar(ICar car) { super(car); } public void swim(){ System.out.println("水上游!"); } @Override public void move() { super.move(); swim(); } } //ConcreteDecorator具体装饰角色 class AICar extends SuperCar { public AICar(ICar car) { super(car); } public void autoMove(){ System.out.println("自动跑!"); } @Override public void move() { super.move(); autoMove(); } } public class Client { public static void main(String[] args) { Car car = new Car(); car.move(); System.out.println("增加新的功能,飞行----------"); FlyCar flycar = new FlyCar(car); flycar.move(); System.out.println("增加新的功能,水里游---------"); WaterCar waterCar = new WaterCar(car); waterCar.move(); System.out.println("增加两个新的功能,飞行,水里游-------"); WaterCar waterCar2 = new WaterCar(new FlyCar(car)); waterCar2.move(); // Reader r = new BufferedReader(new InputStreamReader(new FileInputStream(new File("d:/a.txt")))); } }
案例 外观模式
一个软件实体应尽可能少的与其他实体发生相互作用为子系统提供统一的入口,分装子系统的复杂性 便于客户端调用
相关文章推荐
- Hibernate3使用(一)不使用Spring时使用Hibernate
- Java注释Override、Deprecated、SuppressWarnings
- org.w3c.dom处理xml的常用方法
- Java LinqCollection 仿Linq的list常用函数
- Struts2笔记——ONGL表达式语言
- Struts2笔记——ONGL表达式语言
- Eclipse技巧:[5]eclipse js提示
- Java的向上转型与向下转型
- java--类型
- eclipse安装了adt之后再选择了sdk路径,工具栏里找不到sdk和avd的manager
- eclipse 开发环境配置
- 深入理解Java的接口和抽象类
- Java学习之自动装箱和自动拆箱源码分析
- Java快速排序
- Myeclipse 10,删除工程导致 severUI打不开
- HBase Java客户端编程
- 深入Java类加载器
- 零基础搭建 spring mvc 4 项目(本文基于 Servlet 3.0)
- 零基础搭建 spring mvc 4 项目(本文基于 Servlet 3.0)
- myeclipse导出doc