diff --git a/Controller.qml b/Controller.qml
new file mode 100644
index 0000000000000000000000000000000000000000..eb1be466155c3ca0683fbc31f993afa07afd4b89
--- /dev/null
+++ b/Controller.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.15
+import QtQml.WorkerScript 2.15
+import io.qt.examples.backend 1.0
+
+QtObject {
+    id: root
+    objectName: "Controller.qml"
+    readonly property BackEnd backend: BackEnd {
+        objectName: root.objectName + "backend"
+        onUserNameChanged: {
+            console.log("[" + objectName + "].userName:" + userName)
+        }
+        onHandledResultsByWorker: {
+            console.log("[" + objectName + "].onHandledResultsByWorker(" + result + ")")
+        }
+        onHandledResultsByWorkerThread: {
+            console.log("[" + objectName + "].onHandledResultsByWorkerThread(" + result + ")")
+        }
+    }
+    readonly property WorkerScript worker: WorkerScript {
+        objectName: root.objectName + "worker"
+        source: "sampleWorkerScript.mjs"
+        onMessage: {
+            console.log("[" + objectName + "].onMessage(" + messageObject + ")")
+            console.log("[" + objectName + "].onMessage(" + messageObject.message + ")")
+        }
+    }
+
+}
diff --git a/View.qml b/View.qml
new file mode 100644
index 0000000000000000000000000000000000000000..40f52518d4a06fd19ab95b111ab0f15a51c4cff9
--- /dev/null
+++ b/View.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.15
+import QtQuick.Controls 2.15
+
+Column {
+    id: root
+    objectName: "View.qml"
+    property alias textField: textField
+    property alias buttonFuncA: buttonFuncA
+    property alias buttonFuncB: buttonFuncB
+    property alias buttonWS: buttonWS
+
+    TextField {
+        id: textField
+        placeholderText: qsTr("User name")
+    }
+    Button {
+        id: buttonFuncA
+        text: "call BackEnd.funcA"
+    }
+    Button {
+        id: buttonFuncB
+        text: "call BackEnd.funcB"
+    }
+    Button {
+        id: buttonWS
+        text: "call WorkerScript"
+    }
+}
diff --git a/main.qml b/main.qml
index fc6fb0a4d04a5a85d1f8f56f90d90e6a49e13492..73969e3f2e236e610408928bf3a7066f8d00b972 100644
--- a/main.qml
+++ b/main.qml
@@ -1,8 +1,5 @@
 import QtQuick 2.15
-import QtQuick.Window 2.15
 import QtQuick.Controls 2.15
-import QtQml.WorkerScript 2.15
-import io.qt.examples.backend 1.0
 
 ApplicationWindow {
     id: root
@@ -11,64 +8,51 @@ ApplicationWindow {
     height: 480
     visible: true
 
-    BackEnd {
-        id: backend
-        objectName: root.objectName + "backend"
-        onUserNameChanged: {
-            console.log("[" + objectName + "].userName:" + userName)
-        }
-        onHandledResultsByWorker: {
+    Connections {
+        objectName: root.objectName + ".Connections(" + target.objectName + ")"
+        target: controller.backend
+        function onHandledResultsByWorker(result) {
             console.log("[" + objectName + "].onHandledResultsByWorker(" + result + ")")
-            buttonFuncA.enabled = true
+            view.buttonFuncA.enabled = true
         }
-        onHandledResultsByWorkerThread: {
+        function onHandledResultsByWorkerThread(result) {
             console.log("[" + objectName + "].onHandledResultsByWorkerThread(" + result + ")")
-            buttonFuncB.enabled = true
+            view.buttonFuncB.enabled = true
         }
     }
-    WorkerScript {
-        id: worker
-        objectName: root.objectName + "worker"
-        source: "sampleWorkerScript.mjs"
-        onMessage: {
+    Connections {
+        objectName: root.objectName + ".Connections(" + target.objectName + ")"
+        target: controller.worker
+        function onMessage(messageObject) {
             console.log("[" + objectName + "].onMessage(" + messageObject + ")")
             console.log("[" + objectName + "].onMessage(" + messageObject.message + ")")
-            buttonWS.enabled = true
+            view.buttonWS.enabled = true
         }
     }
 
-    Column {
+    Controller {
+        id: controller
+        objectName: root.objectName + ".controller"
+    }
+
+    View {
+        id: view
+        objectName: root.objectName + ".view"
         anchors.centerIn: parent
         spacing: 10
-        TextField {
-            text: backend.userName
-            placeholderText: qsTr("User name")
-            onEditingFinished: backend.userName = text
-        }
-        Button {
-            id: buttonFuncA
-            text: "call BackEnd.funcA"
-            onClicked: {
-                backend.funcA()
-                enabled = false
-            }
-        }
-        Button {
-            id: buttonFuncB
-            text: "call BackEnd.funcB"
-            onClicked: {
-                backend.funcB()
-                enabled = false
-            }
-        }
-        Button {
-            id: buttonWS
-            text: "call WorkerScript"
-            enabled: worker.ready
-            onClicked: {
-                worker.sendMessage({ 'message': 'call WorkerScript' })
-                enabled = false
-            }
+        textField.text: controller.backend.userName
+        textField.onEditingFinished: controller.backend.userName = textField.text
+        buttonFuncA.onClicked: {
+            controller.backend.funcA()
+            buttonFuncA.enabled = false
+        }
+        buttonFuncB.onClicked: {
+            controller.backend.funcB()
+            buttonFuncB.enabled = false
+        }
+        buttonWS.onClicked: {
+            controller.worker.sendMessage({ 'message': 'call WorkerScript' })
+            buttonWS.enabled = false
         }
     }
 }
diff --git a/qml.qrc b/qml.qrc
index 8297584a3897f878169196b9663a5813ac3e13d5..3d0f4c634e0eda380ed5014f28ef1532d7a83226 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -2,5 +2,7 @@
     <qresource prefix="/">
         <file>main.qml</file>
         <file>sampleWorkerScript.mjs</file>
+        <file>View.qml</file>
+        <file>Controller.qml</file>
     </qresource>
 </RCC>