软件体系结构与设计模式期末复习

第一章
统一建模语言基础知识
有必要对类之间的关联做一个详细的说明和提供简洁的记忆方式:
单向关联: customer ——> Address 就单向而言更有意义(顾客拥有地址)
双向关联:Customer——Product 相互之间似乎可访问(顾客购买商品并拥有商品&卖出的商品与该顾客有关)
聚合: ◇——> 拥有的(一台计算机包含显示器、鼠标、键盘等)
组成:◆——>离不开(头和嘴巴,缺一不可的包含关系)
实现:- - - - - -△指向这是做了什么事(接口与具体实现类)
继承:——△源于(子类与基类)
依赖:- - - - - ->靠(司机与汽车)
1.类与类图:
类封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性(类的数据职责)操作(类的行为职责)、关系的对象集合的总称。
在软件系统运行时类被实例化为对象,对象应用与某个具体的事物。
简单来说:类是对象的抽象,对象是类的实例。
属性:公有、私有(private)、受保护(protected).
关于操作的类型可见性:+(public)、-(私有)、#(受保护)

method(object par) :void 这表示这个方法带入了一个object类型的参数par,返回值为空(void).
UML类图中基本的操作格式定义:
可见性 名称(【参数列表】)【:返回类型】
2.类之间的关系:
【有了下面这些作为基础后续在代码实现时就会发现逻辑就会清晰起来(代码能力不强不要跳过),变得没有那么难哒】
关联(单箭实线头单向关联eg: customer——>address,双箭头双向关联、还有自关联{一个节点类的成员又是节点对象;通常将一个类的对象作为另一个类的对象的属性});

《
public class LoginForm{
   private JBotton loginbotton;
...
}
public class JBotton{
//private LoginForm[] loginforms;双向关联
...
}

聚合(空心菱形加箭头,箭头一端是聚合的成分、接口【可以脱离整体对象独立存在】);

《
public class Car{
  private Engine engine;
  public Car(Engine engine){
     this.engine=engine;
}
  public void setEngine(Engine engine){
     this.engine=engine;
}
}
public class Engine{}

{在类Car中不直接实例化Engine(单独一个类),而是通过构造方法或者设值方法Setter将在类外部实例化好的Engine一参数形式传入到Car中,这种方式成为注入}
组合(实心菱形加加箭头,箭头一端是组合成分【不可以脱离、就课本而言没有聚合常用】)

《
public class Head{
private Mouth mouth;   //-mouth:Mouth
public Head(){
  mouth= new Mouth;
}
}
public class Mouth{...}

依赖关系(虚线单向箭头,箭头一端指向所依赖的对象【多数情况体现在某个依赖对象的方法使用另一个对象的‘方法’作为参数】)

《
public class Drive{
  public drive(Car car){
    car.move;
}
}
public class Car{
  public void move(){
...
}
}

泛化关系(空心三角形一端指向父类,也称继承关系,父类{基类,超类}子类{派生类})

《
public class Person{
  protected String name;
  protected int age;
  public void move(){...};
  public void say(){...};
}
public class Student extents Person{
   private String studentNo; 
public void study(){...}
 }
public class Teacher extents Person{
  private String teacherNo;
  public void teach(){...}
}

接口与实现关系(空心三角形一端指向被实现方加上虚线【接口和类之间还存在实现关系,类实现了接口中声明的操作】)

《
public interface Vehicle{
  public void move();
}
public class Ship implements Vehicle{
  public void move()
{
...
}
}
public class Car implements Vehicle{
  public void move()
{
...
}
}

第二章
面向对象设计原则
(核心:支持可维护的同时提高可复用性)
一个易于维护的系统,就是复用率高的系统,而一个复用率较好的系统就是一个可维护的系统,但实际上软件的可复用性和可维护性是两个独立的目标。
可维护性较低的4个原因:过于僵硬、过于脆弱、复用率低、黏度过高。
好的系统设计:可扩展性、灵活性、可插入性。

面向对象7个设计原则简介:【*关于那个原则在哪里要怎么用自己得会举例】
1.单一职责原则SRP:类的职责要单一,不能将太多职责放在一个类当中。【实现高内聚,低耦合的指导方针,使用它会使得类的个数增加但是复用性很好,也好修改】
2.开闭原则OCP:软件实体对扩展是开放的,但是对修改是关闭的,级在不修改一个软件实体的基础上去扩展其功能。【抽象化是开闭原则的关键,比如抽象一个按钮,通过继承实现分类对应按钮,如果系统在扩展时只涉及修改配置文件则符合该原则】
3.里氏代换原则LSP:在软件系统中一个可以接受其基类对象的地方一定可以接受其子类。【使用时尽量把父类设计为抽象类或接口,让子类继承父类或实现父接口,并实现在父类中声明的方法,在继承过程中关于新增的子类继承的对象当为复用性更高的基类】
4.依赖倒转原则DIP:要针对抽象层变成,而不要针对具体类编程。【如果说开闭原则是面向对象的设计目标的话,依赖倒转就是其主要机制,是系统抽象化的具体实现,高层不应依赖于底层,它们应该都依赖于抽象,抽象不应依赖细节,细节依赖抽象“针对接口编程,不要针对实现编程”;常用的方法是在代码中使用抽象类,而将具体类放在配置文件中;里氏代换原则是它的基础;{依赖注入:对象与对象之间的依赖关系是可以传递的,通过传递依赖,在一个对象中可以调用另一个对象的方法,在传递时要做好抽象依赖,针对抽象层编程。简单来说:就是将一个类的对象传入另一个类的对象,注入时应该尽量注入其父类对象,而在程序运行时再通过子类对象覆盖父类对象};

这里有三种注入方式:
【1.构造注入;
public interface AbstractBook{
public void view():
}
public interface AbstractReader{
  public void read();
}
public class ConcreateBook implements AbstractBook{
  public void view(){...}
}
public class ConcreateReader implements AbstractReader{
  private AbstractBook book;
  public ConcreateReader(AbstractBook book){
this.book=book;
}  
public void read(){
  book.view();
}
}

2.设值注入;
public interface AbstractBook{
public void view():
}
public interface AbstractReader{
  public void setBook(AbstractBook book);
public void read();
}
public class ConcreateBook implements AbstractBook{
  public void view(){...}
}
public class ConcreateReader implements AbstractReader{
  private AbstractBook book;
  public ConcreateReader(AbstractBook book){
this.book=book;
}  
public void read(){
  book.view();
}
}

3.接口注入
public interface AbstractBook{
public void view():
}
public interface AbstractReader{
  public void read(AbstractBook book);
}
public class ConcreateBook implements AbstractBook{
  public void view(){...}
}
public class ConcreateReader implements AbstractReader{
 
  public void read(AbstractBook book){
book.view();
}  
}

5.接口隔离原则ISP:使用多个专门的接口来代替一个统一的接口。【客户端不应该依赖那些它不需要的接口,只提供用户需要的行为,隐藏其它的(将胖接口细化)】
6.合成复用原则CRP:在复用功能时,多使用聚合和组合少使用甚至不使用继承。【GoF提倡这么做,这点体现在继承的时候是“白箱”复用转换为聚合/组合之后就是“黑箱”复用。合成复用可以在运行时动态进行,新对象可以动态的引用与成员对象类型相同的其他对象,灵活些,类与类之间的耦合也降低了;只需修改配置文件符合开闭原则】
7.迪米特法则LoD:也称最少知识原则,不要和陌生人说话,只和直接朋友通信引入第三者发生间接交互。【简单来说:一个软件实体应当尽可能少的与其他实体发生相互作用。狭义上,可以降低耦合但是导致系统中散落增加大量的小方法,可以使局部设计简化但是使得不同模块间通信效率降低。广义上,就是指对对象之间的信息流量、流向以及信息的影响进行控制,主要是对信息隐藏的控制。主要用途控制信息的过载】

第三章
设计模式简单概述
设计模式是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结,使用设计模式是为了课重用代码,让代码更容易被理解提高代码的可读性。
包含几个要素:模式名称、问题、目的、解决方法、效果、实例代码和相关设计模式。
设计模式一般有以下分类方式:
根据其目的(用来做什么)将其分为:
创建型(主要用来创建对象{工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式}),结构型(主要用于处理类或者对象的组合{适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、代理模式})和行为型(主要用于描述类或对象怎样交互和怎样分配职责{职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式})。
根据范围:是用于处理什么间的关系分为:对象模式(占大部分)和类模式(因为继承)。

在这里插入图片描述
模式的快速记忆方法:
首先是口诀:
创建型:抽建(KFC)工原单(创建对象)5 抽工建单原
结构型:适桥组装外享代(处理类或对象的组合)7 适桥
行为型:职命解迭中备观状策模仿(类与对象间怎样交互怎样分配职责)11
【考试肯定不考还有哪些模式,但是可能会考该模式属于哪个类型,这里来不及的话记下两个剩余的都是另一个也行】

GoF中模式的定义:
创建型:
抽象工厂模式(Abstract Factory):提供了一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
建造者模式(Bulider):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
工厂方法模式(Factory Method):将类的实例化操作延迟到类的子类中完成,即由子类来决定究竟应该实例化(创建)哪一个类。
原型模式(prototype):通过给出一个原型对象来指明所要创建的对象的类型然后通过复制这个原型对象的办法创建出更多同类型的对象。
单例模式(Singleton):确保在在系统中某一个类只有一个实例,而且自行实例化,并向整个系统提供这个实例。
结构型:
适配器模式(Adapter):将一个借口转换成用户需要的另一个接口,从而使接口不兼容的那些类可以一起工作。
桥接模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独立的变化。
组合模式(Composite):通过组合多个对象形成树型结构以表示“整体-部分”的结构层次,对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性。
装饰模式(Decorator):动态的给一个对象增加一些额外的职责。
外观模式(Facade):为复杂的子系统提供一个统一的接口。【外观角色、子系统角色】
享元模式(Flyweight):通过应用共享技术有效的地支持大量细粒度对象的复用。
代理模式(Proxy):给某一个对象提供一个代理,并由代理对象控制原对象的使用。
行为型:
职责链模式(Chain of Responsibility):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,,并且沿着这条链传送请求,直到有对象处理它为止。
命令模式(Command):将一个请求封装为一个对象,从而使得请求调用者和请求接受者解耦。
解释器模式(Interpreter):描述如何为语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这个句子。
迭代器模式(Iterator):提供了一种方法来访问聚合对象,而不用暴露这个对象的内部表示。
中介者模式(Mediator):通过一个中介对象来封装一系列的对象交互,使得各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
备忘录模式(Memento):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后对象恢复原型保存状态。
观察者模式(Observer):定义了一种对象间的一对多的依赖关系,使得每当一个对象的状态发生改变时,其相关依赖对象皆得到通知并且自动更新。【观察者目标不需要了解其具体观察者,只需要知道它们都有一个共同的接口即可(具体目标继承抽象目标类——>抽象观察者接口由具体观察者实现)】
状态模式(State):允许一个对象在其内部状态改变时改变它的行为。
策略模式(Strategy):定义一系列算法,并将每一个算法封装在一个类中,并让它们可以相互替换,策略模式让算法独立于它的客户而变化。
模板方法模式(Template Method):定义一个操作中算法的股价,而将一些步骤延迟到子类中。
访问者模式(Visitor):表示一个作用于某对象结构中的各元素操作,它使得用户可以在不改变各元素的前提下定义作用于这些元素的新操作。

【模式定义很枯燥,用对应实例记起来会好些】

补充小题:
设计模式的优点:
1.方便开发人员之间的沟通和交流,使得设计方案更加通俗易懂。
2.更加简单方便地复用成功的设计和体系结构。
3.使得设计方案更加灵活且易于修改。
4.提供软件开发效率和软件质量。
5.有助于理解面向对象思想。
关键元素:模式名称、问题、解决方案、效果。
反模式:用来解决问题的带有共同性的不同方法。

通过角色记忆模式:
1.简单工厂模式(Simple Factory):【不属于GoF但应用频繁
{工厂角色、抽象产品角色、具体产品角色}

2.工厂方法模式(Factory Method):
{抽象产品、具体产品、抽象工厂、具体工厂}

3.抽象工厂模式(Abstract Factory):
{抽象产品、具体产品、抽象工厂、具体工厂}

4.建造者模式(Bulider):
{抽象建造者、具体建造者、产品角色、指挥者}

5.原型模式(Prototype):
[能够实现克隆的类必须实现一个标识接口Cloneable,表示这个Java类支持复制,如果没有这个接口就调用的clone() 方法会抛出异常
在客户端调用也很简单:
PrototypeDemo obj1= new prototypeDemo();
PrototypeDemo obj2=obj1.clone();
在浅克隆中,当对象被复制时,它所包含的成员对象却没有被复制;
而深克隆中,除了对象本身被复制外,对象所包含的引用(成员对象)也被复制。]
{抽象原型类、具体原型类、客户类}

6.单例模式(Singleton):(饿汉式、懒汉式)
{单例角色一个类}

7.适配器模式(Adapter):
{目标抽象类、适配器类、适配者类、客户类}

8.桥接模式(Bridge):
{抽象类、扩充抽象类、实现类接口、具体实现类}

9.组合模式(Composite):
{抽象构建、叶子构建、容器构建、客户类}

10.装饰模式(Decorator):
{抽象构建、具体构建、抽象装饰类、具体装饰类}

11.外观模式(Facade):
{外观角色、子系统角色}

12.享元模式(Flyweight):
{抽象享元类、具体享元类、非共享具体享元类、享元工厂类}

13.代理模式(Proxy):
{抽象主题角色、代理主题角色、真实主题角色}

14.职责链模式(Chain of Responsbility):
{抽象处理者、具体处理者、客户类}

15.命令模式(Command):
{抽象命令类、具体命令类、调用者、接收者、客户类}

16.解释器模式(Interpreter):
{抽象表达式、终结符表达式、非终结符表达式、环境类、客户类}

17.迭代器模式(Iterator):
{抽象迭代器、具体迭代器、抽象聚合类、具体聚合类}

18.中介者模式(Mediator):
{抽象中介者、具体中介者、抽象同事类、具体同事类}

19.备忘录模式(Memento):
{原发器、备忘录、负责人}

20.观察者模式(Observer):
{目标、具体目标、观察者、具体观察者}

21.状态模式(State):
{环境类、抽象状态类、具体状态类}

22.策略模式(Strategy):
{环境类、抽象策略类、具体策略类}

23.模板方法模式(Template Method):
{抽象类、具体子类}

24.访问者模式(Visitor):
{抽象访问者、具体访问者、抽象元素、具体元素、对象结构}

这里我的学习感悟是:
我们判断一个模式有什么不同通过用途还有它拥有的元素角色,注意理解分析类图本身也不简单。因为类图中就包含了类之间关系,方法,角色,反射注入机制,会画类图就等于成功了一大半。

有课本的话23个类图实例都分别记下一个模式对应类图,强调怎么实现的,关系是怎样的,去做就会发现规律而不那么焦虑,等考试就会这发现很受用(甚至可以自己从图上观察出这个模式的特点,也许不理解的就突然明白了),等有时间再补上类图。*关于我的其他文章里因为前期不理解类图之间的关系可能表示错了小些,但是代码都能用。

  • 6
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_54152049

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值