最近复习基础看到了Learning Typescript这本书,翻开学习,发现了不少知识,在此记录一下。
面向对象编程
SOLID原则
利用Typescript进行面向对象编程要注意五个点,简称为“SOLID”原则
- 单一职责原则(SRP): 表明软件组件(函数,类,模块)必须专注于单一的任务(只有单一的职责)
- 开/闭原则(OCP): 表明软件设计时必须时刻考虑到(代码)可能的发展(具有扩展性),但是程序的发展必须最少地修改已有的代码(对已有的修改封闭)
-里氏替换原则(LSP): 表明只要继承的是同一个接口,程序里任意一个类都可以被其他的类替换。在替换完成后,不需要其他额外的工作程序就能像原来一样运行。
-接口隔离原则(ISP): 表明我们应该将那些非常大的接口拆分成一些更具体的接口,这样客户端就只需要关心他们需要用到的接口
-依赖反转原则(DIP): 表明一个方法应该遵从依赖于抽象(接口)而不是一个实例(类)的概念。
用
Typesciript编写一个类如下:
class Person{
public name: string;
public surname: string;
public email: string;
constructor(name: string, surname: string, email: string){
this.email = email;
this.name = name;
this.surname = surname;
}
greet(){
alert("hello");
}
}
var p : Person = new Person("liming", "li", "123@163.com");
如果要验证email的格式,在Person上增加代码会使Person类变得非常大,我们可以八email抽象成一个类分离出来,这体现了第一个单一职责原则。
class Email{
public email: string;
constructor(email: string){
if(this.validateEmail(email)){
this.email = email
}else{
throw new Error("Invalid email!")
}
}
private validateEmail(email: string){
var re = '/\S+@\S+\.\S+/';
return re.test(email)
}
}
class Person{
public name: string;
public surname: string;
public email: Email;
constructor(name: string, surname: string, email: string){
this.email = email;
this.name = name;
this.surname = surname;
}
greet(){
alert("hello");
}
}
在面向对象的过程中,类与类有一些关系,比如关联,聚合,组合,继承,混合等,接下来并不介绍他们的概念,而是介绍一下泛型类和泛型约束
泛型类
泛型类如同泛型函数,可以介绍很多重复的代码,接下来用代码说明 首先是一个类
这里包括一个
User的类和一个NotGenericUserRepository的类,后面这个类是获取User的列表,并传给JSON文件,当我们想获取一个会议,或者一个歌曲列表时,不同的类形成的这个GenericRepository类也就要重写,这时可以利用泛型类。如下所示:
有时候,我们需要泛型约束,如上述例子,新需求是增加一些变更来验证通过Ajax请求的数据:
success: (data)=>{
var list: T[]
var items = <T[]>data.items
for(let i=0;i<items.length;i++){
if(items[i].isValid()){ // 验证
// ...
}
}
resolve(list)
}
那我们可以写一个验证接口,将泛型进行约束:
class User implements ValidatableInterface{
public name: string
public password: string
constructor(name: string, password: string){
this.name = name
this.password = password
}
public isValid(){
// ...
return true
}
}
class Talk implements ValidatableInterface{
public name: string
constructor(name: string, password: string){
this.name = name
}
public isValid(){
// ...
return true
}
}
class NotGenericUserRepository<T extends ValidatableInterface>{
private _url: string
constructor(url: string){
this._url = url
}
public getAsync(){
return new Promise((resolve: (users: T[]) => void. reject) => {
$.ajax({
url: this._url,
type: "GET",
dataType: "JSON",
success: (data)=>{
var list: T[]
var items = <T[]>data.items
for(let i=0;i<items.length;i++){
if(items[i].isValid()){
list.push(items[i])
}
}
resolve(list)
},
error: (e)=>{
reject(e)
}
})
})
}
}class User implements ValidatableInterface{
public name: string
public password: string
constructor(name: string, password: string){
this.name = name
this.password = password
}
public isValid(){
// ...
return true
}
}
class Talk implements ValidatableInterface{
public name: string
constructor(name: string, password: string){
this.name = name
}
public isValid(){
// ...
return true
}
}
class NotGenericUserRepository<T extends ValidatableInterface>{
private _url: string
constructor(url: string){
this._url = url
}
public getAsync(){
return new Promise((resolve: (users: T[]) => void. reject) => {
$.ajax({
url: this._url,
type: "GET",
dataType: "JSON",
success: (data)=>{
var list: T[]
var items = <T[]>data.items
for(let i=0;i<items.length;i++){
if(items[i].isValid()){
list.push(items[i])
}
}
resolve(list)
},
error: (e)=>{
reject(e)
}
})
})
}
}
泛型中的new操作
要通过代码来创建新的对象,我们需要声明泛型T拥有构造函数,这意味着我们需要像下面一样,用type: {new() :T;}替代type:T