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



    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();
        }
    }
    







  • 相关阅读:
    sqlalchemy
    nginx配置文件,做多个项目代理
    pyspider
    Mysql原理+ 多实例 +表损坏
    Spring 学习-AOP
    java 基础 --- 动态代理和静态代理
    Spring 学习-IoC
    [转]字符编码笔记:ASCII,Unicode 和 UTF-8
    JVM(五) class类文件的结构
    数据结构(四)--- 红黑树(RedBlock-Tree)
  • 原文地址:https://www.cnblogs.com/huangzhe1515023110/p/9276107.html
Copyright © 2020-2023  润新知