您的位置:首页 > 编程语言 > Java开发

JAVA基础10 设计模式:结构型模式(适配器 代理模式 桥接模式 享元模式 组合模式 装饰器模式)

2015-08-27 19:51 716 查看
结构型模式:

核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题

分类: 适配器模式 代理模式 桥接模式 装饰模式 组合模式 外观模式 享元模式

我们在学习中见过的场景

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"))));
}
}


案例 外观模式

一个软件实体应尽可能少的与其他实体发生相互作用

为子系统提供统一的入口,分装子系统的复杂性 便于客户端调用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: