设计模式(三)——结构型模式


1、适配器模式

两个不兼容接口间的桥梁,使得那些原本由于接口不兼容不能一起工作的那些类可以一起工作。将一个接口转换成客户希望的另一个接口。属于结构型模式。


播放器和高级播放器接口

public interface MediaPlayer {
    public void play(String audioType,String fileName);
}
public interface AdvancedMediaPlayer {
    public void playVlc(String fileName);
    public void playMP4(String fileName);
}

实现高级播放器

public class VlcPlayer implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file: "+fileName);
    }

    @Override
    public void playMP4(String fileName) {
        //System.out.println();
    }
}
public class Mp4Player implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        //
    }

    @Override
    public void playMP4(String fileName) {
        System.out.println("Playing MP4 file: "+fileName);
    }
}

创建实现了播放器接口的适配器类

public class MediaAdapter implements MediaPlayer {
    AdvancedMediaPlayer advancedMediaPlayer;

    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")){
            advancedMediaPlayer = new VlcPlayer();
        }else if (audioType.equalsIgnoreCase("mp4")){
            advancedMediaPlayer = new Mp4Player();
        }
    }

    @Override
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("vld")){
            advancedMediaPlayer.playVlc(fileName);
        }else if (audioType.equalsIgnoreCase("mp4")){
            advancedMediaPlayer.playMP4(fileName);
        }
    }
}

实现类播放器接口的实体类

public class AudioPlayer implements MediaPlayer {
    MediaAdapter mediaAdapter;
    @Override
    public void play(String audioType, String fileName) {
        //播放mp3音乐文件的内置支持
        if (audioType.equalsIgnoreCase("mp3")){
            System.out.println("Playing mp3 file: "+fileName);
        }
        //MediaAdapter提供了播放其他文件格式的支持
        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");
        }
    }
}

使用MediaPlayer

public class Main {
    public static void main(String[] args) {
        AudioPlayer audioPlayer  = new AudioPlayer();
        audioPlayer.play("mp3","哈哈");
        audioPlayer.play("mp4","冰雪大冒险");
        audioPlayer.play("vlc","mind me.");
    }
}

2、桥接模式

用于把抽象化和实现化解耦,使得二者可以独立变化。

创建桥接实现接口

public interface DrawAPI {
    public void drawCircle(int radius,int x,int y);
}

实现桥接接口的实现类

public class RedCircle implements DrawAPI {
    @Override
    public void drawCircle(int radius, int x, int y) {
        System.out.println("Drawing circle: [color:red ,radius: "+radius+" ,x: "+x+" ,y: "+y+" ]");
    }
}
public class GreenCircle implements DrawAPI{
    @Override
    public void drawCircle(int radius, int x, int y) {
        System.out.println("Drawing circle: [color:green ,radius: "+radius+" ,x: "+x+" ,y: "+y+" ]");
    }
}

使用桥接接口创建抽象类Shape

public abstract class Shape {
    DrawAPI drawAPI;

    public Shape(DrawAPI drawAPI) {
        this.drawAPI = drawAPI;
    }

    public abstract void draw();
}

创建Shape的实现类

public class Circle extends Shape {
    private int x,y,radius;

    public Circle(DrawAPI drawAPI, int x, int y, int radius) {
        super(drawAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    @Override
    public void draw() {
        drawAPI.drawCircle(x,y,radius);
    }
}

使用Shape和DrawAPI画出不同颜色的圆

public class Main {
    public static void main(String[] args) {
        Shape redCircle = new Circle(new RedCircle(),100,100,10);
        Shape greenCircle = new Circle(new GreenCircle(),100,100,10);

        redCircle.draw();
        greenCircle.draw();
    }
}

3、装饰模式

允许向一个现有的对象添加一个新的功能,同时又不改变其结构。

接口以及实现类

public interface Shape {
    public void draw();
}
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape: Rectangle");
    }
}
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape: Circle");
    }
}

创建实现了Shape接口的抽象装饰类

public abstract class ShapeDecorator implements Shape {
    protected Shape shape;

    public ShapeDecorator(Shape shape) {
        this.shape = shape;
    }

    @Override
    public void draw() {
        shape.draw();
    }
}

扩展了ShapeDecorator的实体装饰类

public class RedShapeDecorator extends ShapeDecorator {
    public RedShapeDecorator(Shape shape) {
        super(shape);
    }
    
    @Override
    public void draw(){
        shape.draw();
        setRedBorder(shape);
    }
    public void setRedBorder(Shape shape){
        System.out.println("Border color : Red");
    }

}

使用RedShapeDecorator 来装饰Shape对象

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle();
        Shape redCircle = new RedShapeDecorator(new Circle());
        Shape redRectangle = new RedShapeDecorator(new Rectangle());

        System.out.println("Circle with normal border.");
        circle.draw();
        System.out.println("Circle with red border.");
        redCircle.draw();
        System.out.println("Rectangle of red border");
        redRectangle.draw();
    }

}

4、外观模式

隐藏系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种属于结构型模式,为子系统中的一组接口提供了一个一只界面,外观模式提供了一个高层接口,使得这一子系统更加容易使用。

创建一个接口以及其实现类

public interface Shape {
    void draw();
}
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Rectangle::draw()");
    }
}
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Circle::draw()");
    }
}
public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Square::draw()");
    }
}

创建一个外观类

public class ShapeMaker {
    private Shape circle;
    private Shape rectangle;
    private Shape square;

    public ShapeMaker() {
        circle = new Circle();
        rectangle =new Rectangle();
        square =new Square();
    }
    public void drawCircle(){
        circle.draw();
    }
    public void drawRectangle(){
        rectangle.draw();
    }
    public void drawSquare(){
        square.draw();
    }
}

使用外观类画出各种形状

public class Main {
    public static void main(String[] args) {
        ShapeMaker shapeMaker = new ShapeMaker();
        shapeMaker.drawCircle();
        shapeMaker.drawRectangle();
        shapeMaker.drawSquare();
    }
}

5、享元模式

主要用于减少创建对象的数量,以减少内存占用和提高性能。属于结构型模式。

运用共享技术有效的支持大量细粒度的对象。

创建接口以及实现类

public interface Shape {
    void draw();
}
public class Circle implements Shape {
    private String color;
    private int x;
    private int y;
    private int radius;

    public Circle(String color) {
        this.color = color;
    }

    public void setX(int x) {
        this.x = x;
    }

    public void setY(int y) {
        this.y = y;
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

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

创建一个工厂,生成给定信息的实体类的对象

public class ShapeFactory {
    private static final HashMap<String ,Shape> circleMap = new HashMap<String, Shape>();

    public static HashMap<String, Shape> getCircleMap(String color) {
        Circle circle = (Circle) circleMap.get(color);
        if(circle == null){
            circle = new Circle(color);
            circleMap.put(color,circle);
            System.out.println("Creating circle of color: "+color);
        }
        return circleMap;
    }
}

使用工厂通过传递颜色信息来获取实体类对象

public class Main {
    private static final String[] colors =new String[]{
            "Red","Green","Blue","White","Black"
    };

    public static void main(String[] args) {

        for (int i = 0; i < 20; i++) {
            Circle circle = (Circle) ShapeFactory.getCircle(getRandomColor());
            circle.setX(getRandomX());
            circle.setY(getRandomY());
            circle.setRadius(100);
            circle.draw();
        }
    }


    public static String  getRandomColor(){
        return colors[(int) (Math.random()*colors.length)];
    }
    public static int getRandomX(){
        return (int) (Math.random()*100);
    }
    public static int getRandomY(){
        return (int) (Math.random()*100);
    }
}

6、代理模式

在代理模式中,一个类代表另一个。属于结构型模式。

为其他对象提供一种代理以控制对这个对象的访问。


创建接口和实现接口的实体类

public interface Image {
    void display();
}
public class RealImage implements Image {
    private String fileName;

    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFromDisk(fileName);
    }

    private void loadFromDisk(String fileName) {
        System.out.println("Loading :"+fileName);
    }

    @Override
    public void display() {
        System.out.println("Displaying: "+fileName);
    }
}
public class ProxyImage implements Image {
    private String fileName;
    private RealImage realImage;

    public ProxyImage(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void display() {
        if (realImage == null){
            realImage = new RealImage(fileName);
        }
        realImage.display();
    }
}

被请求时,使用ProxyImage来获取RealImage对象

public class Main {
    public static void main(String[] args) {
        Image image = new ProxyImage("s.jpg");
        //图像从磁盘加载
        image.display();
        System.out.println("");
        //图像将无法从磁盘加载
        image.display();
    }
}







原文地址:https://www.cnblogs.com/huangzhe1515023110/p/9276107.html