Showing posts with label Software Development. Show all posts
Showing posts with label Software Development. Show all posts

Angular module include module

module ใน Angular เราสามารถไปเรียก module อื่นๆ ได้

ตัวอย่าง

HomeModule.js
1
2
3
4
5
var app = angular.module('HomeModule', []);

app.controller('HomeController', function($scope) {
 $scope.name = 'AngularJS';
});

จากนั้นเขียน module ที่ต้องการจะเรียก module

app.js
1
var app = angular.module('A02', ['HomeModule']);

จากนั้นก็เขียน html ในการเรียก angular ปกติ แต่จะต้องใส่ script ทุกไฟล์ที่ module เรียกไว้ให้ครบด้วยนะค่ะ

02.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html ng-app="A02">
<head>
 <title>02</title>
 <script src="js/angular.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="app/02/app.js" type="text/javascript" charset="utf-8"></script>
 <script src="app/02/HomeModule.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
 <div ng-controller="HomeController">
  <p>{{ name }}</p>
 </div>
</body>
</html>

แค่นี้ก็สามารถเรียกใช้เป็น module ได้

จบ.

Angular factory

คราวที่แล้วเราสร้าง service ไปแล้ว คราวนี้จะมาดูกันว่านอกจาก service แล้ว เราสามารถเขียนเป็น factory ก็ได้เหมือนกัน

app.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var app = angular.module('A05', []);

app.factory('CalculatorFactory', function() {
 var currency = 'US$';

 function resultWithCurrency(value) {
  return currency + ' ' + value;
 }

 return {
  name: 'Calculator Factory',
  calculate: function(value) {
   return resultWithCurrency(value * value);
  }
 }
});

app.controller('FactoryController', function($scope, CalculatorFactory) {
 $scope.name = CalculatorFactory.name;
 $scope.calculate = function() {
  console.log(CalculatorFactory.calculate(10));
 }
});

คราวที่แล้วเราเขียน function เดียวกันแต่ใช้ผ่าน service ซึ่งไม่มีการ return อะไร แต่ว่าผูกค่าหรือ function ไว้กับ this แต่ถ้าเป็น factory จะมีการ return ค่า

file.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html ng-app="A05">
<head>
 <title>05</title>
 <script src="js/angular.min.js" type="text/javascript" charset="utf-8" ></script>
 <script src="app/05/app.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div ng-controller="ConstantController">
 <p><b>Constant</b>: {{ viewPath }}</p>
</div>
<hr>

<div ng-controller="FactoryController">
 <p><b>Factory</b>: {{ name }}</p>
 <p><button ng-click="calculate()">{{ name }}</button></p>
</div>
</body>
</html>

แต่ตอนที่เรียกใช้ ไม่ว่าจะเป็น service หรือ controller จะเรียกไม่ต่างกัน

จบ.

Reference:
AngularJS: Service vs provider vs factory

Angular service

คราวที่แล้วเราเริ่มต้นด้วย module กับ controller ไปแล้ว ถ้าเราจะเขียนให้สวยก็เขียนใส่ service หรือ factory สำหรับการเรียกใช้ในหลายๆ controller (คิดว่าน่าจะเหมือนกับ MVC)

ตัวอย่างการเขียน service และการเรียกใช้ผ่าน controller

app.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
var app = angular.module('A05', []);

app.service('CalculatorService', function() {
 var currency = 'US$';

 function resultWithCurrency(value) {
  return currency + ' ' + value;
 }

 this.name = 'Calculator Factory';
 this.calculate = function(value) {
  return resultWithCurrency(value * value);
 };
});

app.controller('ServiceController',
function($scope, CalculatorService) {
 $scope.name = CalculatorService.name;
 $scope.calculate = function() {
  console.log(CalculatorService.calculate(10));
 }
});

ใน service เราผูกค่า หรือ function ที่เราต้องใช้ไปกับตัว service เอง (this) แล้วค่อยให้ controller มาเรียกใช้ service ไปอีกที โดยจะต้องผ่านตัวแปร $scope เพื่อให้หน้า client สามารถเห็นค่าเหล่านี้

file.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html ng-app="A05">
<head>
 <title>05</title>
 <script src="js/angular.min.js" type="text/javascript" charset="utf-8" ></script>
 <script src="app/05/app.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div ng-controller="ServiceController">
 <p><b>Service</b>: {{ name }}</p>
 <p><button ng-click="calculate()">{{ name }}</button></p>
</div>
</body>
</html>

ในหน้าเวป เราก็เรียกใช้ controller เหมือนปกติ

จบ.

Angular module and controller

function หรือ global API คือคำสั่งที่เรียกผ่าน object angular ทั้งหมด ซึ่งมีด้วยกันหลายคำสั่ง ซึ่งตามหลักที่ดี ก็คือเขียนเป็น module และใน module แยกเป็นแต่ละ controller เพื่อใช้เรียก service หรือ factory อีกที (ส่วนตัวเข้าใจว่า service จะเป็นการสร้าง object service ใหม่ แต่ factory เป็นการเรียก service นั้นๆ โดยไม่สร้างใหม่)

ซึ่งเราจะแยกไฟล์ AngularJS แยกไว้ต่างหาก และในไฟล์ HTML ก็จะ include script เข้ามาโดยผ่าน directive ng-app และ ng-controller

ตัวอย่างไฟล์ AngularJS ที่เขียนเป็น module และการเรียนใช้ controller ภายใน module

app.js
1
2
3
4
5
6
// create angular model A02
var app = angular.module('A02', []);

app.controller('HomeController', function($scope) {
 $scope.name = 'AngularJS';
});


02.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!DOCTYPE html>
<html ng-app="A02">
<head>
 <title>02</title>
 <script src="js/angular.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="app/02/app.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
 <div ng-controller="HomeController">
  <p>{{ name }}</p>
 </div>
</body>
</html>

อันนี้ถือเป็นการเริ่มทำความคุ้นเคยกับการเขียน Angular ซึ่งจะเห็นว่า เราก็จะเขียน Angular function ต่างๆ ไว้ในไฟล์แยกเหมือน javascript ตัวหนึ่ง แล้วเรียกใช้ เพียงแต่การเรียกใช้เราจะเรียกผ่าน Angular directive ต่างๆ

จบ.

Basic Angular Directive

นอกจาก Angular Expression แล้ว เรายังสามารถใช้ Angular Directive สำหรับการผูกข้อมูล (binding) โดย directive ที่ใช้ทั่วไป มีดังนี้

ng-init

สำหรับการกำหนดค่าเริ่มต้นให้กับตัวแปร


1
2
3
4
5
6
7
<div ng-init="price=50;qty=25">

    <p>Amount: {{ price * qty }}</p>
    <p>Amount: {{ price * qty | currency }}</p>
    <p>Amount: {{ price * qty | currency:'THB' }}</p>

</div>

ตัวอย่างจะเป็นการกำหนดค่าตัวแปร price กับ qty

ng-model

เป็นการผูกค่าตัวแปรกับ input tag ใน HTML

1
2
<input type="text" ng-model="name">
<p>Name: {{ name }}</p>

ในตัวอย่างเป็นการผูก input text กับตัวแปรชื่อ name ซึ่งในการผูกค่า อาจจะใช้เป็นตัวแปรแบบ primitive หรือว่า object ก็ได้

หรืออีกตัวอย่างหนึ่ง เป็นการผูกค่าตัวแปร like กับ input radio

1
2
3
4
5
<div ng-init="like='Yes'">
    <input type="radio" value="Yes" ng-model="like">I like
    <input type="radio" value="No" ng-model="like">I don't like
    <p>Answer: {{ like }}</p>
</div>


หรือ ผูกค่ากับ select tag

1
2
3
4
5
6
7
<select ng-model="food">
    <option value="Rice">Rice</option>
    <option value="Noodle">Noodle</option>
    <option value="Soup">Soup</option>
</select>

Your Order: {{ food }}

ng-click

เนื่องจากใน javascript ตัวแปรนอกจากจะเก็บค่าต่างๆ หรือว่าใช้เก็บเป็น object ของ property (ซึ่งก็เป็นการเก็บค่าอยู่ดี) ได้แล้ว ยังสามารถกำหนดให้ตัวแปรมีค่าเก็บ function ได้ด้วย เสมือนกับ function เป็นค่าๆ หนึ่ง ดังนั้นเราจึงใช้คุณสมบัตินี้มากำหนดพฤติกรรมของการทำงานในเอกสาร HTML ได้

ตัวอย่างกำหนดการคำนวณให้กับปุ่ม


1
2
<button ng-click="counter=counter+1">Count</button>
<p>Counter: {{ counter }}</p>

ng-if

เป็น directive ที่ใช้กำหนดเงื่อนใขให้กับ HTML

ตัวอย่างกำหนดให้แสดงหรือไม่แสดงข้อความ (รวมถึงสีพื้น)

1
2
3
4
5
6
<div ng-init="show=true">
    <p ng-if="show" style="background-color: red;">Red</p>
    <p ng-if="!show" style="background-color: green;">Green</p>

    <button ng-click="show=!show">Toggle</button>
</div>

นอกจากนี้ยังมี

  • ng-repeat
  • ng-app
  • ng-controller


พื้นฐานของ Angular Directive ก็จะมีประมาณนี้ เอาไว้ค่อยมาต่อกันนะค่ะ

Reference:
ng Directive

Angular Expression

Angular สามารถเขียน code ลงไปได้ 2 รูปแบบ คือ Angular Expression และ Angular Directive ซึ่งสำหรับ Angular Expression จะมีลักษณะคล้ายๆ การเขียน JavaScript ลงไปยัง {{ script }}

ซึ่งตัวอย่างที่สามารถเขียนลงไปได้ก็อย่างเช่น

  • {{ 'Hello World' }} - แสดงข้อความ
  • {{ 1 + 2 }} - คำนวณค่าคงที่
  • {{ a + b }} - คำนวณค่าจากตัวแปร
  • {{ user.name }} - แสดงค่า property จาก object
  • {{ items[index] }} - แสดงค่าจาก array
แต่จะแตกต่างจาก JavaScript คือ
  • JavaScript อ้างอิงจาก ตัวแปร window แต่ Angular จะใช้ $scope object
  • ตัวแปรไหนที่ไม่อยู่ใน scope หรือไม่เคยกำหนดค่ามาก่อน Angular จะใส่ให้เป็น null หรือเริ่มต้น เช่น ถ้าเป็นตัวเลขก็จะใส่เป็นค่า 0 เป็นต้น
  • ไม่สามารถใส่ Control Flow ได้ เช่น loop, if
  • ไม่สามารถสร้าง function ได้
ไว้โอกาสหน้าจะมาต่อกันเรื่อง Directive

Reference:

AngularJS 101

AngularJS เป็น lib ของ javascript ที่จะช่วยให้การเขียนได้ง่ายขึ้น (เข้าใจว่า) ดังนั้นการเขียน Angular JS จึงเหมือน javascript ทั่วๆ ไป แต่อาจจะมีการรูปแบบการเขียน (syntax) ที่แตกต่างออกไป

การจะเริ่มเขียน AngularJS สามารถเขียนได้บนไฟล์ .html ทั่วๆ ไป โดยเพิ่มการอ้างอิง AngularJS lib และใส่ module เข้าไป


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html ng-app>
    <head>
        <meta charset="utf-8">
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js" type="text/javascript" charset="utf-8"></script>
        <title>test</title>
    </head>
    <body>
        {{ 'Hello World '}}
    </body>
</html>

ส่วนที่เพิ่มเข้าไปคือ "ng-app" ใน html tag และ script ที่อ้างไปยัง AngularJS lib เพียงเท่านี้ก็เป็นอันเสร็จ คือไฟล์ html นี้สามารถเพิ่ม code ส่วนที่เป็น Angular เข้าไปได้แล้ว ซึ่งในตัวอย่างจะเป็นการแสดงข้อความ 'Hello World' ผ่านทาง AngularJS

เอาหอมปากหอมคอแค่นี้ก่อน ไว้มาดูตอนต่อไป


ติดตั้ง Sublime และ Package Control

Sublime เป็น text editor ตัวหนึ่งคล้ายๆ กับ Notepad++ แต่ว่าเป็นโปรแกรมที่มีอยู่ทั้งใน Windows, MacOS ก็เลยทำให้หลายคนใช้กัน เพราะว่าจะได้สภาพแวดล้อมที่คล้ายกันทั้งใน PC และ Mac

การติดตั้ง Sublime ก็ไม่ได้ยุ่งยากอะไร Search มาแล้วก็สามารถเลือกติดตั้งกันได้เลยทั้ง Windows, Mac แต่การจะใช้ Sublime ให้เป็นประโยชน์จะไม่ได้สิ้นสุดแค่นั้น จะต้องหา package อื่นๆ มาติดตั้งเพิ่มเติม เพื่อให้ Sublime สามารถทำงานได้มีประสิทธิภาพมากขึ้น ดังนั้นเมื่อติดตั้ง Sublime แล้ว สิ่งที่ควรติดตั้งตามมาคือ Package Control เพื่อให้สามารถติดตั้ง package อื่นๆ ต่อไปได้ ซึ่งวิธีติดตั้งสามารถเข้าไปดูจาก https://packagecontrol.io/installation ได้ค่ะ แต่สั้นๆ ก็คือไปที่เมนู View > Show Console แล้ว copy text จากในหน้าเวปนั้น ไปใส่กด enter เป็นอันเสร็จค่ะ 

หลังจากนั้นสามารถกด Ctrl + Shift + p เพื่อติดตั้ง package อื่นๆ ต่อไป ซึ่ง package อื่นๆ ก็อย่างเช่น
  • Emmet เป็นตัวช่วยให้การเขียนโปรแกรมง่ายขึ้น เช่น สามารถเขียน table>tr>td แล้วก็กด tab ได้เลย มันก็จะขึ้นมาเป็น tag table ทั้งหมดให้เรียบร้อย
  • HTML5 เข้าใจว่าเป็นตัวที่ทำให้ Sublime รู้จัก tag HTML5 จะได้แสดงสีอย่างสวยงาม
  • SublimeCodeIntel ใช้สำหรับ autocomplete code โดยเมื่อพิมพ์เข้าไปแล้วจะแสดงเป็น pop up มาให้เลือก
นอกจากนี้ยังมี package สำหรับแต่ละภาษาเช่น Python เพื่อให้แสดงสีตามแต่ละภาษาด้วย 

ก็สรุปจบการแนะนำ Sublime พร้อมการติดตั้งไว้เท่านี้

ติดตั้ง Git เชื่อมต่อกับ GitHub

1. สมัคร GitHub ที่ https://github.com/
เมื่อสมัครแล้ว GitHub จะส่งเมล์มา verify email ที่เราใส่ไป เพราะจะใช้เป็น email ในการส่งการเปลี่ยนแปลงของ project ที่เราเข้าร่วมมาให้ ให้เราทำการ verify ให้เรียบร้อย

2. download โปรแกรมจาก http://git-scm.com/

3. double click เพื่อติดตั้ง

4. สร้าง ssh key สำหรับเชื่อมต่อกับ GitHub ในการ push, pull ไฟล์
โดยการ คลิ๊กขวาที่ directory ใดๆ เลือก Git Bash



เมื่อเข้าหน้า command ให้ใช้คำสั่ง

$ ssh-keygen

ซึ่ง git จะไปสร้าง key file ใน home directory\.ssh ของ user ซึ่งสำหรับ Windows จะอยู่ที่ C:\Users\[username]\.ssh

ซึ่งไฟล์จะประกอบด้วย

  • known_hosts เป็น ip และ public key ของ GitHub
  • id_rsa ซึ่งเป็น private key
  • id_rsa.pub เป็น public key

5. add public key ใน GitHub
โดย login เข้า GitHub
เลือก Setting
เลือก SSH Keys
กดปุ่ม Add SSH Key


ตั้งชื่อ title ซึ่งเป็นอะไรก็ได้
copy content ของ id_rsa.pub ใส่ใน key

โดย 1 user จะสามารถมี key ที่เครื่องใดๆ ได้ 1 key เท่านั้น แต่ถ้า 1 user มีหลายเครื่องก็จะต้องสร้าง key สำหรับแต่ละเครื่องในการติดต่อกับ GitHub

6. ตั้งค่า user name, email
ใน Git Bash

$ git config --global user.name "xxx"
$ git config --global user.email "xxx@xxx"


เท่านี้ก็น่าจะเสร็จเรียบร้อยสำหรับการติดตั้งค่ะ





.Net constants, Settings.settings, Resources.resx

ไม่รู้คนอื่นเป็นหรือเปล่า แต่เรามีความสับสนในการกำหนดค่าต่างๆ ในโปรแกรม ไม่รู้ว่าควรจะกำหนดยังไงดี

  • กำหนดเป็นค่าคงที่ใน Code
  • กำหนดใน Settings.settings
  • กำหนดใน Resources.resx
ก็ไปอ่านเจอบทความหนึ่ง ซึ่งรู้สึกว่าอ่านแล้วกระจ่างมาก เลยแปลมาให้กัน สำหรับใครที่อยากอ่านต้นฉบับดูที่ที่ลิงค์ท้ายบทความค่ะ

เค้าบอกว่าเกณฑ์ในการเลือกว่าควรจะกำหนดค่าอะไรไว้ยังไงมีดังนี้
  1. ถ้าเป็นค่าที่ไม่ได้ให้ผู้ใช้แก้ไข และเกี่ยวข้องกับ class ใด class หนึ่งโดยเฉพาะ ให้กำหนดเป็นค่าคงที่ใน class นั้นๆ
  2. ถ้าเป็นค่าที่ไม่ได้ให้ผู้ใช้แก้ไข แต่เกี่ยวข้องกับหลาย class ให้กำหนดเป็นค่าคงที่ใน class กลางของโปรเจค
  3. ถ้าเป็นค่าที่ให้ผู้ใช้แก้ไขได้ ให้กำหนดใน Settings.settings.
  4. ถ้าเป็นค่าที่ต้องแก้ไขโดยขึ้นกับ locale ให้กำหนดใน Resources.resx
  5. ถ้าเป็นค่าที่ต้องเปลี่ยนแปลงตามกลุ่ม (เข้าใจว่า เช่นค่าที่กำหนดสำหรับแต่ละหน้าจอ เหมือนที่เรากำหนด label ในหน้าจอ) ก็ให้กำหนดใน Resource.resx ตามโฟลเดอร์
และในบทความก็สรุปว่า Resources.resx จะกำหนดได้ก่อน build เท่านั้น ผู้ใช้ไม่สามารถเปลี่ยนค่าได้ ในขณะที่ Settings.settings สามารถแก้ได้โดยผู้ใช้ แต่ Settings.settings จะไม่เปลี่ยนตาม locale เหมือนกับ Resources.resx

References:

การ Generate Entity class จาก Entity Framework

ที่เราใช้อยู่ขณะนี้เป็น EF 6 นะค่ะ

1. คลิ๊ก Add > New Item... ที่โปรเจค


2. เลือก ADO.NET Entity Data Model และตั้งชื่อ ซึ่งจะเป็นชื่อของ .edmx ไฟล์


3. เลือกวิธีที่จะได้ diagram มา ซึ่งเราเลือกเป็น Empty EF Designer model ซึ่งจะได้ diagram เปล่าๆ มาแล้วมาใส่ entity ต่างๆ เองค่ะ


4. จากนั้นก็สร้าง Entity โดยใช้ Toolbox ด้านข้าง
5. หลังจากนั้นก็ถึงวิธีการ generate Entity โดยคลิ๊กขวาที่ diagram เลือก Generate Database from Model...


6. ถ้าเป็นการ generate ครั้งแรก VS จะขึ้นหน้าต่างมาให้เราสร้าง Connection string โดยเราจะต้องเลือกฐานข้อมูลที่เราต้องการจะให้สร้าง Entity (ทั้งนี้มันจะไม่ได้ไปสร้าง table หรืออะไรในฐานข้อมูลนั้นๆ หรอกนะค่ะ แค่เลือกเพื่อเอาไปสร้าง Connection string เฉยๆ เราจะต้องไปสร้าง table เองค่ะ)

เมื่อเสร็จแล้ว มันจะให้เรายืนยันว่าจะให้บันทึก password ของฐานข้อมูลใน Connection string หรือเปล่า ซึ่งเราจะให้มันบันทึกหรือไม่ก็ได้ค่ะ

7. เราจะได้

  • file .sql มา สำหรับไป execute ในฐานข้อมูล
  • ได้ Entity Container .cs 
  • ได้ Entity .cs 
เป็นอันเสร็จค่ะ

หมายเหตุ
- ใน Entity Framework ไม่สามารถสร้าง unique key ที่ไม่ใช่ primary ได้ค่ะ ตามลิงก์

.net unable to cast of type dbquery`1 [] to type objectquery

ช่วงนี้กำลังศึกษา .Net Entity Framework อยู่ค่ะ

แล้วก็เลยลองทำ ADO.Net Entity Framwork Quick Start ดูค่ะ

ก็ทำตามไปเรื่อยๆ แต่มาสะดุดเอาตรง (เราใช้ EF 6.1 ค่ะ ตามที่ได้ Nuget ออกมา)

this.departmentList.DataSource = ((ObjectQuery)departmentQuery).Execute(MergeOption.AppendOnly);


ซึ่งมี Exception ตอน runtime ค่ะ ซึ่งตามชื่อหัวข้อเลยค่ะ มัน cast จาก DbQuery ไป ObjectQuery ไม่ได้ ก็หาอยู่นานค่ะ เพราะก็เพิ่งจะอ่าน Quick Start อ่ะเน้อะ จะไปรู้เรื่องอะไร

สรุปเลยละกันค่ะ คือมัน cast ไม่ได้ค่ะ ถูกแล้ว เพราะ edmx มันสร้างเป็น DbSet ซึ่ง query ที่ได้จะเป็น DbQuery ก็ต้องใช้มันทั้งแบบนั้นค่ะ แต่แล้วใช้แบบนั้นมันใช้ยังไงฟร่ะ ก็หากันต่อไปค่ะ ก็มามั่วเองจนได้ ซึ่งที่ถูกควรจะเป็น

this.departmentList.DataSource = departmentQuery.ToList();

จึงแจ้งมาเผื่อใครจะเป็นเหมือนกัน

Reference:
ADO.Net Entity Framwork Quick Start

Entity Framework 4.1: Unable to cast from DbQuery to ObjectQuery

C# Format Item Syntax

สำหรับคนที่เพิ่งมาเรียนรู้ C# ใหม่ๆ เวลาเห็นคำสั่ง Console.Write หรือ Console.WriteLine (ซึ่งเราใช้มากสำหรับการทดสอบระบบ) อาจจะเห็น string แปลกๆ ที่อยู่ใน { } ซึ่งจะเขียน Format Item Syntax ซึ่งมี syntax ง่ายๆ คือ

{ index[,alignment][:formatString]}

index เป็น ลำดับของตัวแปรที่เป็น parameter ต่อท้ายมา
alignment ถ้าเป็น ค่าบวก คือชิดขวา ค่าลบ ชิดซ้าย
formatString ก็คือเป็น format ที่จะให้แสดงออกมานั้นเอง 

ตัวอย่าง


Console.Write("Name = {0}, hours = {1,1:hh}", myName, DateTime.Now);

{0} ก็จะแสดงเป็นค่าของ myName
{1:hh} จะแสดงเป็นค่า DateTime.Now โดยแสดงเป็น ชั่วโมง ชิดขวา

Reference:
Composite Formatting

Missing item ADO.Net Data Entity Model

สำหรับใครที่จะใช้ Entity Framework แล้วเป็นเหมือนเรา คือพยายามตามหา item ADO.Net Data Entity Model แต่ว่าไม่มี


หาอ่านอยู่หลายที่ก็ยังไม่รู้ว่าวิธีแก้ทำยังไงนะค่ะ ติดตั้ง EntityFramework package จาก NuGet ก็แล้ว ก็ยังไม่ได้

ง่ายมากค่ะ ให้หา Entity Framework Tools มาลงค่ะ (ลิงค์ที่ให้ไว้เป็นของ version 6 ค่ะ) แค่นั้นเอง ไม่ได้เกี่ยวกับการ install Entity Frameowork package เลยแม้แต่น้อย 


Test run C# console application

เพิ่งจะเรียน C# ค่ะ เปิดใช้ Visual Studio ด้วยความงุนงง เพราะที่เคยใช้มันตั้งแต่เมื่อสมัยยังละอ่อน ยังไม่มี .Net Framework นู้นเลย และโปรแกรมแรก Hello World ซึ่งเป็น Console Application เขียนเสร็จ เอาละซิ จะเทสต์ยังไงฟร่ะ พอกด Start มันก็จะทำงานเปิด Console ขึ้นมาอย่างรวดเร็ว และจบไปอย่างรวดเร็ว สรุปว่า Hello World ของตรูสำเร็จม่ะเนี้ยะ มองไม่ทัน "-__-

และแล้วก็ได้มาเจอคำสั่ง หยุดหน้าจอ (ไม่ใช่ล่ะ) คือเป็นคำสั่งที่รอรับแป้นพิมพ์ก่อนด้วย

Console.ReadKey() 

โอ้ว เห็น Hello World แล้ว

บทเรียนต่อไปค่ะ โปรแกรมสำหรับรับ argument เขียนเสร็จ เอ่อ ... แล้วมันจะใส่ argument ยังไงฟร่ะ ตอนเทสต์ หาไปค่ะ หายังไงก็หาไม่เจอ (เพราะมันไม่มี) และได้มาพบกับ Tools Command Prompt บน Visual Studio Tools ค่ะ ซึ่งจะมาพร้อมกับตอนที่เราลง VS เลยค่ะ


แต่อ้าว.. แล้วนู๋จะต้องสั่ง compile บน Command Prompt หรือนี่... จริงๆ ก็ไม่ยากนะค่ะ แต่ แล้วตรูจะมี VS ไว้ทำแป๊ะอาราย แต่ก็นึกขึ้นได้ว่า ใน VS มันมี Build นี่หว่า Build แล้วไปไหนหว่า อันนี้หาไม่ยากค่ะ ไปส่องๆ ใน directory ที่เราเขียนโปรแกรมนะแหละ มันจะมี directory ชื่อ bin ค่ะ ถ้าเราสร้าง project เป็น Console Application พอ build แล้วก็จะได้ .exe อยู่ใน directory นี่แหละค่ะ เช่น ถ้าเราสร้าง solution ชื่อ Example และ project ชื่อ ConsoleTutorial ไว้ ก็จะได้ .exe อยู่ใน

...\Example\ConsoleTutorial\bin

เมื่อรู้ดังนี้แล้วก็ง่ายละค่ะ เราก็ใช้ VS build solution ตามปกติค่ะ แล้วก็เปิด Tools Command Prompt แล้วเปิดไป directory bin เลยค่ะ แล้วก็สั่ง

> ConsoleTutorial.exe 1 2

อ่า... เรียบร้อย เทสต์ได้แล้ว... ไม่น่าเชื่อว่า เรื่องแค่นี้ หามาช้านาน เศร้าใจ สงสัยจะแก่แล้วจริงๆ

Test Double

วันนี้ได้อ่านบทความที่เกี่ยวกับการทำ test และได้รู้คำใหม่ๆ เช่น Test Double ที่ใช้เรียก class ที่ใช้ในการกันส่วนที่ไม่เกี่ยวข้องกับส่วนที่ต้องการทดสอบออกไป ซึ่ง Test Double มีหลายตัว คือ

Dummy <-- and="" fake="" mock="" p="" spy="" stub="">
ที่เขียนแบบนี้เพราะมีบทความจาก Robert C. Martin ที่บอกว่า Mock เป็นประเภทหนึ่งของ Spy และ Spy เป็นประเภทหนึ่งของ Stub และ Stub เป็นประเภทหนึ่งของ Dummy แต่ว่า Fake เป็นประเภทที่แตกต่างออกไป (ทั้งนี้ควรจะอ่านบทความควบคู่ไปด้วย เพื่อความเข้าใจมากขึั้น มิฉะนั้น อาจจะเข้าใจผิดได้ เช่น ถึงแม้ Stub จะเป็นประเภทหนึ่งของ Dummy แต่ว่าการใช้ในการทดสอบก็ต่างกัน เพราะว่า Dummy มักใช้เป็น parameter ในการส่งเข้า method แต่ว่า Stub เราใช้แทน class เพื่อให้ทำงานบางวัตถุประสงค์)

ทั้งนี้จากบทความเอง ก็ช่วยให้เรารู้ว่าโดยปกติการเขียน unit test เค้ามักจะใช้ Stub กับ Spy ส่วน Dummy ใช้น้อยมาก และจะใช้ Mock น้อยมากๆ เนื่องจาก syntax ในการเขียนที่ดูยุ่งๆ ของ Mocking Tools (ตามบทความนะจ๊ะ แต่เราก็รู้สึกแบบนั้น)

ก็ถือเป็นการเปิดหูเปิดตาในการทำ Unit Test อย่างมาก

Reference:
The Little Mocker

Design principle


  • Encapsulate what varies. - Identify the aspects of your application that vary and separate them from what stays the same.
  • Program to an interface, not an implementation.
  • Favor composition over inheritances.
  • Strive for loosely coupled designs between objects that interact.
  • Classes should be open for extension, but closed for modification.
  • Depend upon abstractions. Do not depend upon concrete classes.
  • Only talk to your friends.
  • Don't call us, we'll call you.
  • A class should have only one reason to change.

หรือในอีกมุมหนึ่งจะดูตามหัวข้อ

  • Communication Path and Access Channel 
    • Communication Path เป็นการกำหนดเส้นทางสือสารระหว่าง Element ต่างๆ
    • Access Channel เป็นการกำหนดการเข้าถึง Element
  • Coupling and Cohesion
  • Modularity คือการกำหนดหน้าที่ (method) และคุณสมบัติ (property) ให้โมดูลมีความสมบูรณ์ และมีความอิสระ ไม่พึ่งพาโมดูลอื่นๆ
  • Classification ต้องใช้ Design Principle หลายชนิด 
    • Association, Aggretation, Composition
    • Hierarchy, Generalization, Specialization
    • Packaging
  • Hierarchy, Generalization and Specialization
  • Information Hiding, Encapsulation and Abstraction
  • Contract, Boundary and Interface Design
  • Capability, Operation and Method
  • Dispatch and Delegate
  • Association, Aggregation and Composition


Reference: Head First Design Patterns - O'reilly

Eclipse: การใช้ Ant ใน Eclipse

Ant มีการให้กับ Eclipse ตั้งแต่ version 3.0 แล้วค่ะ การจะใช้ ก็คือใน project ของเราจะต้องมี build.xml ซึ่งเป็นไฟล์ config สำหรับการ build ด้วย Ant หลังจากนั้นก็กำหนดค่าเพื่อให้ Eclipse รู้ว่าจะต้อง build project ด้วย Ant โดยไปที่ เมนู Project > Properties เลือกไปที่ Builders ในหน้าจอทางด้านขวาจะแสดง Java Builder เป็น default



ให้คลิ๊ก New...


แล้วเลือก Ant Builder แล้วคลิ๊ก OK




ใส่ชื่อ Builder ซึ่่งเป็นอะไรก็ได้ ในตัวอย่างใส่เป็น Ant Builder แล้วคลิ๊ก Browser Workspace... เพื่อเลือกไฟล์ build.xml ใน project แล้วคลิ๊ก OK

แค่นี้ก็เป็นอันเสร็จสิ้น เราก็สามารถใช้คำสั่ง Build Project ใน project เหมือนปกติ แต่มันจะไปทำการเรียก Ant ขึ้นมา build ตามที่เรา config ไว้ใน build.xml

Reference:

State Pattern

The State Pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.




ดูแค่ structure จะเห็นว่า state pattern คล้ายกับ strategy pattern มากเลย เรียกว่าเหมือนกะเป๊งเลยดีกว่า แต่ว่า จุดประสงค์ของ 2 pattern ไม่เหมือนกัน state pattern จะเน้นที่ context object หรือ ตัว object หลักของแต่ละ state มีการเปลี่ยนพฤติกรรม ได้ โดยที่ context ไม่รู้ คือตัว state จะเปลี่ยนไปตามแต่ method ที่ถูกเรียก ในขณะีที่ strategy จะถูกโปรแกรมกำหนดให้