1.设计模式
上次介绍了单例设计模式和工厂模式,我们这些学习的人一定要熟悉手写单例模式和工厂模式,并能够说明其作用。
这篇文章接着代理模式的讲解,所谓代理模式,就是代理一个真实的业务实现。
在生活中,代理模式无处不在,租房子是个业务实现,中介就是一个代理,代理租房子的业务实现。
1.中介会去检查租房子的房子的情况是否满足需求 即所谓 前置代理 前置服务
2.租房子业务实现
3.中介会在租房子之后去定期检查房子的设备和安全及其它服务。即所谓 后置代理 前置服务
代理是很专业的,业务精通,业务共享机制。
面向对象的继承,继承是作用减少子类的变量和方法,属性的冗余,怎么减少的,是通过继承关系<:,父类抽取子类中共有的变量和方法,属性。
代理的设计模式,是抽取业务的能力,形成切面的共享机制。
通过对目标实现方法的前置和后置控制,形成切面编程,通过代理模式实现,可以形成业务控制的切面工具类,减少控制方法的冗余。
业务实现类 --- 租房子
业务控制类 (切面类)--- 对租房子、相亲业务、跑外卖等业务的检查。 通过切面类的共享减少业务检查的冗余。
类似于支付的业务控制类
切面的实现在仓颉语言中可以基于两种方式去实现:
1.面向对象的编程思想
参考代码如下
package cjchapter5.chapter1
//代理设计模式通过面向对象编程思想来实现
//业务类的接口描述
public interface Operator{
public func operatorHouse():Unit
}
//真实类的实现
public class OperatorUser <: Operator{
public func operatorHouse():Unit{
println("实现租到三室一厅的带花园的房子")
}
}
//中介类,就是一个代理实现类
public class ProxyAny <:Operator{
var op : Operator
ProxyAny(op : Operator) // 接口动态绑定的子类
{
this.op = op
}
public func operatorHouse():Unit
{
this.beforeCheck() // 方法的切面 前置切面
this.op.operatorHouse() //业务的实现 租到满足需求的房子
this.afterService() // 方法的切面 后置切面
}
public func beforeCheck()
{
println("前置的检查是否符合要求")
}
public func afterService()
{
println("后置的服务能够体现能力")
}
}
public func exec()
{
// 代理类代理真实类完成初始化
var proxy : ProxyAny = ProxyAny(OperatorUser())
//代理类完成业务实现
proxy.operatorHouse()
}
代码的实现结果图如下
2.面向函数式的编程思想
示例代码如下
package cj6.chapter2
import std.convert.Parsable
//面向函数式编程思想来实现代理
//目标的业务方法
public func action(str: String) {
println("实现完成了${str}这个业务")
}
//前置代理方法1 检查手机号码
public func beforeCheck1(phone: String): Bool {
if (phone.size == 11) {
true
} else {
false
}
}
//前置代理方法2 检查年龄
public func beforeCheck2(age: String): Bool {
if (Int16.parse(age) > 18) {
true
} else {
false
}
}
// 函数类型:()->返回类型 函数的参数的抽象
// lambda表达式:{参数 =>具体的实现 }
//可以代理任何一个业务
public func operatorProxy(param: String, before: (String) -> Bool, actionFun: (String) -> Unit, str: String) {
if (before(param)) {
actionFun(str)
} else {
println("对不起,不能够继续目标任务${str}")
}
}
public func exec() {
operatorProxy("13913321086", beforeCheck1, action, "开通这个5G通话")
operatorProxy("16", beforeCheck2, action, "开结婚证明")
}
2.枚举类型和Option类型和解析
下面给出一部分例子,希望大家可以自己学习 体会
package cj7.chapter1
//仓颉的类型:1.基本数据类型(值类型) Int16等, struct类型
//2. 引用类型,类,接口,枚举类型
// 隐式的函数类型,好处可以指向相同的参数和返回类型的函数实现 是不是一个指向,一个绑定,一个代理
public interface A {
public func run(): Unit
}
public enum Famialy {
| FATHER | MONTHER | SON
public func exec1() {
}
public static func exec2() {
}
}
public enum UserType <: A {
| F1 | F2 | F3
public func run(): Unit {
}
}
package cj7.chapter2
public enum Fami {
| FATHER(Int64) | MONTHER(Int64, String) | SON(Int64, Int64)
}
public func execFun(value: Fami): String {
//基于枚举类型的模式匹配
let result = match (value) {
case FATHER(age) => "父亲的年龄是:${age}"
case MONTHER(age, likeName) => "母亲的年龄是:${age},喜欢吃${likeName}"
case SON(age, score) => "儿子的年龄是:${age},分数是${score}"
}
result
}
public func exec() {
println(execFun(Fami.SON(20,100)))
}
package cj7.chapter3
public enum operatorFun {
| ADD | SUB
}
public func add(a: Int64, b: Int64) {
a + b
}
public func sub(a: Int64, b: Int64) {
a - b
}
public func execFun(fn: operatorFun) {
match (fn) {
case ADD => add
case SUB => sub
}
}
public func exec()
{
execFun(operatorFun.ADD)(20,30)
}
package cj7.chapter4
//Option类型
/**
public enum Option<T>{
|Some(T)|None
}
*/
public func exec1() {
var str: String = "Hello"
//str这个字符串中e的下标a
//Option<T>, 就是一个枚举类型 <T> type, 泛型,就是一个统一的类型
//Option<Int64> == ?Int64
var currentIndex1: Option<Int64> = str.indexOf("a")
var currentIndex2: ?Int64 = str.indexOf("e")
//1.解析Option类型的值,有下列几种方法
//1.1 模式匹配解析
match (currentIndex1) {
case Some(index) => println("下标是:${index}")
case None => println("下标不存在")
}
//1.2 getOrThrow()
let index = currentIndex2.getOrThrow()
println("下标是:${index}")
//3. if let
if (let Some(index) <- currentIndex2) {
println("下标是:${index}")
}
}
package cj7.chapter5
public open class Person {
var name: String = ""
}
public class Student <: Person {
var sname: String = ""
}
public class Other {}
public func matchAny(stu: Option<Student>) {
let result = match (stu) {
case Some(T) => "1.这个是学生类"
case None => "2.这个不是学生类"
}
result
}
public func exec() {
println(matchAny(Student()))
var p: Person = Person()
p = Student() //体会有这行代码,就是动态绑定,有和没有的区别???
println(matchAny(p as Student))
println(matchAny(Other() as Student))
}
package cj7.chapter6
public open class Person {
var name: String = ""
}
public class Student <: Person {
var sname: String = ""
}
public class Other {}
public func matchAny(stu: ?Student) {
let result = match (stu) {
case Some(T) => "1.这个是学生类"
case None => "2.这个不是学生类"
}
result
}
public func exec() {
println(matchAny(Student()))
var p: Person = Person()
//p = Student()
println(matchAny(p as Student))
println(matchAny(Other() as Student))
}
package cj7.chapter7
public func exec() {
var name = "Hello Nanjing"
var currentIndex: ?Int64 = name.indexOf("f")
let indexValue = currentIndex ?? -1
println("下标为:${indexValue}")
}
public class User{
var name :String
init(name:String)
{
this.name = name
}
}
public func exec1() {
var u1:Option<User> = Some(User("李欣"))
println(u1?.name)
var val:?String = u1?.name
var name = val.getOrThrow()
println("${name}")
if(let Some(name)<-u1?.name)
{
println("${name}")
}
}
通过本文的学习,相信大家对于设计模式,以及枚举类型和Option类型有了更深的理解,相信大家能在此基础上完成更多更好更复杂的程序的。