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 //自动类型推断,不能自行推断
}
5375

被折叠的 条评论
为什么被折叠?



