• 浅谈设计模式(五)


    一、观察者模式

    又被称为发布/订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系。

    Observer(抽象被观察者): 抽象主题角色把所有观察者对象保存在一个集合里。

    Subject:抽象观察者,是观察者的抽象类。QQNotice:具体观察者,以便在得到主题更改通知时更新自身的状态。QQClient:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。

    观察者

    1. interface Observer{
    2. void update(String message);
    3. }
    4. class QQClient implements Observer{
    5. String clientName;
    6. public QQClient(String clientName) {
    7. this.clientName = clientName;
    8. }
    9. @Override
    10. public void update(String message) {
    11. System.out.println(this.clientName + "推送了消息" + message);
    12. }
    13. }

    被观察者

    1. interface Subject{
    2. void attache(Observer observer);
    3. void notify(String message);
    4. }
    5. class QQNotice implements Subject{
    6. List<Observer> noticeList = new ArrayList<>();
    7. @Override
    8. public void attache(Observer observer) {
    9. noticeList.add(observer);
    10. }
    11. @Override
    12. public void notify(String message) {
    13. for(Observer observer: noticeList){
    14. observer.update(message);
    15. }
    16. }
    17. }

    客户端调用

    1. QQClient qq = new QQClient("客户端1");
    2. QQNotice qqNotice = new QQNotice();
    3. qqNotice.attache(qq);
    4. qqNotice.notify("新的好友消息");

    二、访问者模式

    概念:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。在不改变数据结构的前提下可以改变数据元素,解决了数据结构和操作耦合性的问题。原理是在被访问的类里增加一个对外提供的待访问者的接口。

     主要角色的功能:Judge(抽象访问者): 定义了对每一个元素访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来讲与元素类个数(即抽象元素角色类的实现类的个数)是一样。

    MaleJudge、FemaleJudge(具体访问者): 给出对每一个元素类访问时所产生的具体行为。

    Pie(抽象元素): 定义了一个接受访问者的方法(即accept),即每个元素都要可以被访问者访问。

    ApplePie、BananaPie(具体元素): 提供接受访问方法的具体实现。

    PieStore(对象结构):  是一个盛放元素的容器,并且可以迭代这些元素,供访问者访问。

    1. interface Judge{
    2. void perfectScore(ApplePie pie);
    3. void lowScore(BananaPie pie);
    4. }
    5. // 每一个裁判对不同的物品做出不同的反应
    6. class MaleJudge implements Judge{
    7. @Override
    8. public void perfectScore(ApplePie pie) {
    9. System.out.println("男人的完美评价");
    10. }
    11. @Override
    12. public void lowScore(BananaPie pie) {
    13. System.out.println("男人的很low评价");
    14. }
    15. }
    16. class FemaleJudge implements Judge{
    17. // 这里要依赖具体的类 并不能依赖模糊的接口
    18. @Override
    19. public void perfectScore(ApplePie pie) {
    20. System.out.println("女人的完美评价");
    21. }
    22. @Override
    23. public void lowScore(BananaPie pie) {
    24. System.out.println("女人的很low评价");
    25. }
    26. }

     抽象元素和具体元素实现

    1. interface Pie{
    2. void accept(Judge judge);
    3. }
    4. // 每一个被访问的都需要提供一个对外的接口
    5. class ApplePie implements Pie {
    6. @Override
    7. public void accept(Judge judge) {
    8. judge.perfectScore(this);
    9. }
    10. }
    11. class BananaPie implements Pie {
    12. @Override
    13. public void accept(Judge judge) {
    14. judge.lowScore(this);
    15. }
    16. }
    1. class PieStore {
    2. List<Pie> pies = new ArrayList<>();
    3. public void addPie(Pie pie){
    4. pies.add(pie);
    5. }
    6. public void startJudge(Judge judge){
    7. for(Pie pie: pies){
    8. pie.accept(judge);
    9. }
    10. }
    11. }

    客户端进行调用

    1. PieStore store = new PieStore();
    2. ApplePie applePie = new ApplePie();
    3. BananaPie bananaPie = new BananaPie();
    4. store.addPie(applePie);
    5. store.addPie(bananaPie);
    6. store.startJudge(new FemaleJudge());

    三、迭代器模式

    提供一个对象来顺序访问聚合对象中的一系列数据;优点是提供一个统一遍历的方法,隐藏了聚合内部的结构客户端无需考虑内部结构;缺点是每个聚合对象都要一个迭代器,会生成多个不好管理。

     Iterator: 定义访问和遍历聚合元素的接口,通常包含hasNext()、next()等方法,这里用的是JDK自带的。

    CakeIterator、PieIterator:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

    PieCreater:迭代器创建类。

    1. public class Store {
    2. private String name;
    3. private String desc;
    4. public Store(String name, String desc) {
    5. this.name = name;
    6. this.desc = desc;
    7. }
    8. public String getName() {
    9. return name;
    10. }
    11. public void setName(String name) {
    12. this.name = name;
    13. }
    14. public String getDesc() {
    15. return desc;
    16. }
    17. public void setDesc(String desc) {
    18. this.desc = desc;
    19. }
    20. }
    1. public class CakeIterator implements Iterator<Store> {
    2. Store[] stores;
    3. int index = 0;
    4. @Override
    5. public boolean hasNext() {
    6. return index < stores.length && stores[index] != null;
    7. }
    8. @Override
    9. public Store next() {
    10. return stores[index++];
    11. }
    12. public CakeIterator(Store[] storeList){
    13. this.stores = storeList;
    14. }
    15. }
    16. public class PieIterator implements Iterator<Store> {
    17. List<Store> stores = new ArrayList<>();
    18. int index = 0;
    19. public PieIterator(List<Store> storeList){
    20. this.stores = storeList;
    21. }
    22. @Override
    23. public boolean hasNext() {
    24. if(index >= stores.size() || stores.get(index) == null){
    25. return false;
    26. }
    27. return true;
    28. }
    29. @Override
    30. public Store next() {
    31. return stores.get(index++);
    32. }
    33. }
    1. public class PieCreater {
    2. List<Store> stores = new ArrayList<>();
    3. public PieIterator createPieIterator(){
    4. return new PieIterator(stores);
    5. }
    6. public CakeIterator createCakeIterator(){
    7. return new CakeIterator(stores.toArray(new Store[0]));
    8. }
    9. public void addStores(Store store){
    10. stores.add(store);
    11. }
    12. }

  • 相关阅读:
    使用Apache Flink实现实时数据同步与清洗:MySQL和Oracle到目标MySQL的ETL流程
    TCP连接管理
    手把手教你如何玩转Git
    抖音数据抓取工具|短视频下载工具|视频内容提取软件
    ES6中const注意点
    golang的切片使用总结二
    pkg-config使用
    Qt开发必备技术栈学习路线和资料
    【rust/egui】(八)使用panels给你的应用划分功能区块
    [HDLBits] Exams/ece241 2014 q7a
  • 原文地址:https://blog.csdn.net/weixin_41678001/article/details/125188965