构建型设计模式—adapter(适配器模式)/bridge(桥接模式)/decorator(装饰者模式)

本文探讨了适配器模式如何处理不同接口需求,桥接模式如何解决多维度扩展,以及装饰者模式如何动态添加功能。通过实例解析,展示了这些模式在实际编程中的应用和优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、构建型设计模式的作用

关注点在于如何将多个类或对象,整体布局成一个更强大的结构

二、adapter(适配器模式)

(1)、思想

	当原接口不能处理某种数据的时候,就交给一个适配器去处理(类似于转接头原理)。
适配器根据不同的参数,来确定用哪一个扩展的对象方法(哪一个插卡连接)来处理数据。
重点就在于根据参数的不同,选择不同的处理方式,在客户端要看不出内部实现,
逻辑全在适配器里判断。

(2)、步骤

 1. 声明原接口,创建接口方法。
 2. 声明原接口实现类,持有适配器,,重写接口方法,方法里面根据参数判断,
    能自己处理的就自行处理,否则就交给适配器处理。
 3. 声明多个扩展适配抽象接口。 实现多个扩展适配接口,用于处理不同的数据。 
 4. 声明适配器,适配器要实现原接口,并持有多个扩展适配接口。
 5. 适配器里面声明适配方法,通过方法参数来判断,用哪一个扩展适配实现类来处理数据 
    在适配器重写的接口方法里面,调用适配方法。
 6. 客户端中,声明原接口实现类对象,调用方法,传入不同的参数,根据不同的参数,
    会去判断是自行处理还是交给适配器对象,适配器对象内部也会根据参数判断交给
    那个扩展对象进行处理。

(3)、代码

//原接口
public interface IMediaPlayer {

    //参数为类型和文件
    public void play(String audioType, String fileName);
}

//原接口实现类
public class MediaPlayer implements IMediaPlayer{

    //持有适配器
    private MediaAdapter mediaAdapter;

    @Override
    public void play(String audioType, String fileName) {
        //原接口只能读取mp3格式
        if ("mp3".equalsIgnoreCase(audioType)){
            System.out.println("播放mp3:"+fileName);
        }else {
            //如果是其它的格式,就要用适配器转一下
            mediaAdapter=new MediaAdapter(audioType);
            mediaAdapter.play(audioType,fileName);
        }
    }
}

//适配器
public class MediaAdapter implements IMediaPlayer{

    private AdvancedMediaPlayer advancedMediaPlayer;
    //构造方法里面判断,实例化那个具体的扩展接口实现类
    public MediaAdapter(String audioType) {
        if ("mp4".equalsIgnoreCase(audioType)){
            advancedMediaPlayer=new Mp4Player();
        }
        if ("mp5".equalsIgnoreCase(audioType)){
            advancedMediaPlayer=new Mp5Player();
        }
    }

    @Override
    public void play(String audioType, String fileName) {
        advancedMediaPlayer.play(fileName);
    }
}

//扩展的接口
public interface AdvancedMediaPlayer {

    public void play(String fileName);
}

public class Mp4Player implements AdvancedMediaPlayer{

    @Override
    public void play(String fileName) {
        System.out.println("播放mp4:"+fileName);
    }
}

public class Mp5Player implements AdvancedMediaPlayer{

    @Override
    public void play(String fileName) {
        System.out.println("播放mp5:"+fileName);
    }
}

//适配器模式,一个接口实现类,通过参数类型判断,如果无法处理的类型,就调用扩展接口的方法来实现
//重点在于 原接口实现方法里面通过参数判断,能自己处理的就自己处理,不能处理的就通过适配器方法处理
//适配器里通过构造方法,实例化不同的扩展接口对象,然后在适配器方法里调用不同的接口对象方法。
public class adapterTest {

    public static void main(String[] args) {
        IMediaPlayer mediaPlayer=new MediaPlayer();
        mediaPlayer.play("MP3","MP3音乐");
        mediaPlayer.play("MP4","MP4音乐");
        mediaPlayer.play("MP5","MP5音乐");
    }
}

三、bridge(桥接模式)

(1)、思想

对于两个维度的扩展关系,如果用继承的方式,会产生类爆炸。
比如涂颜料这个功能,可以涂不同的颜色,每种颜色又可以涂成不同的形状。

所以可以把数据抽象成一个抽象类,把行为抽象成一个接口,两个维度分别去扩展。
在抽象类里面持有接口对象,然后通过在客户端用不同的抽象类的继承子类,
构造方法里面传入不同的接口,实现两种维度的组合。

(2)、步骤

 1. 声明抽象类(数据维度),持有接口,构造方法里面将传入的接口对象赋值给成员变量,
    创建一个抽象方法。 
 2. 声明接口(行为维度),创建接口方法。
 3. 声明具体类继承抽象类,重写抽象方法,方法里面调用成员变量
    (通过构造方法传入的接口对象)的方法。
 4. 声明接口实现类,重写接口方法(具体的行为) 在客户端声明不同的抽象子类,
    构造方法里面传入不同的接口实现类,这样就实现了两个维度的结合。

(3)、代码

//抽象类.对数据进行分类,持有抽象接口对象(对行为分类)
public abstract class Color {

    protected DrawAPI drawAPI;
    protected String tag;

    public Color(DrawAPI drawAPI, String tag) {
        this.drawAPI = drawAPI;
        this.tag = tag;
    }

    public abstract void draw(int x,int y);
}

//接口,抽象行为类
public interface DrawAPI {

    public void draw(int x,int y);
}

//抽象数据具体类(对不同的数据分类),比如当前对象是对red的任何形状(根据传入的DrawAPI实现类对象区分)进行操作
public class Red extends Color{

    private int x, y;
    public Red(DrawAPI drawAPI, String tag) {
        super(drawAPI,tag);
    }
    @Override
    public void draw(int x,int y) {
        System.out.println("颜色是"+tag);
        drawAPI.draw(x,y);
    }
}

//抽象接口实现类(行为实现类)
public class DrawCircle implements DrawAPI{

    @Override
    public void draw(int x, int y) {
        System.out.println("Circle,"+x+","+y);
    }
}

//抽象接口实现类(行为实现类)
public class DrawLozenge implements DrawAPI{

    @Override
    public void draw(int x, int y) {
        System.out.println("Lozenge,"+x+","+y);
    }
}

//桥接模式.对于两个维度的扩展有用车,比如画一个形状,可以是圆形和正方形,每种形状都可以是不同的颜色,如果用继承的方式来做
//可能会产生类爆炸,所以就将两个维度拆开,
//抽象类(数据)里面持有接口(行为)对象,然后在抽象子类里面去调用接口方法。
public class test {
    public static void main(String[] args) {
        Color color=new Red(new DrawLozenge(),"RED");
        color.draw(1,8);
    }
}

四、decorator(装饰者模式)

(1)、思想

装饰者类里面通过构造方法,将外部传入的接口对象赋值给装饰者类的成员变量。
装饰者类实现和目标类一样的接口,在重写的接口方法里面调用外部传入的接口对象方法
(实际上就是目标对象方法)。

装饰者模式和代理模式很像,
区别在于装饰者模式是在客户端中通过构造方法将目标
对象传入到装饰者对象里面。
代理模式是在通过jdk反射或者cgilb生成一个代理类,
目标对象和代理对象的逻辑都封装在代理类里面了,客户端是不体现的。

(2)、步骤

 1. 声明接口 
 2. 声明目标类,实现接口,重写接口方法。
 3. 声明装饰者类,通过构造方法持有目标类接口对象,实现和目标类一样的接口。
 4. 在重写的接口方法里面调用目标对象方法。
 5. 在客户端,通过构造方法将目标对象传入装饰者对象。

(3)、代码

public interface IGold {

    public void buyGold();
}

public class Gold implements IGold{

    @Override
    public void buyGold() {
        System.out.println("购买黄金");
    }
}

//装饰者,持有被装饰对象,和被装饰对象实现同一个接口,在接口方法里面调用被装饰者接口方法,然后在调用前后加上自己的逻辑。
public class decorator implements IGold{

    private IGold iGold;

    public decorator(IGold iGold) {
        this.iGold = iGold;
    }

    @Override
    public void buyGold() {
        System.out.println("开始");
        iGold.buyGold();
        System.out.println("结束");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值