ISO SQuaRE Quality-in-Use model
从用户的角度去分析一个软件的使用质量:
- effecitiveness 效果
- saticifaction 满意度
- safety 安全性
- context coverage 内容覆盖
ISO System/Software Product Quality Model
软件产品质量:
- performance efficiency
- portability
- compatibility
- security
- reliability
- usability
- functional suitability
- maintainability
- modularity
- reusability
- analysability
- modifiability
- testability
The SOLID Principles of class design 设计类
- SRP the single responsibility principle
- OCP open closed
- modules should be open for extension, but closed for modification 当系统需求变化我们希望继承旧系统而不是更改旧系统
- LSP liskov substitution
- code that uses a reference to a base type must be able to use objects of derived types without knowing it: subtypes must be substitutable for their base types
- violation of lsp 违反的例子
public interface PersistedResource { void load(); void store(); }
public class ApplicationSettings implements PersistedResource { //... public void load() { // Loads the saved application settings from storage System.out.println("Got the application settings"); } public void store() { // Stores the application settings to preserve changes System.out.println("Saved the application settings"); } } public class UserSettings implements PersistedResource { //... public void load() { // Loads the saved user settings from storage System.out.println("Got the user settings"); } public void store() { // Stores the user settings to preserve changes System.out.println("Saved the user settings"); } }
public class Application { List<PersistedResource> resources = new ArrayList<PersistedResource>(); public void initializeResources() {
/////////////////////////////////////////////////////////////////////here subtypes resources.add(new ApplicationSettings()); resources.add(new UserSettings()); loadAll(); } public void loadAll() { for (PersistedResource resource: resources) { resource.load(); } } public void saveAll() { for (PersistedResource resource: resources) { resource.store(); } } //continued
CHANGE REQUESTpublic static void main(String[] args) { Application app = new Application(); app.initializeResources(); //do some work, maybe changing settings System.out.println("Made changes to settings"); //save the changes before terminating app.saveAll(); } }
public class SpecialSettings implements PersistedResource { //... public void load() { // Loads the special settings from storage System.out.println("Got the system settings"); } public void store() { // Special settings are read only and cannot be saved // What to do???? } }
public class Application { List<PersistedResource> resources = new ArrayList<PersistedResource>(); public void initializeResources() { resources.add(new ApplicationSettings()); resources.add(new UserSettings()); resources.add(new SpecialSettings()); loadAll(); } public void loadAll() { for (PersistedResource resource: resources) { resource.load(); } } public void saveAll() { for (PersistedResource resource: resources) { resource.store();
} //??? NO!! VERY NASTY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- ISP interface segregation
- DIP dependency inversion
Design Pattern guiding principles
- 对接口进行编程,而不是对实现进行编程
- 接口出来干了一件好事,就是将类内部进行分类。对于map对象,我们可以做好几个接口,这些接口中定义不同功能的方法,函数和属性,map类实现这些接口,这样我们可以使用接口定义,实现对象。因此,所谓接口就是一系列相关方法与属性集合的定义。
- 第一个好处是客户不需要知道他们使用的对象的特定类型 ,只须对象有客户所期望的接口;第二个好处是客户无须知道他们使用的对象是用什么类来实现的,他们只须知道定义的接口或者抽象类。这将极大的减少子系统实现之间的相互依赖关系。
- 接口出来干了一件好事,就是将类内部进行分类。对于map对象,我们可以做好几个接口,这些接口中定义不同功能的方法,函数和属性,map类实现这些接口,这样我们可以使用接口定义,实现对象。因此,所谓接口就是一系列相关方法与属性集合的定义。
- 类的聚合比类的继承要好
- 第一,由于对象的实现是基于接口编写的,所以在实现上存在较少的依赖关系,可以在运行时刻动态的替换引用的对象实现;第二,优先使用对象组合有助于保持每个类背封装,并被集中在单个任务上,这样类和类的继承层次会保持在较少的规模,并且不太可能增长为不可控制的庞然大物;第三,使用对象组合可以最大限度的不用创建新的构件,而使用已有的构件就可以组装获得所需要的功能。
- 第一,由于对象的实现是基于接口编写的,所以在实现上存在较少的依赖关系,可以在运行时刻动态的替换引用的对象实现;第二,优先使用对象组合有助于保持每个类背封装,并被集中在单个任务上,这样类和类的继承层次会保持在较少的规模,并且不太可能增长为不可控制的庞然大物;第三,使用对象组合可以最大限度的不用创建新的构件,而使用已有的构件就可以组装获得所需要的功能。
- 思考设计中的变量以及封装好这些变量
Contract 建立合同
- a subtype method can weaken the precondition
- a subtype method can strengthen the postcondition