装饰器设计模式
装饰器设计模式,其实就是对一个类进行的装饰。 以完成在不进行继承的基础上,拓展一个类的功能。需要让每一个装饰者类实现相同的接口,被装饰的类也实现相同的接口。在IO流部分,对装饰器模式的使用比较多的。
下面就是装饰器模式的应用:
BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream(new File("file\\装饰器模式")));
public class DecoratorTest {
public static void main(String[] args) {
Person p=new Person();
Decorator decorator=new ShoesDecorator(new TrousersDecorator(new TshirtDecorator(p)));
decorator.show();
}
}
class Person implements Decorator{
@Override
public void show() {
System.out.println("一个人站在这");
}
}
interface Decorator{
void show();
}
abstract class AbstractDecorator implements Decorator{
protected Decorator decorator;
public AbstractDecorator(Decorator decorator){
this.decorator=decorator;
}
}
class ShoesDecorator extends AbstractDecorator{
public ShoesDecorator(Decorator decorator){
super(decorator);
}
@Override
public void show() {
decorator.show();
System.out.println("穿了一双鞋");
}
}
class TshirtDecorator extends AbstractDecorator{
public TshirtDecorator(Decorator decorator) {
super(decorator);
}
@Override
public void show() {
decorator.show();
System.out.println("穿了T恤衫");
}
}
class TrousersDecorator extends AbstractDecorator {
public TrousersDecorator(Decorator decorator) {
super(decorator);
}
@Override
public void show() {
this.decorator.show();
System.out.println("穿了一条裤子");
}
}
代理模式
有些时候,需要自己去处理的一些逻辑、任务,此时由于种种原因,导致自己无法处理,委托给其他人去处理。这种模式,就是一个代理模式。找到一个代理,帮助我完成某些任务。
案例:代购。小明、小美、小娟,知道了老王要出国玩,想让老王帮忙代购苹果电脑。
在代理模式中,代理者与被代理者,应该具有相同的功能。
静态代理
public class StaticProxyTest {
public static void main(String[] args) {
// 1. 实例化三个购买方
Buyer xiaoming = new Buyer("小明");
Buyer xiaomei = new Buyer("小美");
Buyer xiaojuan = new Buyer("小娟");
// 2. 实例化一个代购方
Proxy proxy = new Proxy("老王", xiaoming, xiaomei, xiaojuan);
//购买
proxy.buyMac("MacBook Pro");
}
}
interface BuyMac{
void buyMac(String type);
}
//实际购买者
class Buyer implements BuyMac{
private String name;
public Buyer(String name){
this.name=name;
}
public String getName() {
return name;
}
@Override
public void buyMac(String type) {
System.out.println(name+"买了一台"+type);
}
}
//代购
class Proxy implements BuyMac{
private String name;
private Buyer[] buyers;
public Proxy(String name,Buyer ... byers){
this.name=name;
this.buyers=byers;
}
@Override
public void buyMac(String type) {
System.out.println("代购"+this.name+"走进了店里");
for (Buyer buyer : buyers) {
System.out.println(buyer.getName()+"买了一台"+type);
}
System.out.println("代购"+this.name+"走出了店");
}
}
动态代理
为了解决静态代理中的复杂的需求(每一个被代理者需求都不一样)
案例: 小明、小美、小娟三个人都需要购买苹果设备,找到了一个代购————老王。但是他们三个人的需求是不一样的: 小明需要买电脑、小美需要买手机、小娟需要买pad。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author 昊
* @Create 2020/5/10 9:47
* @Description
*/
public class DynamicProxyTest {
public static void main(String[] args) {
// 小明需要购买电脑
MacBuyer xiaoming = new MacBuyer("xiaoming");
// 小美需要购买手机
PhoneBuyer xiaomei = new PhoneBuyer("xiaomei");
// 小娟需要购买pad
PadBuyer xiaojuan = new PadBuyer("xiaojuan");
// 实例化动态代理类对象
DynamicProxy proxy = new DynamicProxy();
//getBuyer得到的是Object对象,要强转成Buy
Buy buyer = (Buy) (proxy.getBuyer(xiaoming));
buyer.buy();
Buy buyer1 = (Buy) (proxy.getBuyer(xiaomei));
buyer1.buy();
Buy buyer2 = (Buy) (proxy.getBuyer(xiaojuan));
buyer2.buy();
}
}
//实际购买者
abstract class Buyer{
protected String name;
}
//购买行为
interface Buy{
void buy();
}
class MacBuyer extends Buyer implements Buy{
public MacBuyer(String name){
this.name=name;
}
@Override
public void buy() {
System.out.println(this.name+"购买了一个MacBook Pro");
}
}
class PhoneBuyer extends Buyer implements Buy{
public PhoneBuyer(String name){
this.name=name;
}
@Override
public void buy() {
System.out.println(this.name+"购买了 iphone 12 ");
}
}
class PadBuyer extends Buyer implements Buy {
public PadBuyer(String name) {
this.name = name;
}
@Override
public void buy() {
System.out.println(this.name + "得到了一个 iPad Pro");
}
}
//代购,必须实现InvocationHandler接口,并重写invoke方法
class DynamicProxy implements InvocationHandler{
//实际购买者
private Object buyer;
public Object getBuyer(Object buyer){
this.buyer=buyer;
/*
* Proxy: java.lang.reflect.Proxy类,专门用来表示动态代理的类
* Proxy.newProxyInstance: 获取一个动态代理对象
*
* 参数1: ClassLoader: 指定产生代理类的类加载器,需要使用它来指定目标类的类加载器。
* 参数2: 指定目标类实现的接口
* 参数3: 指定了InvocationHandler实现类
* 返回一个Object对象,所以购买者的类型是Object而不是Buyer
*/
return Proxy.newProxyInstance(buyer.getClass().getClassLoader(),buyer.getClass().getInterfaces(),this);
}
/**
*
* @param o 购买者
* @param method 代理的行为==>购买行为,即购买方法
* @param objects 行为的参数
* @return 执行结果
* @throws Throwable 抛出的异常
*/
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("代购走进店里");
return method.invoke(this.buyer,objects);
}
}