一种特别的面向对象设计

XiLaiTL大约 3 分钟

一种特别的面向对象设计

我的设计的尝试

核心:

  1. 用一个单例来描述类,也就是伴随对象
  2. 类似于JavaScript原型链——成员方法和静态方法属于描述类的单例的属性(方法降级为属性)
  3. 接口就是伴随对象的类型
  4. 语法糖:扩展函数(且像scala那样可以给泛型加扩展函数)
  5. 泛型支持structural的子类型限制

利用伴随对象放置成员方法和静态方法、利用扩展函数补充成员方法

//只包含属性、字段
struct NewsArticle{
	var location: String
	val author: String
}
//伴随对象
object NewsArticle{
	//默认Self是NewsArticle?
	//NewsArticle的成员方法
	val summarize: Self.()->String = self.()->{
		self.location=xxx
	}
	
	//NewsArticle的静态方法
	val static_summarize: ()->String = ()->{}
}

利用泛型设计接口

//只包含属性、字段
struct NewsArticle {
    var headline: String
    	get = it.()->{}
    	set = it.(value:String)->{ it = value}
    var location: String
    val author: String
    val content: String
}
//用于接口
struct Summary<Self: type>{
	//扩展方法式的写法
	val summarize: Self.()->String   
	val summarize_author: Self.()->String = self.()->{}
}
//实现接口
object NewsArticle: Summary<Self = NewsAriticle> {
	//NewsArticle的成员方法
	val summarize: Self.()->String = self.()->{}
	
	//NewsArticle的静态方法
	val static_summarize: ()->String = ()->{}
}

object OneArticle: NewsArticle {
	
}

使用的时候,接口要求的是“某对象的类型的伴随对象”符合要求,而且需要把“某对象的类型”填入泛型参数里。

现在我觉得比较好的设计是:

val function= (t:(T:Summary<T>))->{}
val function= (t:_:Summary<_>)->{}
val function= (t::Summary)->{}
val function: (T:Summary<T>)->() = (t)->{}

接口可以直接要求属性字段

struct Summary<
    Self: struct{
        var location: String
        val author: String
    }
> {
	val summarize: Self.()->String = self.()->{
		self.location=xxx
	}
}


struct NewsArticle{
	var location: String
	val author: String
}
object NewsArticle: Summary<Self = NewsArticle>{

}

附录

“某对象的类型的伴随对象”符合要求的思考

会出现下面这样抽象的东西:

  • val function= <T> ((t as T).type:Summary<T>)->{}
  • val function= <T> (t:T)->{} where T:Summary<T>
  • val function= <T:Summary<T>> (t:T)->{}
  • val function= (t:T:Summary<T>)->{} 如果直接从t出发,这里需要两个语法糖:
  1. 把对象的类型填入类型的泛型里,例如t:T要得到Summary<T>。 写成Summary<t.type>或者写成Summary<type>
  2. 要求对象的类型的伴随对象的类型,例如t:TT:Summary<T>。 写成t.type : Summary<t.type>或者写成t.type : Summary<type>?

(类似于rust struct/trait/impl三件套)

rust的设计

trait专注方法的接口

struct专注字段

impl给struct提供方法

泛型用于struct的字段类型扩展,并且可以特设重载多态

pub trait Summary {
    fn summarize(&self) -> String;
    fn summarize_author(&self) -> String {
        format!("(Read more from {}...)", self.summarize_author())
    }
}

pub struct NewsArticle {
    pub headline: String,
    pub location: String,
    pub author: String,
    pub content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}, by {} ({})", self.headline, self.author, self.location)
    }
}

pub struct Tweet {
    pub username: String,
    pub content: String,
    pub reply: bool,
    pub retweet: bool,
}

impl Summary for Tweet {
    fn summarize(&self) -> String {
        format!("{}: {}", self.username, self.content)
    }
}


pub fn notify(item1: &impl Summary, item2: &impl Summary) {}
pub fn notify<T: Summary>(item1: &T, item2: &T) {}
pub fn notify<T: Summary + Display>(item: &T) {}
struct Pair<T> {
    x: T,
    y: T,
}

impl<T> Pair<T> {
    fn new(x: T, y: T) -> Self {
        Self { x, y }
    }
}

impl<T: Display + PartialOrd> Pair<T> {
    fn cmp_display(&self) {
        if self.x >= self.y {
            println!("The largest member is x = {}", self.x);
        } else {
            println!("The largest member is y = {}", self.y);
        }
    }
}

还需要思考rust的enum如何融合进来

上次编辑于:
贡献者: XiLaiTL