10装饰与外观模式代码实现

发布时间 2023-04-24 21:19:43作者: vbig

装饰模式代码实现

  • 使用装饰模式设计实现计算费用的功能系统。

实例说明:某咖啡店在卖咖啡时可以根据顾客的要求在其中加入各种配料,咖啡店会根据所加入的配料来计算总费用。现使用装饰模式为该咖啡店设计一个程序以实现计算费用的功能,输出每种饮料的详细描述及花费。

  1. 类图:

Pasted image 20230329092952

  1. 源代码:
  • Beverage
package com.fish.pattern.decorator;  
  
// 抽象组件  
public abstract class Beverage {  
    public abstract String getDescription();  
    public abstract double getCost();  
}
  • CondimentDecorator
package com.fish.pattern.decorator;  
  
public abstract class CondimentDecorator extends Beverage{  
    private Beverage beverage;  
    public CondimentDecorator(Beverage beverage) {  
        this.beverage = beverage;  
    }  
    @Override  
    public String getDescription() {  
        return beverage.getDescription();  
    }  
    @Override  
    public double getCost() {  
        return beverage.getCost();  
    }  
}
  • Espresso
package com.fish.pattern.decorator;  
  
// 具体组件  
public class Espresso extends Beverage {  
    @Override  
    public String getDescription() {  
        return "Espresso 咖啡";  
    }  
    @Override  
    public double getCost() {  
        return 25.00;  
    }  
}
  • HouseBlend
package com.fish.pattern.decorator;  
  
// 具体组件  
public class HouseBlend extends Beverage {  
  
    @Override  
    public String getDescription() {  
        return "HouseBlend 咖啡";  
    }  
    @Override  
    public double getCost() {  
        return 30.00;  
    }  
}
  • Milk
package com.fish.pattern.decorator;  
  
// 具体装饰类  
public class Milk extends CondimentDecorator {  
    public Milk(Beverage beverage) {  
        super(beverage);  
    }  
    @Override  
    public String getDescription() {  
        String decription = super.getDescription();  
        return decription + "加牛奶";  
    }  
    @Override  
    public double getCost() {  
        double cost = super.getCost();  
        return cost + 6.0;  
    }  
}
  • Mocha
package com.fish.pattern.decorator;  
  
// 具体装饰类  
class Mocha extends CondimentDecorator {  
    public Mocha(Beverage beverage) {  
        super(beverage);  
    }  
    @Override  
    public String getDescription() {  
        String decription = super.getDescription();  
        return decription + "加摩卡";  
    }  
    @Override  
    public double getCost() {  
        double cost = super.getCost();  
        return cost + 10.0;  
    }  
}
  • StarBuzzCoffee
package com.fish.pattern.decorator;  
  
// 客户端测试类  
public class StarBuzzCoffee {  
    public static void main(String args[]) {  
        String decription;  
        double cost;  
        Beverage beverage;  
        beverage = new Espresso();  
        decription = beverage.getDescription();  
        cost = beverage.getCost();  
        System.out.println("饮料:" + decription);  
        System.out.println("价格:" + cost);  
        System.out.println("---------------------");  
  
        Beverage beverage_m;  
        beverage_m = new Milk(beverage);  
        decription = beverage_m.getDescription();  
        cost = beverage_m.getCost();  
        System.out.println("饮料:" + decription);  
        System.out.println("价格:" + cost);  
        System.out.println("---------------------");  
  
        Beverage beverage_mo;  
        beverage_mo = new Mocha(beverage_m);  
        decription = beverage_mo.getDescription();  
        cost = beverage_mo.getCost();  
        System.out.println("饮料:" + decription);  
        System.out.println("价格:" + cost);  
        System.out.println("---------------------");  
  
    }  
}
  1. 运行结果:

Pasted image 20230329094050

外观模式代码实现

  • 使用外观模式设计程序实现遥控器统一对这些子模块的控制。

实例说明:电视遥控器是现实生活中一个比较好的外观模式的运用,遥控器可以控制电源的开源、声音的调整、频道的切换等。这个遥控器就是我们这里说的外观或者门面,而电源、声音、频道切换系统就是我们的子系统,遥控器统一对这些子模块的控制。请使用外观模式设计程序实现遥控器统一对这些子模块的控制,并绘制其类图。

  1. 类图:

Pasted image 20230329101330

  1. 源代码:
  • Channl
package com.fish.pattern.facade.first;  
  
//频道切换  
public class Channl {  
    public void channlDown(){  
        System.out.println("下一个频道");  
    }  
  
    public void channlUp(){  
        System.out.println("上一个频道");  
    }  
}
  • Client
package com.fish.pattern.facade.first;  
  
public class Client {  
    public static void main(String[] args) {  
        TVcontroller tVcontroller=new TVcontroller();  
        tVcontroller.channlDOWN();  
        tVcontroller.channlUP();  
        tVcontroller.powerOFF();  
        tVcontroller.powerON();  
        tVcontroller.soundUP();  
        tVcontroller.soundDOWN();  
    }  
}
  • Power
package com.fish.pattern.facade.first;  
  
//电源开关  
public class Power {  
    public void powerOff(){  
        System.out.println("关闭电源");  
    }  
  
    public void powerOn(){  
        System.out.println("打开电源");  
    }  
}
  • Sound
package com.fish.pattern.facade.first;  
  
public class Sound {  
    public void soundUp(){  
        System.out.println("调大声音");  
    }  
  
    public void soundDown(){  
        System.out.println("调小声音");  
    }  
}
  • TVcontroller
package com.fish.pattern.facade.first;  
  
public class TVcontroller {  
    private Power power= new Power();  
    private Sound sound= new Sound();  
    private Channl channl= new Channl();  
  
    public void powerOFF(){  
        power.powerOff();  
    }  
  
    public void powerON(){  
        power.powerOn();  
    }  
  
    public void soundUP(){  
        sound.soundUp();  
    }  
  
    public void soundDOWN(){  
        sound.soundDown();  
    }  
  
    public void channlUP(){  
        channl.channlUp();  
    }  
  
    public void channlDOWN(){  
        channl.channlDown();  
    }  
  
}
  1. 运行结果:

Pasted image 20230329101337

  • 用外观模式设计文件加密模块。

实例说明:某软件公司要开发一个可应用于多个软件的文件加密模块,该模块可以对文件中的数据进行加密并将加密之后的数据存储在一个新文件中,具体的流程包括3个部分,分别是读取源文件、加密、保存加密之后的文件,其中,读取文件和保存文件使用流来实现,加密操作通过求模运算实现。这3个操作相对独立,为了实现代码的独立重用,让设计更符合单一职责原则,这3个操作的业务代码封装在3个不同的类中。现使用外观模式设计该文件加密模块。

  1. 类图:

Pasted image 20230329114142

  1. 源代码:
  • CipherMachine
package com.fish.pattern.facade.second;  
  
public class CipherMachine {  
    public String encrypt(String plainText){  
        System.out.print("数据加密,将明文转换为密文:");  
        String es = "";  
        for (int i = 0; i <plainText.length() ; i++) {  
            String s = String.valueOf(plainText.charAt(i) % 7);  
            es+=s;  
        }  
        System.out.println(es);  
        return es;  
    }  
}
  • Client
package com.fish.pattern.facade.second;  
  
public class Client {  
    public static void main(String[] args) {  
        EncryptFacade ef = new EncryptFacade();  
        ef.fileEncrypt("src\\main\\java\\com\\fish\\pattern\\facade\\second\\src.txt",  
                "src\\main\\java\\com\\fish\\pattern\\facade\\second\\des.txt");  
    }  
}
  • EncryptFacade
package com.fish.pattern.facade.second;  
  
public class EncryptFacade {  
    //维持对子系统对象的引用  
    private FileReader reader;  
    private CipherMachine cipher;  
    private FileWriter writer;  
  
    public EncryptFacade() {  
        reader = new FileReader();  
        cipher = new CipherMachine();  
        writer = new FileWriter();  
    }  
    //调用子系统对象的业务方法  
    public void fileEncrypt(String fileNameSrc,String fileNameDes){  
        String plainStr = reader.read(fileNameSrc);  
        String encryptStr = cipher.encrypt(plainStr);  
        writer.write(encryptStr,fileNameDes);  
    }  
}
  • FileReader
package com.fish.pattern.facade.second;  
  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
  
public class FileReader {  
    public String read(String fileNameSrc){  
        System.out.println("读取文件,获取明文:");  
        StringBuffer sb = new StringBuffer();  
  
        try {  
            FileInputStream inFS = new FileInputStream(fileNameSrc);  
            int data;  
            while ((data=inFS.read())!=-1){  
                sb = sb.append((char) data);  
            }  
            inFS.close();  
            System.out.println(sb.toString());  
        } catch (FileNotFoundException e) {  
            System.out.println("文件不存在!");  
        } catch (IOException e) {  
            System.out.println("文件操作错误!");  
        }  
        return sb.toString();  
    }  
}
  • FileWriter
package com.fish.pattern.facade.second;  
  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
  
public class FileWriter {  
    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("文件操作错误!");  
        }  
  
    }  
}
  1. 运行结果:

Pasted image 20230329114146