本专栏将从基础开始,循序渐进,由浅入深讲解常见的设计模式,希望大家都能够从中有所收获,也请大家多多支持。
专栏地址:设计模式实战
所有代码地址:代码地址
如果文章知识点有错误的地方,请指正!大家一起学习,一起进步。
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();
}
}