若干种设计模式
线程安全的策略
四种GC策略
多态:LSP原则,泛型,重载和重写。
语法错误,类名 / 函数名错误 ,参数数目错误,参数类型错误 ,返回值类型错误
非法的参数值 ,非法的返回值 ,越界 ,空指针。
描述程序运行时内存里变量层面的状态。
参考链接:https://www.cnblogs.com/zdj-/p/8494316.html
使用mutable类型的风险,前后打印出的结果相同。
groundhogAnswer与partyDate引用相同,更改了partyDate,groundhogAnswer也将随之更改。
判断两个函数实现是否可相互替换。站在客户端视角看行为等价性。
根据规约判断是否行为等价,如果两个函数符合这个规约则等价。
requires effects
在规范中,前置条件和后置条件的某些部分可以在@param和@return子句之外的其他位置找到,因此必须仔细阅读。
对于可变函数
除非在后置条件里声明过,否则方法内部不应该改变输入参数
避免使用可变的全局变量,但是为了性能原因,有时候却不得不用。这对程序的安全性造成了巨大破坏。
可变类型的对象:提供了可改变其内部数据的值的操作。
不变数据类型: 其操作不改变内部值,而是构造新的对象。
ADT 开发者关注表示空间 R , client 关注抽象空间 A。
White box reuse 白盒复用:源代码可见,可修改和扩展
Black box reuse 黑盒复用:源代码不可见,不能修改
delegation 委托
显式委派:将发送对象传递给接收对象
隐式委托:由语言的成员查找规则
(Framework)框架:可重复使用的框架代码,可以自定义到应用程序中。一组具体类、抽象类、及其之间的连接关系。
Adapter
shape是目标对象
Rectangle是适配器
LegacyRectangle是被适配对象
Decorator
Display类是抽象类,被装饰物与装饰物的抽象父类,这样保持了两者之间的一致性。
StringDisplay类是被装饰者类,具体类
Border类是装饰物的抽象类
(deligation是声明了在class类中使用了被委托的类型的变量,并调用该类型变量的方法,而继承没有)
参考链接:https://blog.csdn.net/zoinsung_lee/article/details/82771581
factory method 设计模式
抽象工厂类:工厂的抽象类实现
具体工厂类:一个工厂生产一类产品
abstract factory(产品族)
抽象工厂类:工厂的抽象类实现
抽象产品类:产品的抽象类实现
具体产品类:
具体工厂类:一个工厂创建多个不同类型的产品。具体产品与具体工厂之间通过deligation联系。
builder 设计模式
Builder:抽象建造类,用于规范产品的各个组成部分,并进行抽象。
ConcreteBuilder:具体建造类,实现抽象类中的所有方法并返回一个产品实例。
Product:builder要返回的多个产品类
Director:安排一有模块的顺序,并且告诉builder开始建造
Iterator
Iterator(迭代器接口):该接口必须定义实现迭代功能的最小定义方法集,比如提供hasNext()和next()方法。
ConcreteIterator(迭代器实现类): 比如BookShelfIterator,迭代器接口Iterator的实现类。可以根据具体情况加以实现。
Aggregate(容器接口):定义基本功能以及提供类似Iterator iterator()的方法。
ConcreteAggregate(容器实现类): 比如BookShelf,容器接口的实现类。必须实现Iterator iterator()方法。
参考链接:https://blog.csdn.net/xw13106209/article/details/6912873
Strategy
AthContext:外部环境类,实现create()方法
Strategy类:抽象类,策略实现接口
ConcreteStrategy类:具体类
state 和 memento 设计模式
Facade(外观模式)
(电脑)
参考链接:https://blog.csdn.net/bifuguo/article/details/81432774
visitor设计模式
Visitor类:存放要访问的对象
Myvisitor类:针对不同子类型的subject类,分别实行visitor操作
Subject类:accept()方法,与特定的visitor子类联系起来,允许其对自己的数据进行操作。
observer模式
Subject:被观察者的抽象类,定义增加和删除观察者对象的操作。声明了获取当前状态的方法,如果MySubject发生变化,会通知所有需要监控的对象。
MySubject:如果MySubject发生变化,会通知所有需要监控的对象。
Observer:观察者的抽象类。声明了update方法,负责接收来自Subject角色的状态变化通知。
Observer1:依赖于MySubject的对象,表示具体的Observer,当update执行后会获取观察对象的最新的状态
Observer2:依赖于MySubject的对象,表示具体的Observer,当update执行后会获取观察对象的最新的状态
//proxy、bridge、composite,template、mediator 等设计模式
Flyweight设计模式
Prototype 设计模式
用 Singleton 和 Object Pool 设计模式
(canonicalization 的思想)
通过继承和动态绑定实现的可扩展性
template method pattern
通过为可以插入框架的组件定义接口来实现可扩展性
通过定义符合特定接口的组件来重用现有功能
这些组件通过委派与框架集成
更强的不变量
更弱的前置条件
更强的后置条件
前置条件越弱,后置条件越强,spec强度越强。
https://blog.csdn.net/JAck_chen0309/article/details/92803893
是否使用了delegation 替代继承?
纠错性,适应性,完善性,预防性。
软件的大部分成本来自于维护阶段。
软件维护不仅仅是运维工程师的工作,而是从设计和开发阶段就开始了。
高内聚,低耦合,分离关注点,信息隐藏。
Collections.unmodifiableList或unmodifiableSet就是将一个List或Set进行包装,返回一个不可修改的List或者Set,如果调用修改方法就会抛出java.lang.
UnsupportedOperationException异常。
单一责任原则(Single Responsibility Principle):不应该有多于 1 个原因让你的 ADT 发生变化,否则就拆分开
(面向变化的)开放 / 封闭原则:
对扩展性的开放:( 模块的行为应是可扩展的,从而该模块可表现出新的行为以满足需求的变化)
对修改的封闭: 但模块自身的代码是不应被修改的, 扩展模块行为的一般途径是修改模块的内部实现, 如果一个模块不能被修改,那么它通常被认为是具有固定的行为。
Liskov 替换原则(LSP):
子类型必须能够替换其基类型
接口隔离原则:不能强迫客户端依赖于它们
不需要的接口:只提供必需的接口
依赖转置原则:抽象的模块不应依赖于具体的模块, 具体应依赖于抽象。
1.工厂方法模式(一个工厂,多个产品)
Creator?
2.抽象工厂模式(多个工厂,一个工厂只对应一个产品)
3.构造器模式(一个产品,有多个属性,每个具体类的多个属性不一样)
设计模式:Abstract Factory vs Builder
Abstract Factory 创建的是一个“产品族”,有多个不同产品组成。
Builder 创建的是一个完整的产品,有多个部分组成。
4.Bridge(桥接模式)
Bridge | structural pattern 强调双方的 run time delegation linking |
Strategy | behavioral pattern 强调一方 run-time 使用另一方的“算法” |
5.Strategy
6.Proxy(代理模式)
7.(不重要)Composite(组合模式)
Composite | 目的是在同类型的对象之间建立起树型层次结构,一个上层对象可包含多个下层对象 |
Decorator | 强调的是同类型对象之间的“特性增加”问题,它们之间是平等的,区别在于 “拥有特性”的多少 |
8.Observer pattern
9.Visitor Pattern
对特定类型的 object 的特定操作 (visit) ,在运行时将二者动态绑定到一起,该操作可以灵活更改,无需更改被 visit 的类。
10.Mediator Pattern
11.Command pattern
例如:ArrayIndexOutOfBoundsException, NullPointerException,NumberFormatException,ClassCastException,NumberFormatExceptio,ClassCastException, IllegalArgumentException,IllegalStateException,NoClassDefFoundError
需要从 Exception 派生出子类型(除了Runable及其派生的子类)
程序的正确性(后置条件和不变量的满足)取决于并发计算线程A和B中事件的相对时间。
调整代码无用。这三个版本是都存在race condition。
消息传递机制也无法解决竞争条件问题。
利用某些方法调用来主动影响线程之间的 interleaving 关系。
for (int i = 0; i < n; i++) {
//Pause for 4 seconds
Thread.sleep(4000);
//Print a message
System.out.println(msg[i]);
}
Thread.yield() 使用该方法,线程告知调度器:我可以放弃 CPU 的占用权,从而可能引起调度器唤醒其他线程。
Thread.join() 让当前线程保持执行,直到其执行结束。