美文网首页
面向对象的核心

面向对象的核心

作者: sweetBoy_9126 | 来源:发表于2019-10-16 19:46 被阅读0次

    面向对象和函数式不是对立的。

    面向对象语言的分类

    • 纯面向对象语言:一切都是对象,包括数字、字符串也是对象,如 Python、Ruby、Scala、Smalltalk
    • 完全支持面向对象,也支持过程式,如 Java、C++、C#
    • 本来不支持面向对象,后来加上的,如 PHP、Perl
    • 看起来像面向对象,但没有完全使用面向对象(比如基于原型来模拟面向对象):JavaScript、Lua
    • 其他还有很多种。

    设计模式

    设计模式指的是对于某个广泛出现的问题提出的适用性广的、可复用的解决方法,也叫套路。
    某些面向对象语言内置了一些套路,如单例、事件、工厂等。

    对面向对象的批评

    1. 复用性和模块化并没有达到预期目标。
    2. 过分强调模型,而忽略了计算和算法。

    Smalltalk

    双引号是注释,不要使用。

    (1 + 2) * 3
    'Hello, world' printNl //'Hello, world'
    

    数组

    x := Array new: 20 //将一个数组赋值给x 数组的长度是20,默认会打印出20个nil(也就是null)
    x at: 1 //获取x里面的第一个(初始化索引就是从1开始)
    x at: 1 put: 99 // x在第一个位置放一个99
    (x at: 1) + 1 //在x第一个位置的数加1
    

    Set
    使用英文句号断句

    x := Set new // 赋值给x一个不能重复的数组
    x add: 5. x add: 7. x add: 'foo' // 在x里添加5 7 'foo',打印出Set(5 7 'foo')
    x remove: 5 // 从x里移除5
    x includes: 7 // x里面是否包含7 false不包含,true包含
    

    有一种简写形式,可以少写几次 x

    x add: 5; add: 7; add: 'foo'
    

    打印出x

    x 或者 x yourself 或者 x printNl
    

    字典

    y := Dictionary new  // Dictionary()
    y at: 'One' put: 1 // 在One中添加一个1 Dictionary('One' -> 1)
    y at: 'Two' put: 2
    y at: 1 put: 'One'
    y at: 2 put: 'Two'
    
    
    y at: 1 //y在1对应的值 'One'
    y at: 'Two'
    y
    y! 用于删除 y 的值
    y
    

    面向对象的核心就是对象与对象之间交互。

    1. 对象维护自己的状态和生命周期
    2. 每个对象独立
    3. 对象和对象直接通过消息传递来工作

    函数式也可以做成消息传递风格

    消息传递风格使用消息传递风格就可以构造 account 对象了,account 对象可以响应 withdraw(取钱)和 deposit(存钱)消息:

    let makeAccount = money => {
      let take = (n) => {
        money = money - n
        return money
      }
      let save = (n) => {
        money = money + n
        return money
      }
      let dispatch = (m) => {
        return (
        m === 'take' ? take :
        m === 'save' ? save :
        new Error('unknown request'))
      }
      return dispatch
    }
    

    接下来是使用 makeAccount 创造两个 account 对象(其实是过程):

    let account1 = makeAccount(100)
    account1('take')(70) // 30
    account1('save')(50) // 80
    

    函数式代码示例(Pager组件)

    function Pager(props) {
      const buttons = Array.apply(null, { length: props.total })
        .map((n, index) => index + 1)
        .filter(n => {
          if (n === 1) {
            return true;
          } else if (n === props.total) {
            return true;
          } else if (Math.abs(n - props.current) <= 2) {
            return true;
          } else {
            return false;
          }
        })
        .reduce((prev, n) => {
          const last = prev[prev.length - 1];
          return prev.concat(n - last > 1 ? [-1, n] : [n]);
        }, [])
        .map(n => (n === -1 ? <span>...</span> : <button>{n}</button>));
      return <div>{buttons}</div>;
    }
    
    function App() {
      return (
        <div className="App">
          <Pager current={5} total={10} />
        </div>
      );
    }
    

    在线demo:https://codesandbox.io/s/happy-williams-n80v7

    赋值的本质

    如果没有赋值,参数和变量只不过就是一个值的名字;
    如果有了赋值,参数和变量 就是一个容器,可以保存不同的值。

    这带来的问题很多。广泛采用赋值的程序设计叫做『命令式/指令式』程序设计。

    命令式程序在遇到『并发』『克隆』等问题时经常很令人头疼。

    函数式编程的特点

    1. 数学!(公理化和可证明)
    2. 更加强调程序执行的结果而非执行的过程
    3. 函数是一等公民(函数可以作为参数),高阶函数
    4. 纯函数,拒绝副作用
    5. 不可变数据
    6. 数据即代码,代码即数据
    7. 引用透明

    相关文章

      网友评论

          本文标题:面向对象的核心

          本文链接:https://www.haomeiwen.com/subject/plaumctx.html