结构性-适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式

适配器模式

结构

  1. 目标抽象类(定义目标服务所需要的接口,)
  2. 适配器类(是一个转换器,对目标接口和适配者进行适配)
  3. 适配者类(目标服务需要的业务方法)

简单示例

例:某公司开发一款玩具汽车,玩具汽车支持在移动的过程中同时支持多种灯光闪烁和多种声音提示

// 汽车控制类,充当目标抽象类
public abstract class CarController {
    public void move() {
        System.out.println("玩具车移动!");
    }

    public abstract void phonate();// 发出声音
    public abstract void twinkle();// 灯光闪烁
}
// 警笛类,充当适配者
public class PoliceSound {
    public void alarmSound(){
        System.out.println("发出警笛声音。。。");
    }
}
// 警灯类,充当适配者
public class PoliceLamp {
    public void alarmLamp(){
        System.out.println("呈现警灯闪烁!!!");
    }
}
// 警车适配器,充当适配器
public class PoliceCarAdapter extends CarController {
    private PoliceSound sound;
    private PoliceLamp lamp;

    public PoliceCarAdapter() {
        sound = new PoliceSound();
        lamp = new PoliceLamp();
    }

    @Override
    public void phonate() {
        sound.alarmSound();
    }

    @Override
    public void twinkle() {
        lamp.alarmLamp();
    }
}
// 客户端
public class Client {
    public static void main(String[] args) {
        CarController car;
        car = XMLUntil.getBean();
        car.move();
        car.phonate();
        car.twinkle();
    }
}

定义

将一个类公共相同的方法提取出来,对需要个性化的方法,通过一个适配器连接具体的实现和抽象方法,使得不兼容的接口可以一起工作。

扩展

缺省适配器

缺省适配器是普通适配器模式的变体,当不需要实现一个接口提供的所有方法后,可先设计一个抽象类实现该接口,并且给方法提供默认实现。

双向适配器

基于java可以实现多个的机制,适配器类实现多个目标对象时被称为双向适配器。

桥接模式

结构

  1. 抽象类(抽象类通常和接口联系起来,把两个不同维度的实现联系起来)
  2. 扩充抽象类(扩充抽象类,通常是个具体类,实现了抽象类中的方法,并且调用接口的方法)
  3. 实现类接口(提供另一个维度的基本操作)
  4. 具体实现类(接口的实现)

简单示例

例:要求开发一个支持扩展不同操作系统(windows,linux,unix等)展示不同格式(BMP,JPG,GIF,PNG等)的文件。

// 像素矩阵
public class Matrix {
    // 代码省略
}
// 操作系统操作接口类
public interface ImageImp {
    public void doPaint(Matrix m); // 显示像素矩阵m
}
// 操作系统接口实现类
public class WindowsImpl implements ImageImp {
    @Override
    public void doPaint(Matrix m) {
        System.out.println("windows上显示!");
    }
}
// 操作系统接口实现类
public class LinuxImpl implements ImageImp {
    @Override
    public void doPaint(Matrix m) {
        System.out.println("linux上显示");
    }
}

// 抽象图像类
public abstract class Image {
    protected ImageImp imageImp;

    public void setImageImp(ImageImp imageImp) {
        this.imageImp = imageImp;
    }

    public abstract void parseFile (String fileName);
}
// jpg图像实现类
public class JPGImage extends Image {
    @Override
    public void parseFile(String fileName) {
        Matrix m = new Matrix();
        imageImp.doPaint(m);
        System.out.println(fileName + "  " + "格式为JPG");
    }
}
// bmp图像实现类
public class BMPIMage extends Image {
    @Override
    public void parseFile(String fileName) {
        Matrix m = new Matrix();
        imageImp.doPaint(m);
        System.out.println(fileName + "  " + ",格式为PNG");
    }
}
public class Client {
    public static void main(String[] args) {
        Image image = new JPGImage();
        ImageImp imp = new WindowsImpl();
        image.setImageImp(imp);
        image.parseFile("大美女");
    }
}
windows上显示!
大美女  格式为JPG

定义

将抽象部分与他的实现部分解耦,使得两者都能够独立变化。

扩展

桥接模式和适配器模式

适配器模式多应用于匹配第三方时的接口,特别是第三方为黑盒时,而桥接模式则通过实现或者继承对功能进行水平扩展。

组合模式

结构

  • 抽象构件(可以是接口抽下类,有所有子类的操作和子类的管理操作,如增加子构件等。)
  • 叶子构件 (表示叶子节点,是最下层的节点,实现了所有的子类的业务操作)
  • 容器构件(提供存储叶子构件的能力,实现管理叶子节点的能力,业务操作负责循环实现叶子节点的功能)

简单示例

例:开发一个杀毒软件,可以对某个文件夹杀毒,也可以i去某个文件杀毒,并且可以针对不同的类型的文件提供不同的杀毒方式

// 抽象构件角色
public abstract class AbstactFile {
    public abstract void add(AbstactFile file);
    public abstract void remove(AbstactFile file);
    public abstract AbstactFile getChild(int i);
    public abstract void killVirus();
}
// 容器构件
public class Folder extends AbstactFile {
    private List<AbstactFile> fileList = new ArrayList<AbstactFile>();
    private String name;

    public Folder(String name) {
        this.name = name;
    }

    @Override
    public void add(AbstactFile file) {
        fileList.add(file);
    }

    @Override
    public void remove(AbstactFile file) {
        fileList.remove(file);
    }

    @Override
    public AbstactFile getChild(int i) {
        return fileList.get(i);
    }

    @Override
    public void killVirus() {
        System.out.println("对文件夹" + name + "进行杀毒");

        for (AbstactFile file : fileList) {
            file.killVirus();
        }
    }
}

// 叶子构件
public class ImageFile extends AbstactFile {
    private String name;

    public ImageFile(String name) {
        this.name = name;
    }

    @Override
    public void add(AbstactFile file) {
        System.out.println("不支持该方法");
    }

    @Override
    public void remove(AbstactFile file) {
        System.out.println("不支持该方法");
    }

    @Override
    public AbstactFile getChild(int i) {
        return null;
    }

    @Override
    public void killVirus() {
        System.out.println("对图像文件" + name + "进行杀毒");
    }
}
// 叶子构件
public class TextFile extends AbstactFile {
    private String name;

    public TextFile(String name) {
        this.name = name;
    }

    @Override
    public void add(AbstactFile file) {
        System.out.println("不支持该方法");
    }

    @Override
    public void remove(AbstactFile file) {
        System.out.println("不支持该方法");
    }

    @Override
    public AbstactFile getChild(int i) {
        return null;
    }

    @Override
    public void killVirus() {
        System.out.println("对文本文件" + name + "进行杀毒");
    }
}

定义

组合模式:组合多个对象形成树状结构以表示具有部分-整体关系的层次结构,组合模式让客户端可以统一对待单个对象和组合对象

装饰模式

结构

  • 抽象构件(他是具体构件和装饰构件共同的父类,声明了在具体构件中实现的业务方法)
  • 具体构件(抽象构件类的子类,基本业务方法的实现)
  • 抽象装饰类 (抽象构件的子类,给具体构件增加职责,维护了一个指向抽象构件的引用,通过该引用可以调用之前具体构件对象的方法,通过扩展,达到装饰的目的)
  • 具体装饰类(抽象装饰类的子类,负责装饰具体构件的业务实现。)

简单示例

例:有一套图形界面构件库的开发需求,要求对不同构件可以显示不同的效果,比如代黑色边框的文本框,带滚动条的窗体。

// 抽象构件类
public abstract class Component {
    public abstract void display();
}
// 具体构件类
public class TextBox extends Component {
    @Override
    public void display() {
        System.out.println("显示文本框");
    }
}
// 具体构件类
public class Window extends Component {
    @Override
    public void display() {
        System.out.println("显示窗体");
    }
}
// 构件装饰类,充当抽象就装饰类
public class ComponentDecorator extends Component {
    private Component component;

    public ComponentDecorator(Component component) {
        this.component = component;
    }

    @Override
    public void display() {
        component.display();
    }
}

// 滚动条装饰类
public class ScorllBarDecorator extends ComponentDecorator{
    public ScorllBarDecorator(Component component) {
        super(component);
    }

    @Override
    public void display() {
        this.setScorllBar();
        super.display();
    }
    public void setScorllBar() {
        System.out.println("为构件增加滚动条");
    }
}

定义

动态的给一个对象增加额外的职责,就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案

外观模式

结构

  • 外观角色:负责整合内部功能,对外只提供一个接口,然后委派给对应的子系统
  • 子系统角色:具体处理业务的子系统

简单示例

例:实现一个可应用于多个软件的文件加密模块,该模块可以对文件中的数据进行加密并将加密后的数据存在一个新的文件中,具体的流程包括读取源文件,加密,保存加密之后的文件。三个操作相互独立

// 文件读取类
public class FileReader {
    public String read(String fileName){
        System.out.println("读取文件,获取明文:");
        StringBuffer sb = new StringBuffer();
        try {
            FileInputStream inFS = new FileInputStream(fileName);
            int data;
            while ((data = inFS.read()) != -1){
                sb = sb.append(data);
            }
            inFS.close();
            System.out.println(sb.toString());
        } catch (FileNotFoundException e) {
            System.out.println("文件不存在。");
        } catch (IOException e) {
            System.out.println("文件读取错误。");
        }
        return sb.toString();
    }
}
// 文件加密类
public class CiperMachine {
    public String encrypt(String plainText) {
        System.out.println("数据加密,将明文转换为密文。");
        String es = "";
        for (int i = 0; i < plainText.length(); i++) {
            String c = String.valueOf(plainText.charAt(i) % 7);
            es += c;
        }
        System.out.println(es);
        return es;
    }
}

// 文件写入类
public class FileWrite {
    public void write(String encryptStr, String fileNameDes) {
        System.out.println("保存密文,写入文件。");
        try {
            FileOutputStream outFS = new FileOutputStream(fileNameDes);
            outFS.write(encryptStr.getBytes());
            outFS.close();
        } catch (FileNotFoundException e) {
            System.out.println("文件不存在。");
        } catch (IOException e) {
            System.out.println("文件写入错误");
        }
    }
}
// 外观类
public class EncryptFacade {
    private FileReader fileReader;
    private CiperMachine ciperMachine;
    private FileWrite fileWrite;
    public EncryptFacade() {
        fileReader = new FileReader();
        ciperMachine = new CiperMachine();
        fileWrite = new FileWrite();
    }

    public void fileEncrypt(String fileNameSrc, String fileNameDes) {
        String plainStr = fileReader.read(fileNameSrc);
        String encryptStr = ciperMachine.encrypt(plainStr);
        fileWrite.write(encryptStr, fileNameDes);
    }
}

定义

为子系统中的一组接口提供一个统一的入口,外观模式定义了一个高层接口,这个接口使得这一个子系统更加容易使用。

享元模式

结构

  • 抽象享元类: 通常是一个接口或者抽象类,声明被具体对象共享的公共属性和方法
  • 具体享元类: 实现了抽象享元类,其实例称为享元对象,在具体享元类中为内部状态提供了存储空间,通常会结合单例模式。
  • 非共享具体享元类:并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类。
  • 享元工厂类:创建并管理享元对象。

简单示例

例:围棋除了颜色和位置之外,其他的都相同,如果每个棋子都搞一个独立的对象放在内容中,比较浪费。

// 表示棋子位置
public abstract class IgoChessman {
    public abstract String getColor();
    public void display(Coordinates coordinates) {
        System.out.println("棋子颜色:" + this.getColor() + "棋子位置:"+coordinates.toString());
    }
}
// 围棋棋子类,充当抽象享元类
public abstract class IgoChessman {
    public void display(Coordinates coordinates) {
        System.out.println("棋子颜色:" + this.getColor() + "棋子位置:"+coordinates.toString());
    }
}
// 黑色棋子类,充当具体享元类
public class BlackIgoChessman extends IgoChessman {
    @Override
    public String getColor() {
        return "黑色";
    }
}
// 白色棋子类,充当具体享元类
public class WhiteIgoChessman extends IgoChessman {
    @Override
    public String getColor() {
        return "白色";
    }
}
// 棋子工厂类,充当享元工厂类。
public class IgoChessmanFactory {
    private static IgoChessmanFactory instance = new IgoChessmanFactory();
    private static Hashtable ht;
    private IgoChessmanFactory() {
        ht = new Hashtable();
        IgoChessman black,white;
        black = new BlackIgoChessman();
        ht.put("b",black);
        white = new WhiteIgoChessman();
        ht.put("w", white);
    }

    //返回享元工行类的唯一实例
    public static IgoChessmanFactory getInstance() {
        return instance;
    }

    //通过key获取存储在HashTable中的享元对象
    public static IgoChessman getIgoChessman(String color) {
        return (IgoChessman) ht.get(color);
    }
}

定义

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值