结构型模式一、装饰模式以及享元模式、代理模式、外观模式、组合模式

装饰模式

在这里插入图片描述

把原本的对象传进来,增加新的功能。而不是通过子类的方式,也可以装饰套装饰。

装饰模式又叫做包装模式,通常一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

装饰模式的结构

在这里插入图片描述

装饰模式的角色和职责

在这里插入图片描述

非装饰模式,通过子类添加功能

interface Car
{
    public void show();
}

class RunCar implements Car
{
    @Override
    public void show() {
        this.run();
    }
    public void run()
    {
        System.out.println("可以跑");
    }
}

class SwimCar implements Car{
    @Override
    public void show() {
        this.run();
        this.swim();
    }
    public void run()
    {
        System.out.println("可以跑");
    }

    public void swim()
    {
        System.out.println("可以游");
    }

}

class FlyCar implements Car
{
    public void fly()
    {
        System.out.println("可以飞");
    }
    @Override
    public void show() {
        this.run();
        this.fly();
    }
    public void run()
    {
        System.out.println("可以跑");
    }
}

public class MainClass
{
    public static void main(String[] args) {
        Car car = new FlyCar();
        car.show();
    }
}


输出

可以跑
可以飞

通过装饰模式

interface Car
{
    public abstract void show();
    public abstract void run();
}

class RunCar implements Car{
    @Override
    public void show()
    {
        this.run();
    }
    public void run()
    {
        System.out.println("可以跑");
    }
}

abstract class CarDecorator implements Car
{
    private Car car;

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    public CarDecorator(Car car) {
        this.car = car;
    }

    public abstract void show();
}

class FlyCarDecorator extends CarDecorator
{

    public FlyCarDecorator(Car car) {
        super(car);
    }

    @Override
    public void show() {
        this.getCar().show();
        this.fly();
    }

    @Override
    public void run() {

    }


    public void fly()
    {
        System.out.println("可以飞");
    }
}

class SwimCarDecorator extends CarDecorator
{


    public SwimCarDecorator(Car car) {
        super(car);
    }

    @Override
    public void show()
    {
        this.getCar().show();
        this.swim();
    }

    public void swim()
    {
        System.out.println("可以游");
    }

    @Override
    public void run()
    {

    }
}
public class MainClass
{
    public static void main(String[] args) {
        Car car = new RunCar();
        CarDecorator carDecorator = new FlyCarDecorator(car);
        car = new SwimCarDecorator(carDecorator);
        car.show();

    }
}

输出

可以跑
可以飞
可以游

如果想要又可以跑,又可以游,只需要在跑的外面装饰游,或者游的外面装饰跑。而不需要创建新的类。

享元模式

结构型模式的一种,它通过与其他对象共享数据来减小内存占用。

享元模式的结构

在这里插入图片描述在这里插入图片描述

代码

//享元角色
class MyCharacter
{
    private char myChar;

    public MyCharacter(char myChar) {
        this.myChar = myChar;
    }

    public void disPlay()
    {
        System.out.println(myChar);
    }
}

//享元工厂角色
class MyCharacterFactory
{
    private Map<Character,MyCharacter> pool;

    public MyCharacterFactory() {
        this.pool = new HashMap<Character, MyCharacter>();
    }

    public MyCharacter getMyCharacter(Character character)
    {
        MyCharacter myChar = pool.get(character);
        if(myChar == null)
        {
            myChar = new MyCharacter(character);
            pool.put(character,myChar);
        }
        return myChar;
    }

}

public class MainClass
{
    public static void main(String[] args)
    {
//        MyCharacter myCharacter = new MyCharacter('a');
//        MyCharacter myCharacter1 = new MyCharacter('b');
//        MyCharacter myCharacter2 = new MyCharacter('a');
//        MyCharacter myCharacter3 = new MyCharacter('d');
//
//        myCharacter.disPlay();
//        myCharacter1.disPlay();
//        myCharacter2.disPlay();
//        myCharacter3.disPlay();
//        System.out.println(myCharacter==myCharacter2);//false

        MyCharacterFactory myCharacterFactory = new MyCharacterFactory();
        MyCharacter myCharacter = myCharacterFactory.getMyCharacter('a');
        MyCharacter myCharacter1 = myCharacterFactory.getMyCharacter('b');
        MyCharacter myCharacter2 = myCharacterFactory.getMyCharacter('a');
        MyCharacter myCharacter3 = myCharacterFactory.getMyCharacter('b');
        myCharacter.disPlay();
        myCharacter1.disPlay();
        myCharacter2.disPlay();
        myCharacter3.disPlay();
        System.out.println(myCharacter==myCharacter2); //true
        System.out.println(myCharacter1==myCharacter3); //true



    }
}

代理模式

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

介绍

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

  • 主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

  • 何时使用:想在访问一个类时做一些控制。

  • 如何解决:增加中间层。

  • 关键代码:实现与被代理类组合。

实现

我们将创建一个 Image 接口和实现了 Image 接口的实体类。ProxyImage 是一个代理类,减少 RealImage 对象加载的内存占用。

ProxyPatternDemo,我们的演示类使用 ProxyImage 来获取要加载的 Image 对象,并按照需求进行显示。

在这里插入图片描述

interface Image {
   void display();
}

class RealImage implements Image 
{
 
   private String fileName;
 
   public RealImage(String fileName){
      this.fileName = fileName;
      loadFromDisk(fileName);
   }
 
   @Override
   public void display() {
      System.out.println("Displaying " + fileName);
   }
 
   private void loadFromDisk(String fileName){
      System.out.println("Loading " + fileName);
   }
}

class ProxyImage implements Image{
 
   private RealImage realImage;
   private String fileName;
 
   public ProxyImage(String fileName){
      this.fileName = fileName;
   }
 
   @Override
   public void display() {
      if(realImage == null){
         realImage = new RealImage(fileName);
      }
      realImage.display();
   }
}


public class ProxyPatternDemo {
   
   public static void main(String[] args) {
      Image image = new ProxyImage("test_10mb.jpg");
 
      // 图像将从磁盘加载
      image.display(); 
      System.out.println("");
      // 图像不需要从磁盘加载
      image.display();  
   }
}

执行程序,输出结果:

Loading test_10mb.jpg
Displaying test_10mb.jpg

Displaying test_10mb.jpg

外观模式

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

介绍

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

  • 主要解决:降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口。

  • 何时使用: 1、客户端不需要知道系统内部的复杂联系,整个系统只需提供一个"接待员"即可。 2、定义系统的入口。

  • 如何解决:客户端不与系统耦合,外观类与系统耦合。

  • 关键代码:在客户端和复杂系统之间再加一层,这一层将调用顺序、依赖关系等处理好。

  • 应用实例: 1、去医院看病,可能要去挂号、门诊、划价、取药,让患者或患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便。 2、JAVA 的三层开发模式。

  • 优点: 1、减少系统相互依赖。 2、提高灵活性。 3、提高了安全性。

  • 缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。

外观模式结构

在这里插入图片描述

代码

class SystemA
{
    public void doSomething()
    {
        System.out.println("实现A系统功能");
    }
}

class SystemB
{
    public void doSomething()
    {
        System.out.println("实现B系统功能");
    }
}

class SystemC
{
    public void doSomething()
    {
        System.out.println("实现C系统功能");
    }
}

class Facade
{
    private SystemA systemA;
    private SystemB systemB;
    private SystemC systemC;
    public Facade()
    {
        systemA = new SystemA();
        systemB = new SystemB();
        systemC = new SystemC();
    }

    public void doSomethingA()
    {
        systemA.doSomething();
    }
    public void doSomethingB()
    {
        systemB.doSomething();
    }
    public void doSomethingC()
    {
        systemC.doSomething();
    }

}

public class MainClass
{
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.doSomethingA();
    }
}

组合模式

通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个树。

组合模式依据树形结构来组合对象,用来表示部分以及整体层次

组合模式结构

在这里插入图片描述在这里插入图片描述


/**
 * 文件和目录的父类
 */
interface IFile
{
    //显示文件或者文件夹的名称
    public void display();

    //添加
    public boolean add(IFile file);

    //移除
    public boolean remove(IFile file);

    //获得子节点
    public List<IFile> getChild();

}

/**
 * 目录
 */
class Folder implements IFile
{
    String name;
    private List<IFile> children;


    public Folder(String name) {
        this.name = name;
        children = new ArrayList<>();
    }

    @Override
    public void display() {
        System.out.println(name);
    }

    @Override
    public boolean add(IFile file) {
        return children.add(file);
    }

    @Override
    public boolean remove(IFile file) {
        return children.remove(file);
    }

    @Override
    public List<IFile> getChild() {
        return  children;
    }
}


//文件,相当于叶子节点
class File implements IFile
{
    private String name;
    public File(String name)
    {
        this.name = name;
    }

    @Override
    public void display() {
        System.out.println(name);
    }

    @Override
    public boolean add(IFile file) {
        return false;
    }

    @Override
    public boolean remove(IFile file) {
        return false;
    }

    @Override
    public List<IFile> getChild() {
        return null;
    }
}

public class MainClass
{
    public static void main(String[] args)
    {
        //C盘
        Folder rootFolder = new Folder("C:");

        //beifeng目录
        Folder beifengFolder = new Folder("beifeng");

        //文件
        File file = new File("beifeng.txt");
        rootFolder.add(beifengFolder);
        rootFolder.add(file);
        displayTree(rootFolder);
    }
    public static void displayTree(IFile rootFolder)
    {
        //显示自身名称
        rootFolder.display();
        //获得子树
        List<IFile> child = rootFolder.getChild();

        for(IFile file:child)
        {
            if(file instanceof File)
                file.display();
            else
                displayTree(file);
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值