软件设计师——设计模式笔记下
软件设计师——设计模式笔记下(行为型11种)
- 13、责任链模式(对象模式)
- 意图
- 适用性
- 代码实现
- 14、命令模式(对象模式)
- 意图
- 适用性
- 代码实现
- 15、解释器模式(类模式)
- 意图
- 适用性
- 代码实现
- 16、迭代器模式(对象模式)
- 意图
- 适用性
- 代码实现
- 17、中介者模式(对象模式)
- 意图
- 适用性
- 代码实现
- 18、备忘录模式(对象模式)
- 意图
- 适用性
- 代码实现
- 19、观察者模式(对象模式)
- 意图
- 适用性
- 代码实现
- 20、状态模式(对象模式)
- 意图
- 适用性
- 代码实现
- 21、策略模式(对象模式)
- 意图
- 适用性
- 代码实现
- 22、模板方法模式(类模式)
- 意图
- 适用性
- 代码实现
- 23、访问者模式(对象模式)
- 意图
- 适用性
- 代码实现
13、责任链模式(对象模式)
意图
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
适用性
- 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
- 想在不明确指定接收者的情况下向多个对象中的一个提交一 个请求。
- 可处理一个请求的对象集合应被动态指定。
代码实现
public class ChainOfResponsibilityPattern {public static void main(String[] args) {Handler fudaoyuan = new FuDaoYuan();Handler yuanzhang = new YuanZhang();Handler xiaozhang = new XiaoZhang();fudaoyuan.setNext(yuanzhang);yuanzhang.setNext(xiaozhang);fudaoyuan.HandlerRequest(14); //院长审批通过}
}abstract class Handler {protected Handler next;public void setNext(Handler next) {this.next = next;}public abstract void HandlerRequest(int request);
}//辅导员类
class FuDaoYuan extends Handler { // <= 7 审批@Overridepublic void HandlerRequest(int request) {if (request <= 7) {System.out.println("辅导员审批通过");} else {if (next != null) {next.HandlerRequest(request);} else {System.out.println("无法审批");}}}
}//院长类
class YuanZhang extends Handler { // <= 15 审批@Overridepublic void HandlerRequest(int request) {if (request <= 15) {System.out.println("院长审批通过");} else {if (next != null) {next.HandlerRequest(request);} else {System.out.println("无法审批");}}}
}//校长类
class XiaoZhang extends Handler { // <= 30 审批@Overridepublic void HandlerRequest(int request) {if (request <= 30) {System.out.println("校长审批通过");} else {if (next != null) {next.HandlerRequest(request);} else {System.out.println("无法审批");}}}
}
#mermaid-svg-eYlho9gaVfoM5qZM {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-eYlho9gaVfoM5qZM .error-icon{fill:#552222;}#mermaid-svg-eYlho9gaVfoM5qZM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-eYlho9gaVfoM5qZM .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-eYlho9gaVfoM5qZM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-eYlho9gaVfoM5qZM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-eYlho9gaVfoM5qZM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-eYlho9gaVfoM5qZM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-eYlho9gaVfoM5qZM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-eYlho9gaVfoM5qZM .marker.cross{stroke:#333333;}#mermaid-svg-eYlho9gaVfoM5qZM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-eYlho9gaVfoM5qZM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-eYlho9gaVfoM5qZM .cluster-label text{fill:#333;}#mermaid-svg-eYlho9gaVfoM5qZM .cluster-label span{color:#333;}#mermaid-svg-eYlho9gaVfoM5qZM .label text,#mermaid-svg-eYlho9gaVfoM5qZM span{fill:#333;color:#333;}#mermaid-svg-eYlho9gaVfoM5qZM .node rect,#mermaid-svg-eYlho9gaVfoM5qZM .node circle,#mermaid-svg-eYlho9gaVfoM5qZM .node ellipse,#mermaid-svg-eYlho9gaVfoM5qZM .node polygon,#mermaid-svg-eYlho9gaVfoM5qZM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-eYlho9gaVfoM5qZM .node .label{text-align:center;}#mermaid-svg-eYlho9gaVfoM5qZM .node.clickable{cursor:pointer;}#mermaid-svg-eYlho9gaVfoM5qZM .arrowheadPath{fill:#333333;}#mermaid-svg-eYlho9gaVfoM5qZM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-eYlho9gaVfoM5qZM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-eYlho9gaVfoM5qZM .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-eYlho9gaVfoM5qZM .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-eYlho9gaVfoM5qZM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-eYlho9gaVfoM5qZM .cluster text{fill:#333;}#mermaid-svg-eYlho9gaVfoM5qZM .cluster span{color:#333;}#mermaid-svg-eYlho9gaVfoM5qZM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-eYlho9gaVfoM5qZM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
运行结果
院长审批通过!
14、命令模式(对象模式)
意图
将一个请求封装为一个对象,从而使得可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
适用性
- 抽象出待执行的动作以参数化某对象。
- 在不同的时刻指定、排列和执行请求。
- 支持取消操作。
- 支持修改日志。
- 用构建在原语操作上的高层操作构造一个系统。
代码实现
public class CommandPattern {public static void main(String[] args) {Tv tv = new Tv(); // 接收者对象 电视机Command onCommand = new OnCommand(tv); // 命令对象 开机命令Command offCommand = new OffCommand(tv); // 命令对象 关机命令Invoker invoker = new Invoker(); // 请求者invoker.setCommand(onCommand); // 给请求者设置 开机 命令invoker.call(); // 请求者去请求命令System.out.println("=======================");invoker.setCommand(offCommand); // 给请求者设置 关机命令invoker.call(); // 请求者去请求命令}
}// 请求者
class Invoker { private Command command; // 命令public void setCommand(Command command) { // 设置请求者 的 请求的命令this.command = command;}public void call() { // 调用command.Execute();}
}// 命令接口
interface Command { public void Execute(); // 执行命令
}// 开机命令
class OnCommand implements Command { private Tv tv;public OnCommand(Tv tv) {this.tv = tv;}@Overridepublic void Execute() {tv.OnAction();}
}// 关机命令
class OffCommand implements Command { private Tv tv;public OffCommand(Tv tv) {this.tv = tv;}@Overridepublic void Execute() {tv.OffAction();}
}// 接收者 电视机
class Tv { public void OnAction() { System.out.println("电视机开机了..."); // 开机行为}public void OffAction() {System.out.println("电视机关机了..."); // 关机行为}
}
#mermaid-svg-yauXKIK4JAlX7Zs1 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-yauXKIK4JAlX7Zs1 .error-icon{fill:#552222;}#mermaid-svg-yauXKIK4JAlX7Zs1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yauXKIK4JAlX7Zs1 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-yauXKIK4JAlX7Zs1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yauXKIK4JAlX7Zs1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yauXKIK4JAlX7Zs1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yauXKIK4JAlX7Zs1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yauXKIK4JAlX7Zs1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yauXKIK4JAlX7Zs1 .marker.cross{stroke:#333333;}#mermaid-svg-yauXKIK4JAlX7Zs1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yauXKIK4JAlX7Zs1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-yauXKIK4JAlX7Zs1 .cluster-label text{fill:#333;}#mermaid-svg-yauXKIK4JAlX7Zs1 .cluster-label span{color:#333;}#mermaid-svg-yauXKIK4JAlX7Zs1 .label text,#mermaid-svg-yauXKIK4JAlX7Zs1 span{fill:#333;color:#333;}#mermaid-svg-yauXKIK4JAlX7Zs1 .node rect,#mermaid-svg-yauXKIK4JAlX7Zs1 .node circle,#mermaid-svg-yauXKIK4JAlX7Zs1 .node ellipse,#mermaid-svg-yauXKIK4JAlX7Zs1 .node polygon,#mermaid-svg-yauXKIK4JAlX7Zs1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yauXKIK4JAlX7Zs1 .node .label{text-align:center;}#mermaid-svg-yauXKIK4JAlX7Zs1 .node.clickable{cursor:pointer;}#mermaid-svg-yauXKIK4JAlX7Zs1 .arrowheadPath{fill:#333333;}#mermaid-svg-yauXKIK4JAlX7Zs1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yauXKIK4JAlX7Zs1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yauXKIK4JAlX7Zs1 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-yauXKIK4JAlX7Zs1 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-yauXKIK4JAlX7Zs1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yauXKIK4JAlX7Zs1 .cluster text{fill:#333;}#mermaid-svg-yauXKIK4JAlX7Zs1 .cluster span{color:#333;}#mermaid-svg-yauXKIK4JAlX7Zs1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yauXKIK4JAlX7Zs1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
运行结果
电视机开机了...
=======================
电视机关机了...
15、解释器模式(类模式)
意图
给定一个语言,定义它的文法的一种表示,并定义一个解释器, 这个解释器使用该表示来解释语言中的句子。
适用性
当有一个语言需要解释执行,并且可将该语言中的句子表示为一个抽象语法树时, 以下情况效果最好:该文法简单;效率不是一个关键问题。
代码实现
import java.util.*;public class InterpreterPattern {public static void main(String[] args) {Context context = new Context();context.check("A区的开发人员");context.check("B区的调试人员");context.check("C区的测试人员");System.out.println("==========");context.check("D区的程序员");context.check("D区的测试员");context.check("A区的程序员");}
}class Context {private String[] regions = {"A区", "B区", "C区"};private String[] persons = {"开发人员", "测试人员", "调试人员"};private NonterminalExprssion nonterminal;public Context() {TerminalExpression region = new TerminalExpression(regions);TerminalExpression person = new TerminalExpression(persons);nonterminal = new NonterminalExprssion(region, person);}public void check(String info) {boolean bool = nonterminal.Interpret(info);if (bool) {System.out.println("识别成功");} else {System.out.println("识别失败");}}
}interface Expression {public boolean Interpret(String info);
}//非终止符解释器
class NonterminalExprssion implements Expression {private TerminalExpression region;//地区终结符集private TerminalExpression person;//人员终结符集public NonterminalExprssion(TerminalExpression region, TerminalExpression person) {this.region = region;this.person = person;}@Overridepublic boolean Interpret(String info) {String[] str = info.split("的");// B区的调试人员 --> str = {"B区", "调试人员"}return region.Interpret(str[0]) && person.Interpret(str[1]);}
}//终止符解释器
class TerminalExpression implements Expression {private Set<String> set = new HashSet<>();public TerminalExpression(String[] data) {// for (遍历对象类型 对象名 : 遍历对象)for (String str : data) {set.add(str); // 将符号存入终结符集}}@Overridepublic boolean Interpret(String info) {return set.contains(info); //判断某符号是否包含于终结符集内 }
}
16、迭代器模式(对象模式)
意图
提供一种方法顺序访问一个聚合对象中的各个元素,且不需要暴露该对象的内部表示。
适用性
- 访问一个聚合对象的内容而无须暴露它的内部表示。
- 支持对聚合对象的多种遍历。
- 为遍历不同的聚合结构提供一个统一的接口。
代码实现
import java.util.*;public class IteratorPattern {public static void main(String[] args) {BookAggregate bookAggregate = new BookAggregate();String[] books = {"数据结构", "操作系统", "计算机网络", "计算机组成原理"};double[] prices = {10.24, 20.48, 40.96, 81.92};for (int i = 0; i < 4; i ++ ) {bookAggregate.Add(new Book(books[i], prices[i]));}Iterator bookIterator = bookAggregate.CreateIterator();while (bookIterator.hasNext()) {Book book = (Book) bookIterator.next();System.out.println(book.getName() + " " + book.getPrice());}}
}interface Iterator {public boolean hasNext();public Object next();
}class BookIterator implements Iterator {private int index;private BookAggregate bookAggregate;public BookIterator(BookAggregate bookAggregate) {this.index = 0;this.bookAggregate = bookAggregate;}@Overridepublic boolean hasNext() {if (index < bookAggregate.getSize()) {return true;} else {return false;}}@Overridepublic Object next() {Object obj = bookAggregate.get(index);index ++ ;return obj;}
}interface Aggregate {public Iterator CreateIterator();
}class BookAggregate implements Aggregate {private List<Book> list = new ArrayList<Book>();public void Add(Book book) {list.add(book);}public Book get(int index) {return list.get(index);}public int getSize() {return list.size();}@Overridepublic Iterator CreateIterator() {return new BookIterator(this);}
}class Book {private String name;private double price;public Book(String name, double price) {this.name = name;this.price = price;}public String getName() {return name;}public double getPrice() {return price;}
}
运行结果
数据结构 10.24
操作系统 20.48
计算机网络 40.96
计算机组成原理 81.92
17、中介者模式(对象模式)
意图
用一个中介对象来封装一系列的对象交互。 中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
适用性
- 一组对象以定义良好但是复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解。
- 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
- 想定制一个分布在多个类中的行为,而又不想生成太多的子类。
代码实现
public class MediatorPattern {public static void main(String[] args) {ConcreteMediator mediator = new ConcreteMediator();Colleague1 colleague1 = new Colleague1(mediator);Colleague2 colleague2 = new Colleague2(mediator);mediator.setColleague1(colleague1);mediator.setColleague2(colleague2);colleague1.sendMessage("软考加油");colleague2.sendMessage("祝大家软考顺利通过!");}
}abstract class Colleague {protected Mediator mediator;
}class Colleague1 extends Colleague {public Colleague1(Mediator mediator) {this.mediator = mediator;}public void sendMessage(String message) {mediator.sendMessage(message, this);}public void Notify(String message) {System.out.println("同事1收到消息:" + message);}
}class Colleague2 extends Colleague {public Colleague2(Mediator mediator) {this.mediator = mediator;}public void sendMessage(String message) {mediator.sendMessage(message, this);}public void Notify(String message) {System.out.println("同事2收到消息:" + message);}
}abstract class Mediator {public abstract void sendMessage(String message, Colleague colleague);
}class ConcreteMediator extends Mediator {private Colleague1 colleague1;private Colleague2 colleague2;public void setColleague1(Colleague1 colleague1) {this.colleague1 = colleague1;}public void setColleague2(Colleague2 colleague2) {this.colleague2 = colleague2;}public void sendMessage(String message, Colleague colleague) {if (colleague == colleague1) {colleague2.Notify(message); // 让同事2收到消息} else {colleague1.Notify(message); // 让同事1收到消息}}
}
运行结果
同事2收到消息:软考加油
同事1收到消息:祝大家软考顺利通过!
18、备忘录模式(对象模式)
意图
在不破坏封装性的前提下捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后就可以将对象恢复到原先保存的状态。
适用性
- 必须保存一个对象在某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。
- 如果一个用接口来让其他对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
代码实现
import java.util.*;public class MementoPattern {public static void main(String[] args) {Caretaker caretaker = new Caretaker();Originator originator = new Originator();originator.setState("1024");Memento backup1 = originator.createMemento();caretaker.addMemento(backup1);originator.setState("2048");Memento backup2 = originator.createMemento();caretaker.addMemento(backup2);originator.setState("4096");Memento backup3 = originator.createMemento();caretaker.addMemento(backup3);System.out.println(originator.getState() + "\n");//输出人当前记录的备忘录caretaker.showMemento();//手机里面的虚拟管理员显示出所有备忘录列表Memento memento1 = caretaker.getMemento(2);originator.setMemento(memento1);System.out.println("\n根据第2次备份还原之后的状态为:" + originator.getState());}
}// 原发器
class Originator { private String state;public void setState(String state) {this.state = state;}public String getState() {return state;}public Memento createMemento() {return new Memento(state);}public void setMemento(Memento memento) {state = memento.getState();}
}// 备忘录
class Memento { private String state;public Memento(String state) {this.state = state;}public String getState() {return state;}
}// 管理者
class Caretaker { private List<Memento> mementoList = new ArrayList<>();public void addMemento(Memento memento) {mementoList.add(memento);}public Memento getMemento(int index) {// 判断参数是否合法if (index >= 1 && index <= mementoList.size()) {return mementoList.get(index - 1);}return null;}public void showMemento() {int cnt = 1;// for (遍历对象类型 对象名 : 遍历对象)for (Memento memento : mementoList) {System.out.println("第" + cnt + "次备份,状态为:" + memento.getState());cnt ++ ;}}
}
运行结果
4096第1次备份,状态为:1024
第2次备份,状态为:2048
第3次备份,状态为:4096根据第2次备份还原之后的状态为:2048
19、观察者模式(对象模式)
意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
适用性
- 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变时。
- 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两者封装在独立的对象中以使它们可以各自独立地改变和复用。
- 当一个对象必须通知其他对象,而它又不能假定其他对象是谁,即不希望这些对象是紧耦合的。
代码实现
import java.util.*;public class ObserverPattern {public static void main(String[] args) {Subject subjectA = new ConcreteSubject("目标A");Observer observerB = new ConcreteObserver("张三", subjectA);Observer observerC = new ConcreteObserver("李四", subjectA);Observer observerD = new ConcreteObserver("王五", subjectA);subjectA.setState("更新了");System.out.println("======================================");subjectA.Detach(observerD);subjectA.setState("停更了");}
}interface Subject { // 目标public void Attach(Observer observer); // 添加观察者public void Detach(Observer observer); // 删除观察者public void Notify(); // 状态改变后 通知所有观察者public void setState(String state); // 设置状态(改变状态)public String getState(); // 获取状态
}class ConcreteSubject implements Subject {private String name;private String state;private List<Observer> observerList;public ConcreteSubject(String name) {state = "未更新";this.name = name;observerList = new ArrayList<Observer>();}public void setState(String state) {this.state = state;System.out.println(name + "的状态发生变化,变化后的状态为:" + state);Notify();}public String getState() {return state;}public void Attach(Observer observer) {observerList.add(observer);}public void Detach(Observer observer) {observerList.remove(observer);}public void Notify() {// for (遍历对象类型 对象名 : 遍历对象)for (Observer observer : observerList) {observer.update();}}
}interface Observer { // 观察者接口public void update(); // 收到通知 更新观察者的状态
}class ConcreteObserver implements Observer {private String name;private String state;private Subject subject;public ConcreteObserver(String name, Subject subject) {this.name = name;this.subject = subject;subject.Attach(this);state = subject.getState();}@Overridepublic void update() {System.out.println(name + "收到通知");state = subject.getState(); // 让当前观察者的状态 和 改变了状态之后的目标的状态保持一致System.out.println(name + "改变后的状态为:" + state);}
}
运行结果
目标A的状态发生变化,变化后的状态为:更新了
张三收到通知
张三改变后的状态为:更新了
李四收到通知
李四改变后的状态为:更新了
王五收到通知
王五改变后的状态为:更新了
======================================
目标A的状态发生变化,变化后的状态为:停更了
张三收到通知
张三改变后的状态为:停更了
李四收到通知
李四改变后的状态为:停更了
20、状态模式(对象模式)
意图
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
适用性
- 一个对象的行为决定于它的状态,并且它必须在运行时刻根据状态改变它的行为。
- 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态常用一个或多个枚举常量表示。
代码实现
public class StatePattern {public static void main(String[] args) {Context context = new Context(); // count:3System.out.println(context.getState());context.Request(); // 购买一个饮料 count = 2context.Request(); // 购买一个饮料 count = 1context.Request(); // 购买一个饮料 count = 0System.out.println(context.getState());context.Request(); // 无货 等待补货 补货成功 count = 5System.out.println(context.getState());context.Request(); // 购买一个饮料 count = 4System.out.println(context.getCount());}
}class Context { // 贩卖机private int count;private State state;public Context() {count = 3;state = new StateA();}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public State getState() {return state;}public void setState(State state) {this.state = state;}public void Request() { // 购买一个饮料state.Handle(this);}}interface State {public void Handle(Context context);
}class StateA implements State { // 有货@Overridepublic void Handle(Context context) {int count = context.getCount();if (count >= 1) {System.out.println("购买成功!");context.setCount(count - 1);if (context.getCount() == 0) {context.setState(new StateB());}} else {System.out.println("购买失败!");}}
}class StateB implements State { // 无货@Overridepublic void Handle(Context context) {int count = context.getCount();if (count == 0) {System.out.println("购买失败!等待补货");context.setCount(5);System.out.println("补货成功,请重新购买");context.setState(new StateA());}}
}
运行结果
Shejims.StatePattern.StateA@1b6d3586
购买成功!
购买成功!
购买成功!
Shejims.StatePattern.StateB@4554617c
购买失败!等待补货
补货成功,请重新购买
Shejims.StatePattern.StateA@74a14482
购买成功!
4
21、策略模式(对象模式)
意图
定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。此模式使得算法可以独立于使用它们的客户而变化。
适用性
- 许多相关的类仅仅是行为有异。
- 需要使用一个算法的不同变体。
- 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
- 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,将相关的条件分支移入它们各自的Strategy类中,以代替这些条件语句。
代码实现
public class StrategyPattern {public static void main(String[] args) {Strategy add = new AddStrategy();Strategy subtraction = new SubtractionStrategy();Strategy multiply = new MultiplyStrategy();OperationContext context = new OperationContext(add);System.out.print("两数相加:");context.Operation(2022, 528);context = new OperationContext(subtraction);System.out.print("两数相减:");context.Operation(2022, 528);context = new OperationContext(multiply);System.out.print("两数相乘:");context.Operation(2022, 528);}
}class OperationContext {private Strategy strategy;public OperationContext(Strategy strategy) {this.strategy = strategy;}public void Operation(int a, int b) {strategy.TwoNumberOperation(a, b);}
}interface Strategy {public void TwoNumberOperation(int a, int b);
}//相加策略
class AddStrategy implements Strategy {@Overridepublic void TwoNumberOperation(int a, int b) {System.out.println(a + b);}
}//相减策略
class SubtractionStrategy implements Strategy {@Overridepublic void TwoNumberOperation(int a, int b) {System.out.println(a - b);}
}//相乘策略
class MultiplyStrategy implements Strategy {@Overridepublic void TwoNumberOperation(int a, int b) {System.out.println(a * b);}
}
运行结果
两数相加:2550
两数相减:1494
两数相乘:1067616
22、模板方法模式(类模式)
意图
定义一个操作中的算法骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用性
- 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
- 各子类中公共的行为应被提取出来并集中到一个公共父类中,以避免代码重复。
- 控制子类扩展。模板方法旨在特定点调用“hook” 操作(默认的行为,子类可以在必要时进行重定义扩展),这就只允许在这些点进行扩展。
代码实现
public class TemplateMethodPattern {public static void main(String[] args) {// 父类名 对象名 = new 子类名();Person student = new Student();Person teacher = new Teacher();student.TemplateMethod();System.out.println("=====我是分割线=====");teacher.TemplateMethod();}
}abstract class Person {public void TemplateMethod() {System.out.println("上课 去教室"); // 1PrimitiveOperation1(); // 2System.out.println("下课 离开教室"); // 3PrimitiveOperation2(); // 4}public abstract void PrimitiveOperation1(); // 原语操作 1 :上课过程 学生 听课…… 老师 讲课public abstract void PrimitiveOperation2(); // 原语操作 2 :作业 学生 写作业 提交作业…… 老师 批改作业 打分数
}class Student extends Person {@Overridepublic void PrimitiveOperation1() {System.out.println("学生:听课 学习 做笔记 提出问题");}@Overridepublic void PrimitiveOperation2() {System.out.println("学生:写作业 提交作业");}
}class Teacher extends Person {@Overridepublic void PrimitiveOperation1() {System.out.println("老师:上课 讲课 解答问题 布置作业");}@Overridepublic void PrimitiveOperation2() {System.out.println("老师:批改作业 打分数");}
}
运行结果
上课 去教室
学生:听课 学习 做笔记 提出问题
下课 离开教室
学生:写作业 提交作业
=====我是分割线=====
上课 去教室
老师:上课 讲课 解答问题 布置作业
下课 离开教室
老师:批改作业 打分数
23、访问者模式(对象模式)
意图
表示一个作用于某对象结构中的各元素的操作。它允许在不改变各元素的类的前提下定义作用于这些元素的新操作。
适用性
- 一个对象结构包含很多类对象,它们有不同的接口,而用户想对这些对象实施一些依赖于其具体类的操作。
- 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而又想要避免这些操作“污染”这些对象的类。
- 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。
代码实现
import java.util.*;public class VisitorPattern {public static void main(String[] args) {PersonStructure structure = new PersonStructure();Visitor1 visitor1 = new Visitor1();System.out.println("访问者1的访问记录:");structure.Accept(visitor1);System.out.println("学生年龄总和:" + visitor1.getStudentAgeSum() + " 老师年龄总和:" + visitor1.getTeacherAgeSum());System.out.println("=========================================");Visitor2 visitor2 = new Visitor2();System.out.println("访问者2的访问记录:");structure.Accept(visitor2);System.out.println("学生最高成绩:" + visitor2.getMaxScore() + " 老师最大工龄:" + visitor2.getMaxWorkYear());}
}interface Visitor {public void visitStudent(Student student); // 访问学生public void visitTeacher(Teacher teacher); // 访问老师
}class Visitor1 implements Visitor { // 访问者1 分别统计学生和老师的年龄总和private int studentAgeSum = 0;private int teacherAgeSum = 0;public int getStudentAgeSum() {return studentAgeSum;}public int getTeacherAgeSum() {return teacherAgeSum;}@Overridepublic void visitStudent(Student student) {System.out.println("访问者1访问学生:" + student.getName() + " 年龄:" + student.getAge());studentAgeSum += student.getAge();}@Overridepublic void visitTeacher(Teacher teacher) {System.out.println("访问者1访问老师:" + teacher.getName() + " 年龄:" + teacher.getAge());teacherAgeSum += teacher.getAge();}
}class Visitor2 implements Visitor { // 访问者2 分别求出 学生的最高成绩 以及 老师的最高工龄private int maxScore = -1;private int maxWorkYear = -1;public int getMaxScore() {return maxScore;}public int getMaxWorkYear() {return maxWorkYear;}@Overridepublic void visitStudent(Student student) {System.out.println("访问者2访问学生:" + student.getName() + " 成绩:" + student.getScore());maxScore = Math.max(maxScore, student.getScore());}@Overridepublic void visitTeacher(Teacher teacher) {System.out.println("访问者2访问老师:" + teacher.getName() + " 工龄:" + teacher.getWorkYear());maxWorkYear = Math.max(maxWorkYear, teacher.getWorkYear());}
}class PersonStructure {private List<Person> personList = new ArrayList<Person>();public PersonStructure() {personList.add(new Student("张三", 21, 89));personList.add(new Student("李四", 22, 75));personList.add(new Student("王五", 20, 95));personList.add(new Teacher("李老师", 35, 7));personList.add(new Teacher("陈老师", 40, 15));personList.add(new Teacher("刘老师", 27, 3));}public void Accept(Visitor visitor) {// for (遍历对象类型 对象名 : 遍历对象)for (Person person : personList) {person.Accept(visitor);}}
}abstract class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}public abstract void Accept(Visitor visitor);
}class Student extends Person {private int score;public Student(String name, int age, int score) {super(name, age);this.score = score;}public int getScore() {return score;}@Overridepublic void Accept(Visitor visitor) {visitor.visitStudent(this);}
}class Teacher extends Person {private int workYear;public Teacher(String name, int age, int workYear) {super(name, age);this.workYear = workYear;}public int getWorkYear() {return workYear;}@Overridepublic void Accept(Visitor visitor) {visitor.visitTeacher(this);}
}
运行结果
访问者1的访问记录:
访问者1访问学生:张三 年龄:21
访问者1访问学生:李四 年龄:22
访问者1访问学生:王五 年龄:20
访问者1访问老师:谢老师 年龄:35
访问者1访问老师:汪老师 年龄:40
访问者1访问老师:王老师 年龄:27
学生年龄总和:63
老师年龄总和:102
===================================
访问者2的访问记录:
访问者2访问学生:张三 成绩:89
访问者2访问学生:李四 成绩:75
访问者2访问学生:王五 成绩:95
访问者2访问老师:谢老师 工龄:7
访问者2访问老师:汪老师 工龄:15
访问者2访问老师:王老师 工龄:3
学生最高成绩:95
老师最大工龄:15
软件设计师——设计模式笔记下相关推荐
- 软件设计师——设计模式笔记上
软件设计师--设计模式笔记上(创造型5种) 设计模式的主要目的 设计模式的原则 1.工厂方法模式(类模式) 意图 适用性 代码实现 2.抽象工厂模式(对象模式) 意图 适用性 代码实现 3.生成器模式 ...
- 软件设计师-设计模式
前言 正文 一.创建型设计模式 1.工厂模式 定义:定义一个创建对象的接口,让子类决定实例化哪一个类. 2.抽象工厂模式 定义:提供一个创建一系列相关或相互依赖的接口,而无须指定他们具体的类. 3.生 ...
- 软件设计师---设计模式
设计模式上午大概4分+下午两大题30分(java和c++) 对各种设计模式的描述(包括适用情况和意图) 创建型设计模式 工厂模式(Factory Method) 意图:定义一个用于创建对象的接口,让子 ...
- 软考软件设计师下午真题-面向对象的程序设计与实现-状态设计模式(2011年下半年试题六))Java代码讲解
软考软件设计师下午真题-面向对象的程序设计与实现-状态设计模式(2011年下半年试题六))代码讲解 说明 Java代码 注释 说明 某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且 ...
- 软考软件设计师下午真题-面向对象的程序设计与实现-生成器设计模式(2018年上半年试题六))Java代码讲解
软考软件设计师下午真题-面向对象的程序设计与实现-生成器设计模式(2018年上半年试题六))代码讲解 说明 Java代码 注释 说明 生成器(Builder)模式的意图是将一个复杂对象的构建与它的表示 ...
- 软考软件设计师---面向对象技术(设计模式--创建型--工厂、生成器、原型、单例)
转载于自己博客文章: 软考软件设计师---面向对象技术(设计模式--创建型--工厂.生成器.原型.单例) - 松下之约一.创建型设计模式关注对象的创建,让一个类得到实例化过程由另一类的对象完成.分类: ...
- 【软件设计师中级】设计模式之抽象工厂学习笔记(c++)
本文适合新手和小白 目录 1.Absstract Factrory (1)意图 (2)结构 (3)适用性 2.看类图写码 (1)利用泛化关系 (2)利用c++多态的特点 (3)利用依赖关系 (4)UM ...
- 2023上半年软件设计师-试题详解与分析
目录 前言 上午题 计算机组成原理 信息安全 计算机相关法律 软件设计 语言处理 操作系统 软件工程 软件测试 面向对象编程 程序设计语言 数据库 数据结构与算法 计算机网络 计算机专业英语 下午题 ...
- 【软件设计师】软件设计师考试内容及分值分布
软件设计师考试内容及分值分布 简介 考试大纲要求 考题类型及分值分布 计算机与软件工程知识 软件设计 注意 简介 考试分为上午和下午两场,都是笔试题,满分都是75分,45分合格. 上午: 计算机与软件 ...
最新文章
- 10 个 Linux 中方便的 Bash 别名
- 对勾选的下拉选择进行同步选择
- Batch Norm、Layer Norm、Instance Norm、Group Norm、Switchable Norm总结
- 简单的学习心得:网易云课堂Android开发第六章SQLite与ContentProvider
- WordPress主题导航源码webstackpro-支持个人自定义本地保存
- python权限不够cmd安装不了_python环境配置+matplotlib
- 中移4G模块-ML302-OpenCpu开发-(固件编译和烧录)
- [2013.8.16]小议innerText/HTML以及outerText/HTML
- 现代操作系统读书笔记
- 单片机原理及应用c51语言版林立,单片机原理及应用——基于Proteus和Keil C(第4版)...
- robotium测试
- springboot uniapp小说阅读APP源码
- Bugly-全量更新
- python colorsys模块 RGB和其他色彩系统(颜色空间)(YIQ、HLS、HSV)之间的转换 hsv_to_rgb(h, s, v)函数
- eclipse建java gui工程,Eclipse java swing开发环境搭建教程
- HDU5855(最大权闭合图构图技巧+裸的最大流)
- 思科模拟器服务器登录显示什么,思科模拟器服务器远程登录
- 个人公众号成长记 - 你为什么要做公众号呢?
- Oracle HR 样例用户的建立 10g,11g均可
- 杨辉三角 C语言实现【一维数组】
热门文章
- Linux重启服务器,发现部分文件丢失
- OBS推流工具快速上手
- 【CocosCreator 3.x】使用 RenderTexture 实现 3D 渲染在 UI 上 => 攻略
- 51.COM该唱《We are the champion》了
- 设计师必备的插画设计网站
- 动态加载js如何保证顺序执行?
- (转)IOS 7 Xcode 5 免IDP证书 真机调试
- 【Linux基础】查看十六进制hexdump
- rpc服务器太忙共享文件,解决“RPC服务器不可用”的难题
- java学习系列2(并发锁问题-乐观锁与悲观锁以及乐观锁的一种实现方式-CAS)