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

结构型模式: 
核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题
分类: 适配器模式 代理模式 桥接模式 装饰模式 组合模式 外观模式 享元模式
我们在学习中见过的场景
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"))));
	}
}


案例 外观模式

    一个软件实体应尽可能少的与其他实体发生相互作用
    为子系统提供统一的入口,分装子系统的复杂性 便于客户端调用




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值