十三、桥接模式
13.1 模式动机


13.2 模式定义
13.3 模式结构

13.4 模式分析
- 实现化:针对抽象化给出的具体实现,就是实现化,抽象化与实现化是一对互逆的概念,实现化产生的对象比抽象化更具体,是对抽象化事物的进一步具体化的产物。
public interface Implementor {
public void operationImpl();
}
public abstract class Abstraction {
protected Implementor impl;
public void setImpl(Implementor impl) {
this.impl=impl;
}
public abstract void operation();
}
public class RefinedAbstraction extends Abstraction {
public void operation() {
// 代码
impl.operationImpl();
//代码
}
}
13.5 案例与解析

// 抽象类
public abstract class Pen {
protected Color color;
public void setColor(Color color) {
this.color=color;
}
public abstract void draw(String name);
}
// 扩充抽象类
public class SmallPen extends Pen {
public void draw(String name) {
String penType="小号毛笔绘制";
this.color.bepaint(penType,name);
}
}
// 扩充抽象类
public class MiddlePen extends Pen {
public void draw(String name) {
String penType="中号毛笔绘制";
this.color.bepaint(penType,name);
}
}
// 扩充抽象类
public class BigPen extends Pen {
public void draw(String name) {
String penType="大号毛笔绘制";
this.color.bepaint(penType,name);
}
}
// 实现类接口
public interface Color {
void bepaint(String penType,String name);
}
// 扩充实现类
public class Red implements Color {
public void bepaint(String penType,String name) {
System.out.println(penType + "红色的"+ name + ".");
}
}
// 扩充实现类
public class Green implements Color {
public void bepaint(String penType,String name) {
System.out.println(penType + "绿色的"+ name + ".");
}
}
// 扩充实现类
public class Blue implements Color {
public void bepaint(String penType,String name) {
System.out.println(penType + "蓝色的"+ name + ".");
}
}
// 扩充实现类
public class White implements Color {
public void bepaint(String penType,String name) {
System.out.println(penType + "白色的"+ name + ".");
}
}
// 扩充实现类
public class Black implements Color {
public void bepaint(String penType,String name) {
System.out.println(penType + "黑色的"+ name + ".");
}
}
<?xml version="1.0"?>
<config>
<className>Blue</className>
<className>SmallPen</className>
</config>
//使用java反射创建具体的颜色和画笔
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class XMLUtilPen {
//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
public static Object getBean(String args) {
try {
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("configPen.xml"));
NodeList nl=null;
Node classNode=null;
String cName=null;
nl = doc.getElementsByTagName("className");
if(args.equals("color")) {
//获取包含类名的文本节点
classNode=nl.item(0).getFirstChild();
} else if(args.equals("pen")) {
//获取包含类名的文本节点
classNode=nl.item(1).getFirstChild();
}
cName=classNode.getNodeValue();
//通过类名生成实例对象并将其返回
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
}
//客户端
public class Client {
public static void main(String a[]) {
Color color;
Pen pen;
color=(Color)XMLUtilPen.getBean("color");
pen=(Pen)XMLUtilPen.getBean("pen");
pen.setColor(color);
pen.draw("鲜花");
}
}
13.6 模式优缺点

十四、委派模式
14.1 什么是委派模式
14.2 委派模式定义
14.3 源码实现
public interface IEmployee {
void doing(String task);
}
public class EmployeeA implements IEmployee {
protected String name;
public EmployeeA(String name){
this.name = name;
}
@Override
public void doing(String task) {
System.out.println("我是员工A,我擅长"+name+",现在开始做"+task+"工作");
}
}
public class EmployeeB implements IEmployee {
protected String name;
public EmployeeB(String name){
this.name = name;
}
@Override
public void doing(String task) {
System.out.println("我是员工B,我擅长"+name+",现在开始做"+task+"工作");
}
}
import java.util.HashMap;
public class Leader implements IEmployee {
HashMap<String,IEmployee> map = new HashMap<String,IEmployee>();
public Leader(){
map.put("登录",new EmployeeA("开发"));
map.put("登录页面",new EmployeeB("UI"));
}
@Override
public void doing(String task) {
map.get(task).doing(task);
}
}
public class Boss {
public static void main(String[] args) {
new Leader().doing("登录");
new Leader().doing("登录页面");
}
}
十五、模板方法模式
15.1 模式结构

15.2 实例数据库操作

//抽象数据库操作类:抽象类
abstract class DBOperator{
public abstract void connDB();
public void openDB(){
System.out.println("打开数据库");
}
public void useDB(){
System.out.println("使用数据库");
}
public void closeDB(){
System.out.println("关闭数据库");
}
public void process(){
connDB();
openDB();
useDB();
closeDB();
}
}
//SQL Server 数据库操作类:具体子类
class SQLServerDBOperator extends DBOperator{
@Override
public void connDB() {
System.out.println("连接SQL Server数据库");
}
}
//Oracle数据库操作类:具体子类
class OracleDBOperator extends DBOperator{
@Override
public void connDB() {
System.out.println("连接Oracle数据库");
}
}
public class Client {
public static void main(String[] args) {
DBOperator operator;
operator = new SQLServerDBOperator();
operator.process();
System.out.println("------------------");
operator = new OracleDBOperator();
operator.process();
}
}
十六、策略模式
16.1 介绍
public String toPay(String payCode){
if(payCode.equals("ali_pay")){
return "调用支付宝接口支付";
}
if(payCode.equals("weixin_pay")){
return "调用微信支付接口支付";
}
if(payCode.equals("yinlian_pay")){
return "调用银联支付接口支付";
}
return "未找到该支付接口";
}
16.2 实现

public interface PayStrategy {
/**
* 共同方法行为
* @return
*/
public String toPay();
}
public class AliPayStrategy implements PayStrategy {
@Override
public String toPay()
return "调用支付宝接口。。。。。";
}
}
public class WeXinPayStrategy implements PayStrategy {
@Override
public String toPay() {
return "调用微信支付接口。。。。。";
}
}
public enum PayEnumStrategy {
/**
* 支付宝支付
*/
ALI_PAY("com.zigao.com.strategy.impl.AliPayStrategy"),
/**
* 微信支付
*/
WEICHAT_PAY("com.zigao.com.strategy.impl.WeXinPayStrategy"),
/**
* 小米支付
*/
XIAOMI_PAY("com.zigao.com.strategy.impl.XiaoMiPayStrategy");
/**
* 完整地址
*/
private String className;
PayEnumStrategy(String className) {
this.className = className;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
public class StrateFactory {
public static PayStrategy getPayStrategy(String strategyType){
try {
//1:获取枚举类中classname
String classname = PayEnumStrategy.valueOf(strategyType).getClassName();
//2:使用java反射技术初始化类
return (PayStrategy)Class.forName(classname).newInstance();
}catch (Exception e){
return null;
}
}
}
@Component
public class PayContextStrategy {
/**
* 获取具体策略实现
*/
public String toPayHtml(String payCode){
//判断是否为空
if(StringUtils.isEmpty(payCode)){
return "payCode======>>>>>不能为空";
}
//使用策略工厂获取具体策略实现
PayStrategy payStrategy = StrateFactory.getPayStrategy(payCode);
if(payStrategy == null){
return "没有找到具体策略实现。。。。。";
}
return payStrategy.toPay();
}
}
@RestController
@RequestMapping("/pay")
public class PayController{
//打印日志
public Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private PayContextStrategy payContextStrategy;
@PostMapping("/toPay")
public ResponseMessage upload(@RequestBody Map map) {
ResponseMessage responseMessage = new ResponseMessage(0);
try {
String payCode = (String) map.get("payCode");
String payHtml = payContextStrategy.toPayHtml(payCode);
responseMessage.setMessage(payHtml);
} catch (Exception e) {
logger.error("调用支付异常,", e);
throw new RuntimeException(e.getMessage());
}
return responseMessage;
}
}



SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for payment
-- ----------------------------
DROP TABLE IF EXISTS `payment`;
CREATE TABLE `payment` (
`id` int(10) NOT NULL,
`channel_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`channel_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`strategy_bean_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of payment
-- ----------------------------
INSERT INTO `payment` VALUES (1, '支付宝支付实现', 'ALI_PAY', 'aliPayStrategy');
INSERT INTO `payment` VALUES (2, '微信宝支付实现', 'WEICHAT_PAY', 'weXinPayStrategy');
INSERT INTO `payment` VALUES (3, '小米宝支付实现', 'XIAOMI_PAY', 'xiaoMiPayStrategy');
SET FOREIGN_KEY_CHECKS = 1;

16.3 总结
十七、责任链模式
17.1 介绍
17.2 实现

17.3 代码实现
//创建抽象的记录器类
public abstract class AbstractLogger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
//责任链中的下一个元素
protected AbstractLogger nextLogger;
public void setNextLogger(AbstractLogger nextLogger){
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message){
if(this.level <= level){
write(message);
}
if(nextLogger !=null){
nextLogger.logMessage(level, message);
}
}
abstract protected void write(String message);
}
//创建扩展了该记录器类的实体类
public class ConsoleLogger extends AbstractLogger{
public ConsoleLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}
public class ErrorLogger extends AbstractLogger{
public ErrorLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}
public class FileLogger extends AbstractLogger{
public FileLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File::Logger: " + message);
}
}
public class ChainPatternDemo {
private static AbstractLogger getChainOfLoggers(){
AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
errorLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(consoleLogger);
return errorLogger;
}
public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");
loggerChain.logMessage(AbstractLogger.DEBUG,
"This is a debug level information.");
loggerChain.logMessage(AbstractLogger.ERROR,
"This is an error information.");
}
}
十八、迭代器模式
18.1 定义
18.2 角色
18.3 示例
public interface Iterator {
/**
* 移动到聚合对象中下一个元素
*/
void next();
/**
* 判断是否已经移动到聚合对象的最后一个元素
*/
boolean isDone();
/**
* 获取迭代的当前元素
*/
Object currentItem();
}
public class ConcreteIterator implements Iterator {
private ConcreteAggregate concreteAggregate;
private int index = 0;
ConcreteIterator(ConcreteAggregate concreteAggregate) {
this.concreteAggregate = concreteAggregate;
}
@Override
public void next() {
if (index < this.concreteAggregate.size()) {
index++;
}
}
@Override
public boolean isDone() {
if (index == this.concreteAggregate.size()) {
return true;
}
return false;
}
@Override
public Object currentItem() {
return this.concreteAggregate.get(index);
}
}
public abstract class Aggregate {
/**
* 工厂方法,创建相应的迭代器对象的接口
*/
public abstract Iterator createIterator();
}
public class ConcreteAggregate extends Aggregate {
private String[] value;
ConcreteAggregate(String[] value) {
this.value = value;
}
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
public int size() {
return this.value.length;
}
public Object get(int index) {
Object retObj = null;
if (index < value.length) {
retObj = value[index];
}
return retObj;
}
}
public class Test {
public static void main(String[] args) {
String[] names = { "张三", "李四", "王五" };
// 创建聚合对象
ConcreteAggregate aggregate = new ConcreteAggregate(names);
Iterator iterator = aggregate.createIterator();
while (!iterator.isDone()){
System.out.println(iterator.currentItem());
iterator.next();
}
}
}
18.4 迭代器模式的适用性
18.5 迭代器模式的优缺点
十九、命令模式
19.1 定义
19.2 角色
- Invoker:要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
19.3 优点
19.4 缺点
19.5 适用情况
19.6 应用
//执行命令的接口
public interface Command {
void execute();
}
//命令接收者Receiver
public class Tv {
public int currentChannel = 0;
public void turnOn() {
System.out.println("The televisino is on.");
}
public void turnOff() {
System.out.println("The television is off.");
}
public void changeChannel(int channel) {
this.currentChannel = channel;
System.out.println("Now TV channel is " + channel);
}
}
//开机命令ConcreteCommand
public class CommandOn implements Command {
private Tv myTv;
public CommandOn(Tv tv) {
myTv = tv;
}
public void execute() {
myTv.turnOn();
}
}
//关机命令ConcreteCommand
public class CommandOff implements Command {
private Tv myTv;
public CommandOff(Tv tv) {
myTv = tv;
}
public void execute() {
myTv.turnOff();
}
}
//频道切换命令ConcreteCommand
public class CommandChange implements Command {
private Tv myTv;
private int channel;
public CommandChange(Tv tv, int channel) {
myTv = tv;
this.channel = channel;
}
public void execute() {
myTv.changeChannel(channel);
}
}
//可以看作是遥控器Invoker
public class Control {
private Command onCommand, offCommand, changeChannel;
public Control(Command on, Command off, Command channel) {
onCommand = on;
offCommand = off;
changeChannel = channel;
}
public void turnOn() {
onCommand.execute();
}
public void turnOff() {
offCommand.execute();
}
public void changeChannel() {
changeChannel.execute();
}
}
//测试类Client
public class Client {
public static void main(String[] args) {
// 命令接收者Receiver
Tv myTv = new Tv();
// 开机命令ConcreteCommond
CommandOn on = new CommandOn(myTv);
// 关机命令ConcreteCommond
CommandOff off = new CommandOff(myTv);
// 频道切换命令ConcreteCommond
CommandChange channel = new CommandChange(myTv, 2);
// 命令控制对象Invoker
Control control = new Control(on, off, channel);
// 开机
control.turnOn();
// 切换频道
control.changeChannel();
// 关机
control.turnOff();
}
}
19.7 总结
二十、状态模式
20.1 介绍
if (WIFIState.ON) {
// WIFI已打开处理逻辑
} else if (WIFIState.OFF) {
// WIFI关闭的处理逻辑
} else if (WIFIState.CONNECTED) {
// WIFI已连接的处理逻辑
}

20.2 代码实现
//抽象状态类
public abstract class WIFIState {
//声明抽象业务方法,不同的具体状态类可以不同的实现
public abstract void handle();
}
// 具体状态类,打开WIFI,开始播放音乐
public class WIFIOnState extends WIFIState {
@Override
public void handle() {
System.out.println("start to play music");
}
}
//具体状态类,wifi关闭,停止正在播放的音乐
public class WIFIOffState extends WIFIState {
@Override
public void handle() {
System.out.println("stop playing music");
}
}
//环境类
public class Context {
//维持一个对抽象状态对象的引用
private WIFIState wifiState;
public void setState(WIFIState wifiState) {
this.wifiState = wifiState;
}
public void request() {
//调用状态对象的业务方法
wifiState.handle();
}
}
public class StateTest {
public static void main(String[] args) {
Context context = new Context();
WIFIState wifiOnState = new WIFIOnState();
context.setState(wifiOnState);
context.request();
System.out.println("start to change wifi state");
WIFIState wifiOffState = new WIFIOffState();
context.setState(wifiOffState);
context.request();
}
}
20.3 总结
二十一、备忘录模式

21.1 介绍
21.1.1 备忘录模式的结构

21.1.2 备忘录模式的实现
public class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//创建一个备忘录对象
public Memento createMemento() {
return new Memento(this);
}
//根据备忘录对象,恢复之前组织者的状态
public void restoreMemento(Memento m) {
state = m.getState();
}
}
public class Memento {
private String state;
public Memento(Originator o) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
public class Client {
public static void main(String[] args) {
Originator originator = new Originator();
Caretaker caretaker = new Caretaker();
//在originator和caretaker中保存memento对象
originator.setState("1");
System.out.println("当前的状态是:" + originator.getState());
caretaker.setMemento(originator.createMemento());
originator.setState("2");
System.out.println("当前的状态是:" + originator.getState());
//从Caretaker取出Memento对象
originator.restoreMemento(caretaker.getMemento());
System.out.println("执行状态恢复,当前的状态是:" + originator.getState());
}
}
21.2 备忘录模式的应用场景
21.2.1 实现文本编辑器恢复功能
/**
* @description: 输入text的当前状态
*/
public class InputText {
private StringBuilder text = new StringBuilder();
public StringBuilder getText() {
return text;
}
public void setText(StringBuilder text) {
this.text = text;
}
//创建SnapMemento对象
public SnapMemento createSnapMemento() {
return new SnapMemento(this);
}
//恢复SnapMemento对象
public void restoreSnapMemento(SnapMemento sm) {
text = sm.getText();
}
}
/**
* @description: 快照备忘录
*/
public class SnapMemento {
private StringBuilder text;
public SnapMemento(InputText it) {
text = it.getText();
}
public StringBuilder getText() {
return text;
}
public void setText(StringBuilder text) {
this.text = text;
}
}
/**
* @description: 负责SnapMemento对象的获取和存储
*/
public class SnapMementoHolder {
private Stack<SnapMemento> snapMementos = new Stack<>();
//获取snapMemento对象
public SnapMemento popSnapMemento() {
return snapMementos.pop();
}
//存储snapMemento对象
public void pushSnapMemento(SnapMemento sm) {
snapMementos.push(sm);
}
}
/**
* @description: 客户端
*/
public class test_memento {
public static void main(String[] args) {
InputText inputText = new InputText();
StringBuilder first_stringBuilder = new StringBuilder("First StringBuilder");
inputText.setText(first_stringBuilder);
SnapMementoHolder snapMementoHolder = new SnapMementoHolder();
snapMementoHolder.pushSnapMemento(inputText.createSnapMemento());
System.out.println("当前的状态是:" + inputText.getText().toString());
StringBuilder second_stringBuilder = new StringBuilder("Second StringBuilder");
inputText.setText(second_stringBuilder);
System.out.println("修改过后的状态是:" + inputText.getText().toString());
inputText.restoreSnapMemento(snapMementoHolder.popSnapMemento());
System.out.println("利用备忘录恢复的状态:" + inputText.getText().toString());
}
}
21.3 备忘录模式实战


public class ConfigFile {
private String versionNo;
private String content;
private Date dateTime;
private String operator;
//getset,constructor
}
public class ConfigMemento {
private ConfigFile configFile;
public ConfigMemento(ConfigFile configFile) {
this.configFile = configFile;
}
public ConfigFile getConfigFile() {
return configFile;
}
public void setConfigFile(ConfigFile configFile) {
this.configFile = configFile;
}
}
public class ConfigOriginator {
private ConfigFile configFile;
public ConfigFile getConfigFile() {
return configFile;
}
public void setConfigFile(ConfigFile configFile) {
this.configFile = configFile;
}
public ConfigMemento saveMemento() {
return new ConfigMemento(configFile);
}
public void getMemento(ConfigMemento memento) {
this.configFile = memento.getConfigFile();
}
}
public class Admin {
//版本信息
private int cursorIdx = 0;
private List<ConfigMemento> mementoList = new ArrayList<>();
private Map<String, ConfigMemento> mementoMap = new ConcurrentHashMap<String, ConfigMemento>();
//新增版本信息
public void append(ConfigMemento memento) {
mementoList.add(memento);
mementoMap.put(memento.getConfigFile().getVersionNo(), memento);
cursorIdx++;
}
//回滚历史配置
public ConfigMemento undo() {
if (--cursorIdx <= 0) {
return mementoList.get(0);
}
return mementoList.get(cursorIdx);
}
//前进历史配置
public ConfigMemento redo() {
if(++cursorIdx > mementoList.size()) {
return mementoList.get(mementoList.size() - 1);
}
return mementoList.get(cursorIdx);
}
public ConfigMemento get(String versionNo) {
return mementoMap.get(versionNo);
}
}
public class ApiTest {
private Logger logger = LoggerFactory.getLogger(ApiTest.class);
@Test
public void test_memento() {
Admin admin = new Admin();
ConfigOriginator configOriginator = new ConfigOriginator();
configOriginator.setConfigFile(new ConfigFile("1000001", "配置内容1", new Date(), "ethan"));
admin.append(configOriginator.saveMemento());
configOriginator.setConfigFile(new ConfigFile("1000002", "配置内容2", new Date(), "ethan"));
admin.append(configOriginator.saveMemento());
configOriginator.setConfigFile(new ConfigFile("1000003", "配置内容3", new Date(), "ethan"));
admin.append(configOriginator.saveMemento());
configOriginator.setConfigFile(new ConfigFile("1000004", "配置内容4", new Date(), "ethan"));
admin.append(configOriginator.saveMemento());
//(第一次回滚)
configOriginator.getMemento(admin.undo());
logger.info("回滚undo: {}", JSON.toJSONString(configOriginator.getConfigFile()));
//(第二次回滚)
configOriginator.getMemento(admin.undo());
logger.info("回滚undo: {}", JSON.toJSONString(configOriginator.getConfigFile()));
// (前进)
configOriginator.getMemento(admin.redo());
logger.info("前进redo:{}", JSON.toJSONString(configOriginator.getConfigFile()));
// (获取)
configOriginator.getMemento(admin.get("1000002"));
logger.info("获取get:{}", JSON.toJSONString(configOriginator.getConfigFile()));
}
}
二十二、中介者模式
22.1 定义

22.2 使用场景
22.3 优缺点
22.4 实现

/**
* 婚姻中介所:抽象中介者角色
*/
public interface MarriageAgency {
/**
* 为Person配对
* @param person
*/
void pair(Person person);
/**
* 注册为会员
* @param person
*/
void register(Person person);
}
/**
* 具体中介者角色
*/
public class MarriageAgencyImp implements MarriageAgency{
//男会员列表
List<Man> men = new ArrayList<>();
//女会员列表
List<Woman> women = new ArrayList<>();
/**
* 根据条件找对象
* @param person
*/
@Override
public void pair(Person person) {
//如果是男的,在女会员列表中找合适的,反之则在男会员列表中找
if("男".equals(person.sex)){
for(Woman w : women){
if(w.age == person.requeireAge){
System.out.println(person.name + "和" + w.name + "终成眷属");
return;
}
}
}else if("女".equals(person.sex)){
for(Man m : men){
if(m.age == person.requeireAge){
System.out.println(person.name + "和" + m.name + "终成眷属");
return;
}
}
}
System.out.println("目前找不到合适的对象");
}
/**
* 注册会员
* @param person
*/
@Override
public void register(Person person) {
if("男".equals(person.sex)){
men.add((Man) person);
}else if("女".equals(person.sex)){
women.add((Woman) person);
}
}
}
/**
* 抽象同事角色
*/
public abstract class Person {
//姓名
String name;
//年龄
int age;
//性别
String sex;//要求的年龄
int requeireAge;
MarriageAgency marriageAgency;
public Person(String name, int age, String sex, int requeireAge, MarriageAgency marriageAgency) {
this.name = name;
this.age = age;
this.sex = sex;
this.requeireAge = requeireAge;
this.marriageAgency = marriageAgency;
marriageAgency.register(this);
}
/**
* 找对象
*/
public void findPartner(){
marriageAgency.pair(this);
}
}
/**
* 具体同事角色
*/
public class Man extends Person{
public Man(String name, int age, String sex, int requeireAge, MarriageAgency marriageAgency) {
super(name, age, sex, requeireAge, marriageAgency);
}
}
/**
* 具体同事角色
*/
public class Woman extends Person{
public Woman(String name, int age, String sex, int requeireAge, MarriageAgency marriageAgency) {
super(name, age, sex, requeireAge, marriageAgency);
}
}
public class Client {
public static void main(String[] args) {
MarriageAgency marriageAgency = new MarriageAgencyImp();
Person man1 = new Man("张强", 24, "男", 22, marriageAgency);
Person man2 = new Man("康欣", 27, "男", 20, marriageAgency);
Person woman1 = new Woman("王慧", 22, "女", 24, marriageAgency);
Person woman2 = new Woman("李静", 23, "女", 26, marriageAgency);
Person woman3 = new Woman("赵蕊", 24, "女", 24, marriageAgency);
man1.findPartner();
man2.findPartner();
}
}
二十三、解释器模式
23.1 定义

- TerminalExpression:终结符表达式。实现与文法中的终结符相关的解释操作。实现抽象表达式中所要求的方法。文法中每一个终结符都有一个具体的终结表达式与之相对应。
public class Context {
private String input;
private int output;
public Context(String input) {
this.input = input;
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public int getOutput() {
return output;
}
public void setOutput(int output) {
this.output = output;
}
}
public abstract class Expression {
public abstract void interpret(Context context);
}
public class PlusExpression extends Expression {
public void interpret(Context context){
System.out.println("自动递增");
//获得上下文环境
String input=context.getInput();
//进行类转换
int intput=Integer.parseInt(input);
++intput;
//对上下文环境重新进行复制
context.setInput(String.valueOf(intput));
context.setOutput(intput);
}
}
public class MinusExpression extends Expression {
@Override
public void interpret(Context context) {
System.out.println("自动递减");
//获得上下文环境
String input=context.getInput();
//进行类转换
int intput=Integer.parseInt(input);
--intput;
context.setInput(String.valueOf(intput));
context.setOutput(intput);
}
}
public class Client {
public static void main(String[] args) {
String number="10";
Context context=new Context(number);
//递增
Expression expression=new PlusExpression();
expression.interpret(context);
System.out.println(context.getOutput());
//递减
Expression expression1=new MinusExpression();
expression1.interpret(context);
System.out.println(context.getOutput());
}
}
23.2 优点
23.3 缺点
23.4 模式适用场景
23.5 模式总结
二十四、观察者模式
24.1 定义与特点
- 观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息更新传递机制,并抽象了更新接口,使得可以有各种各样不同的表示层充当具体观察者角色。
24.2 结构
24.3 实现
import java.util.*;
public class ObserverPattern {
public static void main(String[] args) {
Subject subject=new ConcreteSubject();
Observer obs1=new ConcreteObserver1();
Observer obs2=new ConcreteObserver2();
subject.add(obs1);
subject.add(obs2);
subject.notifyObserver();
}
}
//抽象目标
abstract class Subject {
protected List<Observer> observers=new ArrayList<Observer>();
//增加观察者方法
public void add(Observer observer) {
observers.add(observer);
}
//删除观察者方法
public void remove(Observer observer) {
observers.remove(observer);
}
public abstract void notifyObserver(); //通知观察者方法
}
//具体目标
class ConcreteSubject extends Subject {
public void notifyObserver() {
System.out.println("具体目标发生改变...");
System.out.println("--------------");
for(Object obs:observers) {
((Observer)obs).response();
}
}
}
//抽象观察者
interface Observer {
void response(); //反应
}
//具体观察者1
class ConcreteObserver1 implements Observer {
public void response() {
System.out.println("具体观察者1作出反应!");
}
}
//具体观察者1
class ConcreteObserver2 implements Observer {
public void response() {
System.out.println("具体观察者2作出反应!");
}
}
24.4 应用实例
import java.util.*;
public class RMBrateTest {
public static void main(String[] args) {
Rate rate=new RMBrate();
Company watcher1=new ImportCompany();
Company watcher2=new ExportCompany();
rate.add(watcher1);
rate.add(watcher2);
rate.change(10);
rate.change(-9);
}
}
//抽象目标:汇率
abstract class Rate {
protected List<Company> companys=new ArrayList<Company>();
//增加观察者方法
public void add(Company company) {
companys.add(company);
}
//删除观察者方法
public void remove(Company company) {
companys.remove(company);
}
public abstract void change(int number);
}
//具体目标:人民币汇率
class RMBrate extends Rate {
public void change(int number) {
for(Company obs:companys) {
((Company)obs).response(number);
}
}
}
//抽象观察者:公司
interface Company {
void response(int number);
}
//具体观察者1:进口公司
class ImportCompany implements Company {
public void response(int number) {
if(number>0) {
System.out.println("人民币汇率升值"+number+"个基点,降低了进口产品成本,提升了进口公司利润率。");
} else if(number<0) {
System.out.println("人民币汇率贬值"+(-number)+"个基点,提升了进口产品成本,降低了进口公司利润率。");
}
}
}
//具体观察者2:出口公司
class ExportCompany implements Company {
public void response(int number) {
if(number>0) {
System.out.println("人民币汇率升值"+number+"个基点,降低了出口产品收入,降低了出口公司的销售利润率。");
}
else if(number<0) {
System.out.println("人民币汇率贬值"+(-number)+"个基点,提升了出口产品收入,提升了出口公司的销售利润率。");
}
}
}
import java.util.*;
public class BellEventTest {
public static void main(String[] args) {
BellEventSource bell=new BellEventSource(); //铃(事件源)
bell.addPersonListener(new TeachEventListener()); //注册监听器(老师)
bell.addPersonListener(new StuEventListener()); //注册监听器(学生)
bell.ring(true); //打上课铃声
System.out.println("------------");
bell.ring(false); //打下课铃声
}
}
//铃声事件类:用于封装事件源及一些与事件相关的参数
class RingEvent extends EventObject {
private static final long serialVersionUID=1L;
private boolean sound; //true表示上课铃声,false表示下课铃声
public RingEvent(Object source,boolean sound)
{
super(source);
this.sound=sound;
}
public void setSound(boolean sound)
{
this.sound=sound;
}
public boolean getSound()
{
return this.sound;
}
}
//目标类:事件源,铃
class BellEventSource {
private List<BellEventListener> listener; //监听器容器
public BellEventSource() {
listener=new ArrayList<BellEventListener>();
}
//给事件源绑定监听器
public void addPersonListener(BellEventListener ren) {
listener.add(ren);
}
//事件触发器:敲钟,当铃声sound的值发生变化时,触发事件。
public void ring(boolean sound) {
String type=sound?"上课铃":"下课铃";
System.out.println(type+"响!");
RingEvent event=new RingEvent(this, sound);
notifies(event); //通知注册在该事件源上的所有监听器
}
//当事件发生时,通知绑定在该事件源上的所有监听器做出反应(调用事件处理方法)
protected void notifies(RingEvent e) {
BellEventListener ren=null;
Iterator<BellEventListener> iterator=listener.iterator();
while(iterator.hasNext()) {
ren=iterator.next();
ren.heardBell(e);
}
}
}
//抽象观察者类:铃声事件监听器
interface BellEventListener extends EventListener {
//事件处理方法,听到铃声
public void heardBell(RingEvent e);
}
//具体观察者类:老师事件监听器
class TeachEventListener implements BellEventListener {
public void heardBell(RingEvent e) {
if(e.getSound()) {
System.out.println("老师上课了...");
} else {
System.out.println("老师下课了...");
}
}
}
//具体观察者类:学生事件监听器
class StuEventListener implements BellEventListener {
public void heardBell(RingEvent e) {
if(e.getSound()) {
System.out.println("同学们,上课了...");
} else {
System.out.println("同学们,下课了...");
}
}
}
24.5 应用场景
24.6 模式的扩展
1. Observable 类
Observable 类是抽象目标类,它有一个 Vector 向量,用于保存所有要通知的观察者对象,下面来介绍它最重要的 3 个方法。
2. Observer 接口
import java.util.Observer;
import java.util.Observable;
public class CrudeOilFutures {
public static void main(String[] args) {
OilFutures oil=new OilFutures();
Observer bull=new Bull(); //多方
Observer bear=new Bear(); //空方
oil.addObserver(bull);
oil.addObserver(bear);
oil.setPrice(10);
oil.setPrice(-8);
}
}
//具体目标类:原油期货
class OilFutures extends Observable {
private float price;
public float getPrice() {
return this.price;
}
public void setPrice(float price) {
super.setChanged() ; //设置内部标志位,注明数据发生变化
super.notifyObservers(price); //通知观察者价格改变了
this.price=price ;
}
}
//具体观察者类:多方
class Bull implements Observer {
public void update(Observable o,Object arg) {
Float price=((Float)arg).floatValue();
if(price>0) {
System.out.println("油价上涨"+price+"元,多方高兴了!");
} else {
System.out.println("油价下跌"+(-price)+"元,多方伤心了!");
}
}
}
//具体观察者类:空方
class Bear implements Observer {
public void update(Observable o,Object arg) {
Float price=((Float)arg).floatValue();
if(price>0) {
System.out.println("油价上涨"+price+"元,伤心了!");
} else {
System.out.println("油价下跌"+(-price)+"元,高兴了!");
}
}
}
二十五、访问者模式
25.1 定义
25.2 角色

25.3 使用场景
25.4 优缺点
25.5 访问者模式的实现

/**
* 抽象元素角色
*/
public abstract class HardWare {
//类型
String type;
public HardWare(String type) {
this.type = type;
}
public String getType() {
return type;
}
/**
* 运行
*/
public abstract void run();
/**
* 接收计算机访问者
* @param computerVisitor 指定的计算机访问者
*/
public abstract void accept(ComputerVisitor computerVisitor);
}
public class CPU extends HardWare{
public CPU(String type) {
super(type);
}
@Override
public void run() {
System.out.println("型号为:" + type + "的CPU在运转");
}
@Override
public void accept(ComputerVisitor computerVisitor) {
computerVisitor.visitCPU(this);
}
}
public class HardDisk extends HardWare{
public HardDisk(String type) {
super(type);
}
@Override
public void run() {
System.out.println("型号为:" + type + "的硬盘在运转");
}
@Override
public void accept(ComputerVisitor computerVisitor) {
computerVisitor.visitHardDisk(this);
}
}
/**
* 抽象访问者角色
*/
public interface ComputerVisitor {
/**
* 访问CPU
* @param cpu
*/
void visitCPU(CPU cpu);
/**
* 访问硬盘
* @param hardDisk
*/
void visitHardDisk(HardDisk hardDisk);
}
public class TypeVisitor implements ComputerVisitor{
@Override
public void visitCPU(CPU cpu) {
System.out.println("CPU的型号为:" + cpu.getType());
}
@Override
public void visitHardDisk(HardDisk hardDisk) {
System.out.println("硬盘的型号为:" + hardDisk.getType());
}
}
public class RunVisitor implements ComputerVisitor{
@Override
public void visitCPU(CPU cpu) {
cpu.run();
}
@Override
public void visitHardDisk(HardDisk hardDisk) {
hardDisk.run();
}
}
public class Computer {
private HardWare cpu;
private HardWare hardDisk;
public Computer() {
this.cpu = new CPU("Intel Core i7-620");
this.hardDisk = new HardDisk("Seagate 500G 7200转");
}
public void accept(ComputerVisitor computerVisitor){
cpu.accept(computerVisitor);
hardDisk.accept(computerVisitor);
}
}
public class Client {
public static void main(String[] args) {
Computer computer = new Computer();
ComputerVisitor typeVisitor = new TypeVisitor();
ComputerVisitor runVisitor = new RunVisitor();
computer.accept(typeVisitor);
System.out.println("==========");
computer.accept(runVisitor);
}
}
二十六、总结
| 范围\目的 | 创建型模式 | 结构型模式 | 行为型模式 |
| --------- | ----------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| 类模式 | 工厂方法 | (类)适配器 | 模板方法、解释器 |
| 对象模式 | 单例<br>原型<br>抽象工厂<br/>建造者 | 代理<br/>(对象)适配器<br/>桥接<br/>装饰<br/>外观<br/>享元<br/>组合 | 策略<br/>命令<br/>职责链<br/>状态<br/>观察者<br/>中介者<br/>迭代器<br/>访问者<br/>备忘录 |
| | | | |
1、工厂方法
2、建造者模式
3、抽象工厂
4、原型模式
跟 MM 用 微信 聊天,一定要说些深情的话语了,我搜集了好多肉麻的情话,需要时只要 copy 出来放到 微信 里面就行了,这就是我的情话 prototype 了。(100 块钱一份,你要不要)
5、单态模式
6、适配器模式
7、桥接模式
8、合成模式
9、装饰模式
10、门面模式
11、享元模式
12、代理模式
真烦人,写个程序做为我的 Proxy 吧,凡是接收到这些话都设置好了自己的回答,接收到其他的话时再通知我回答,怎么样,酷吧。
526

被折叠的 条评论
为什么被折叠?



