仓颉:关于从语法层面转向设计层面

1.设计模式

学习是不断向前滚动的雪球,而我们也必须在学习过程中学会在积累一定知识以后,从一个层面转向了层面的过程。而今天我们就要从语法层面转向设计层面。

在面向对象的编程思想要执行的一个应用的技术栈,有很多种模式可供选择,常用的有:单例模式,工厂模式,代理模式等等。

1.单例模式

首先了解概念,单例模式是指这个程序运行只能产生一个对象。

应用场景: 读取或解析文件,加载数据,数据加载到对象中,1个文件只对应一个对象,只能从这个唯一的对象中再同步数据。(如果是多个对象,造成数据的不一致)。

package cjdemo5.chapter1

//单例模式  程序只创建这个类的一个对象
public  class  User{

     //主构造函数
     public  User()
     {
       println("创建了对象")
     }


}
public  func   exec1()
{
     //创建User类的对象
     var  u1 :User  =User()
     var  u2 :User = User()
       

}

上述代码由于创建了多个对象,所以不属于单例

而单例模式同时也分为了饿汉式单例和懒汉式单例

首先来展示饿汉式单例,代码如下

package cj1.chapter1

//单例模式  程序只创建这个类的一个对象
public class User {

    //静态变量只初始化一次
    static var user: User = User()

    //主构造函数
    //设置成私有,外部不能直接访问
    //断子绝孙
    private User() {
        println("创建了对象")
    }

    //计划生育,只能生一个对象
    //static 静态  修饰方法叫做静态方法
    //类名.静态方法名()  call  这样是不是没有创建对象
    public static func createUser(): User {
        user
    }


}

public func exec1() {
    //创建User类的对象,设置成private,报错
    //  var  u1 :User  =User()
    //  var  u2 :User = User()

    var  u1  = User.createUser()
    var  u2  = User.createUser()
}

如何理解饿汉式单例  不管你需不需要这个对象,这个对象已经在程序中生成

接下来展示懒汉式单例,代码如下

package cj1.chapter2

//单例模式  程序只创建这个类的一个对象
public class User {
    //静态变量只初始化一次
    static var user: User 

    //静态构造函数,只能定义一个,只执行一次
    static init() {
        println("创建对象")
        user = User()
    }

    //主构造函数
    //设置成私有,外部不能直接访问
    //断子绝孙
    private User() {
        println("创建了对象")
    }

    //计划生育,只能生一个对象
    //static 静态  修饰方法叫做静态方法
    //类名.静态方法名()  call  这样是不是没有创建对象
    public static func createUser(): User {
        user
    }
}

public func exec1() {
    //创建User类的对象,设置成private,报错
    //  var  u1 :User  =User()
    //  var  u2 :User = User()

    var u1 = User.createUser()
    var u2 = User.createUser()
}

如何理解懒汉式单例   需要创建对象的时候,程序再去创建对象

2.工厂模式

工厂模式,根据用户的实际需求生产具体的对象

工厂模式中最基础的部分叫做实例工厂,代码如下

package cjdemo5.chapter3


//抽象的编程思想来实现
public abstract class Product {
    var name: String

    public Product(name: String) {
        this.name = name
    }

    //抽象方法
    public open func show(): Unit
}

//具体的A类商品的继承
public class ProductA <: Product {
    public ProductA(name: String) {
        super(name)
    }

    public override func show(): Unit {
        println(this.name)
    }
}

//具体的B类商品的继承
public class ProductB <: Product {
    public ProductB(name: String) {
        super(name)
    }

    public override func show(): Unit {
        println(this.name)
    }
}

//工厂类来根据用户的需求来构建具体的商品子类(A和B)   实例工厂类
public  abstract   class  Factory{

    public  open  func  createProduct():Product
}

public class FactortA<:Factory{
     public    func  createProduct():Product{

        return  ProductA("1.A商品")
     }
}

public class FactortB<:Factory{
     public    func  createProduct():Product{

        return  ProductB("2. B商品")
     }
}

public  func  exec3(){

    //用户要生产B商品
    var pb:Factory = FactortB()
    
    var product :  Product  = pb.createProduct()
    product.show()
}




那我们如何实现工厂模式的静态方法呢

我们可以将上述代码中的

public  abstract   class  Factory{

    public  open  func  createProduct():Product
}

public class FactortA<:Factory{
     public    func  createProduct():Product{

        return  ProductA("1.A商品")
     }
}

public class FactortB<:Factory{
     public    func  createProduct():Product{

        return  ProductB("2. B商品")
     }
}

修改为

 public static func createProduct(name: String): Product {
        if (name == "A") {
            p = ProductA(name)
        } else if (name == "B") {
            p = ProductB(name)
        }
        p
    }
}

即可实现工厂的静态方法。

修改后的代码如下

package cj1.chapter4

// 工厂模式,根据用户的实际需求生产具体的对象

//抽象的编程思想来实现
public  open  class Product {
    var name: String

    public Product(name: String) {
        this.name = name
    }

    public init()
    {
        this.name =""
    }

    
    public open func show(): Unit{}
}

//具体的A类商品的继承
public class ProductA <: Product {
    public ProductA(name: String) {
        super(name)
    }

    public override func show(): Unit {
        println(this.name)
    }
}

//具体的B类商品的继承
public class ProductB <: Product {
    public ProductB(name: String) {
        super(name)
    }

    public override func show(): Unit {
        println(this.name)
    }
}

public class CreateFactory {
    static var p: Product  = Product()
//工厂的静态方法
    public static func createProduct(name: String): Product {
        if (name == "A") {
            p = ProductA(name)
        } else if (name == "B") {
            p = ProductB(name)
        }
        p
    }
}

public  func  exec4(){


    var p: Product =CreateFactory.createProduct("A")
    p.show()
}

2.面向函数式编程

从易到难,展示几段代码,这是一个循序渐进的过程

package cj1.chapter5

//仓颉的函数的基本定义
public func execFun1() {
    println("仓颉的一个函数")
}

//仓颉的函数带参数,非命名参数
public func execFun2(a1: Int64) {
    //仓颉的方法的参数都是不可变变量,不能修改其值
    //a1  =100
}

//仓颉的函数带参数,命名参数 变量名!:类型
public func  execFun3(a1!:Int64)
{
     println("1.值为:${a1}")

}
//命名参数带默认值
public func  execFun4(a1!:Int64 =500)
{
        println("2.值为:${a1}")
}
//带返回值
public  func  exec5():Unit
{

}
public  func  exec6():Any
{
    
}
package cjdemo5
import  cjdemo5.chapter5.*

main(): Int64 {
    execFun3(a1:100)
    execFun4()
    return 0
}
package cj1.chapter6

//定义函数,有非命名参数和命名参数混合
public  func  execFun1(a1:Int64,b1:Int64)
{

}

public  func  execFun2(a1:Int64,b1!:Int64)
{

}

public  func  execFun3(a1!:Int64,b1!:Int64)
{

}
// 仓颉的方法的参数,
//第一个是命名参数,后面都是命名参数
//第一个是命名参数。后面是有非命名参数,编译报错
// public  func  execFun4(a1!:Int64,b1:Int64)
// {

// }

那么仓颉中命名参数的调用机制又是怎么样的呢?我想下面这一段代码就要可以解释清楚

package cj1.chapter7

public func  execFun1(a!:Int64,b!:Int64)
{
     println("1.${a},${b}")
}

public  func call()
{
      execFun1(b:200, a: 100)
}

那我们如何去验证函数的返回值呢。下面这一段代码就可以帮你解开疑惑

package  cjdemo5.chapter8

public  func  execFun1(a:Any):Any
{
    a
}

public  func call()
{
      var result =  execFun1("100")

      if(result  is Int64)
      {
         let  a =  (result as  Int64).getOrThrow()
         println("${a}")
      }
      else{

        println("不能转换")
      }
}

上一篇文章,我们讲过了方法重载,那么函数重载和同名变量,我们又该如何去书写呢

package cj1.chapter9


var   a = 100

public  func  show()
{
    println("result:${a}")
}
public func  show(a:Int64)
{
      var a1 = a
      a1 =200
      println("${a}")

}
public func call()
{
     show(10)
     show()
}

尤其要注意,函数重载不能函数名直接赋值

package  cj1.chapter12

public  func add(a:Int64,b:Int64):Int64{

     a+b
}

public  func add(a:String,b:String):String{

     a+b
}

public  func call()
{
   //面向函数式编程思想  一个函数可以等于一个变量  一个函数可以赋值给一个变量
   var f1 : (a1:Int64,b1:Int64)->Int64  = add 

    //f1是个函数变量
    println(f1(10,20))

    //错误
   // var  f2 = add  //自动类型推断,不能自行推断
    

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值