【设计模式】适配器模式以及桥接模式(以组合代替继承,把需要桥接的对象放入抽象类中)
时间:2022-12-06 03:30:00
本专栏将从基础开始,循序渐进,从浅到深解释常见的设计模式。我希望每个人都能从中得到一些东西更多的支持。
专栏地址:设计模式实战
所有代码地址:代码地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。
文章目录
- 1 适配器模式
- 2 桥接模式(以组合代替继承,将需要桥接的对象放入抽象类)
1 适配器模式
适配器模式:根据不同类型的实例,使用另一种类型将接口变成不同的类别,使用一种类型进行包装,适应任何类型,然后执行相应的方法。本章通过以下示例演示了适配器模式的使用,UML图如下:
在这个例子中,AdvancedMediaPlayer界面有两个抽象函数,即playVlc()和playMp4。AdvancedMediaPlayer接口有两个实现类VlcPlayer和Mp4Player,VlcPlayer类实现了playVlc函数(),Mp4Player类实现了playMp4()。MediaAdapter类和AudioPlayer类实现了界面MedeiaPlayer的play()函数,MediaAdaper适配器中含有接口AdvancedMediaPlayer对于类的对象,根据不同类型将根据不同类型实例化AdvancedMediaPlayer,在AudioPlayer该类包含适配器对象mediaAdapter,当AudioPlayer调用play适配器将用于方法MediaAdaper适配器根据不同的参数调用不同的实例方法,传递不同的参数。
- MediaPlayer.java
public interface MediaPlayer {
public void play(String audioType, String fileName); }
- AdvancedMediaPlayer.java
public interface AdvancedMediaPlayer {
public void playVlc(String fileName); public void playMp4(String fileName); }
- VlcPlayer.java
public class VlcPlayer implements AdvancedMediaPlayer{
@Override public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: " fileName); } @Override public void playMp4(String fileName) {
//do nothing } }
- Mp4Player.java
public class Mp4Player implements AdvancedMediaPlayer{
@Override public void playVlc(String fileName) {
//do nothing } @Override public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: "+ fileName); } }
- MediaAdapter.java
public class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType){
if(audioType.equalsIgnoreCase("vlc") ){
advancedMusicPlayer = new VlcPlayer();
}else if (audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")){
advancedMusicPlayer.playVlc(fileName);
}
else if(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer.playMp4(fileName);
}
}
}
- AudioPlayer.java
public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
//inbuilt support to play mp3 music files
if(audioType.equalsIgnoreCase("mp3")){
System.out.println("Playing mp3 file. Name: " + fileName);
}
//mediaAdapter is providing support to play other file formats
else if(audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")){
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
}
else{
System.out.println("Invalid media. " + audioType + " format not supported");
}
}
}
- AdapterPatternDemo.java
package com.cgw;
public class AdapterPatternDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "media1.mp3");
audioPlayer.play("mp4", "media2.mp4");
audioPlayer.play("vlc", "media3.vlc");
audioPlayer.play("avi", "media4.avi");
}
}
输出结果:
Playing mp3 file. Name: beyond the horizon.mp3
Playing mp4 file. Name: alone.mp4
Playing vlc file. Name: far far away.vlc
Invalid media. avi format not supported
2 桥接模式(以组合代替继承,把需要桥接的对象放入抽象类中)
public class BridgeTest
{
public static void main(String[] args)
{
Implementor imple=new ConcreteImplementorA();
Abstraction abs=new RefinedAbstraction(imple);
abs.Operation();
}
}
//实现化角色
interface Implementor
{
public void OperationImpl();
}
//具体实现化角色
class ConcreteImplementorA implements Implementor
{
public void OperationImpl()
{
System.out.println("具体实现化(Concrete Implementor)角色被访问" );
}
}
//抽象化角色
abstract class Abstraction
{
protected Implementor imple;
protected Abstraction(Implementor imple)
{
this.imple=imple;
}
public void Operation(){
imple.OperationImpl();
}
}
//扩展抽象化角色
class RefinedAbstraction extends Abstraction
{
protected RefinedAbstraction(Implementor imple)
{
super(imple);
}
public void Operation()
{
System.out.println("扩展抽象化(Refined Abstraction)角色被访问" );
super.Operation();
}
}