装饰模式的应用——论坛屏蔽不雅言论

装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。

介绍

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

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

何时使用: 在不想增加很多子类的情况下扩展类。

如何解决: 将具体功能职责划分,同时继承装饰者模式。

关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。

应用实例: 1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

优点: 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点: 多层装饰比较复杂。

使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。

注意事项: 可代替继承。

菜鸟教程——装饰器模式

应用示例

在论坛中为了防止用户发表不雅言论,常常需要将某些敏感词汇屏蔽。假设某论坛是将发帖内容保存在磁盘文件中,请利用装饰模式的概念编写一个过滤流类ReplaceWriter,使用该类的Write字符串系列方法会将敏感词汇用“*”替换掉。需要替换的敏感词汇保存在文件badwords.txt中。请按实验的要求提交实验报告和项目实现的源代码。(提示:参考FilterWriter)

类图设计

在这里插入图片描述

设计方案

  • 首先定义一个接口Writer,有一个write()方法,返回类型为String
  • 创建实现接口的实体类ForumWriter,重写write()方法,用以读取txt文件中的论坛内容并return。
  • 创建实体装饰类ReplaceWriter,包含一个ForumWriter的对象,重写write()方法,调用ForumWriter的对象获取论坛内容并返回String,ReplaceWriter调用自身的方法对敏感词汇进行处理后输出。

代码实现

Writer.java

package decorator;
/** 
* @author 作者 Long: 
* @version 创建时间:2022年5月11日 上午10:36:30 
*/
public interface Writer {
	String write(String filepath);
}

ForumWriter.java

package decorator;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * @author 作者 Long:
 * @version 创建时间:2022年5月11日 上午10:36:59
 */
public class ForumWriter implements Writer {

	@Override
	public String write(String filepath) {
		String ans = "";
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(filepath));
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		String strLine;
		try {
			while (br.ready()) {
				strLine = br.readLine();
				ans += strLine;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return ans;
	}

}

ReplaceWriter.java

package decorator;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @author 作者 Long:
 * @version 创建时间:2022年5月11日 上午10:44:00
 */
public class ReplaceWriter implements Writer {
	protected ForumWriter forumWriter;
	private ArrayList<String> sensitivewords = new ArrayList<String>();

	public ReplaceWriter(ForumWriter forumWriter) {
		this.forumWriter = forumWriter;
		try {
			getSensitivewords();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public ReplaceWriter() {
		try {
			getSensitivewords();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	//读取敏感词汇的方法
	private void getSensitivewords() throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("./files/badwords.txt"));
		String strLine;
		while (br.ready()) {
			strLine = br.readLine();
			sensitivewords.add(strLine);
		}
	}

//	将敏感词汇替代为同等长度的*的方法
	private String getAsteriskString(int num) {
		if (num <= 0) {
			return "";
		}
		String asterisk = "";
		for (int i = 0; i < num; i++) {
			asterisk += "*";
		}
		return asterisk;
	}

	public String write(String filepath) {
		String content = forumWriter.write(filepath);
		for (int i = 0; i < sensitivewords.size(); i++) {
			if (content.contains(sensitivewords.get(i))) {
				content = content.replace(sensitivewords.get(i), getAsteriskString(sensitivewords.get(i).length()));
			}
		}
		return content;
	}
}

Main.java

package decorator;

/**
 * @author 作者 Long:
 * @version 创建时间:2022年5月11日 上午9:41:46
 */
public class Main {

	public static void main(String[] args) {
		Writer writer = new ForumWriter();
		ReplaceWriter writer2 = new ReplaceWriter(new ForumWriter());
		String content = writer.write("./files/articlecontent.txt");
		System.out.println("原发帖内容:");
		System.out.println(content);
		content = writer2.write("./files/articlecontent.txt");
		System.out.println("替代敏感词汇后的发帖内容:");
		System.out.println(content);

	}

}

articlecontent.txt

软件设计模式真是一个小笨蛋

(txt文件的放置位置需要根据自己的项目结构进行更改,代码中的路径也需要进行对应修改)

badwords.txt

笨蛋

敏感词汇还可以增多,一行代表一个敏感词汇

(txt文件的放置位置需要根据自己的项目结构进行更改,代码中的路径也需要进行对应修改)

运行截图

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值