1

在旧的业务流程加入一个“拦截”,原来从前端表单提交到后台的处理逻辑延后处理,本质上是一个异步化的处理过程。
此时将表单参数存储到数据库,在适当的时刻“拦截”结束通过时调用原来的处理逻辑。
F代表表单参数,A代表控制器参数,

F --> A --> F' --> A';

思考以上的流程,
①F --> A,从前端到controller方法
②A --> F',将参数存储到数据库
③F' --> A', 从数据库取出原来的参数对象,希望A'能够完全表达A, A' == A,包括参数类型与顺序。

数据库数据表的设计

table at_form{
 id bigint,
 name varchar
 json  varchar
 type_token varchar?
}

Java的示例代码

public class AtFormApp {
        
        public static void main(String[] args) throws IOException, ClassNotFoundException {
                Person p = new Person();
                p.name = "Honey";
                p.age = 26;
                
                controlMethod1(p);
                controlMethod2();
                
                
        }
        
        static class Person {
                
                String name;
                int age;
        }
        static void controlMethod1(Person p) throws IOException {
                saveService(p, "p");
        }
        static void controlMethod2() throws IOException, ClassNotFoundException {
                AtForm atForm = query();
                ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(atForm.typeToken.getBytes()));
                Type type = (Type) ois.readObject();
                
                //Person type here
                Person p = new Gson().fromJson(atForm.json, type.getClass()); 
                
                realService(p);
        }
        static void saveService(Person p, String name) throws IOException {
                Type type = new TypeToken<Person>() {}.getType();
                String json = new Gson().toJson(p);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(type);
                oos.close();
                String typeToken = baos.toString();
                
                
                AtForm atForm = new AtForm();
                atForm.name = name;
                atForm.json = json;
                atForm.typeToken = typeToken;
                
                insert(atForm);
        }
        static void realService(Person p) {
                //good
        }
        
        static AtForm query() throws IOException {
                AtForm atForm = new AtForm();
                atForm.name = "p";
                atForm.json = "{\"name\":\"Honey\",\"age\":26}";
                Type type = new TypeToken<Person>() {}.getType();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(type);
                oos.close();
                String typeToken = baos.toString();
                atForm.typeToken = typeToken;
                return atForm;
        }
        //imitate insert behavior
        static int insert(AtForm atForm) {
                return 1;
        }
        
        static class AtForm {
                Long id;
                String typeToken;
                String name;
                String json;
                
                
        }
}

实际上在异步的处理过程中很难做到,

clipboard.png
这里的Person类型无法确定,调用realService方法也无法做到,需要反射?
PHP的示例代码

<?php
class AtFormApp {

    public function main() {
        $p = new Person();
        $p->name = 'Honey';
        $p->age = 26;

        $this->controlMethod1($p);
        $this->controlMethod2();
    }

    public function controlMethod1(Person $p) {
        $this->saveService($p, 'p');
    }

    public function controlMethod2() {
        $atForm = AtForm::findOne(['name' => 'p']);
        $p = unserialize($atForm->data);

        $this->realService($p);
    }

    public function saveService(Person $p, $name) {
        $atForm = new AtForm();
        $atForm->name = $name;
        $atForm->data = serialize($p);
        $atForm.save();
    }


    public function realService(Person $p) {
        // good
    }
}

class Person {
    public $name;
    public $age;
}

class AtForm() {
    public $id;
    public $name;
    public $data;

    public static findOne($condition) {}
    public save() {}
}

弱类型语言就没有这样的麻烦,
$p = unserialize($atForm->data);就能得到原来的Person实例对象。
后面调用realService($p)也很自然。虽然这里讨论的示例中只有一个参数,但是多个参数的情况下,PHP也能支持。

感谢@Tranch提供的PHP示例代码


Honwhy
7k 声望96 粉丝

神兽党有福了