Hello World với Swift
swift
51
hello world
2
White

Trần Thiện Khiêm viết ngày 29/10/2015

Bắt đầu

Hôm nay mình sẽ hướng dẫn các bạn viết chương trình Hello World sử dụng Swift. Để bắt đầu, chúng ta sẽ viết 1 chương trình đơn giản:

print("Hello World!")

Sử dụng lại

Chương trình trên sẽ in ra dòng chữ Hello World!. Đơn giản vãi nồi!!! Để có thể sử dụng lại mã nguồn trên ở nhiều nơi, bây giờ chúng ta sẽ phát triển một kiểu (Type) thực hiện nhiệm vụ in ra dòng Hello World! trên. Có 2 lựa chọn trong Swift là value typereference type, nói nhiều các bạn sẽ rối, theo mấy bác bên Apple thì nên sử dụng value type để tránh implicit sharing và dễ kiểm soát hơn (éo hiểu nhưng mà cũng éo cần quan tâm, làm theo phát!). Mình sẽ viết lại chương trình trên như sau:

struct Greeter {

  /// 
  /// Display Message `Hello World`
  /// 
  func sayHelloWorld() {
    print("Hello World!")
  }
} 

let greeter = Greeter()
greeter.sayHelloWorld()

Mở rộng

Vậy là mình vừa phát triển được 1 kiểu Greeter hiển thị dòng chữ HelloWorld!. Nhưng hiện tại, lớp của mình chỉ có thể hiển thị lên console. Mình muốn phát triển ra để chương trình của mình có thể hiển thị thông điệp lên nhiều nơi khác nhau như lên màn hình đồ họa, gửi thông điệp qua email, SMS, ... Để làm được điều đó, mình sẽ định nghĩa một giao thức là Displayer chung cho tất cả các đối tượng kể trên. Trong swift gọi là protocol, một lớp có thể cài đặt nhiều protocol khác nhau nên nghe đồn việc sử dụng protocol sẽ linh hoạt hơn.
Chương trình được viết lại như sau:

// common protocol for displaying a message
protocol Displayer {
  func display(message: String)
}

struct ConsoleDisplayer: Displayer {
  func display(message: String) {
    print(message)
  }
}

struct Greeter {
  let helloWorldMessage = "Hello World!"

  func sayHelloWorld() {
    let displayer = ConsoleDisplayer()
    displayer.display(helloWorldMessage)
  }
}

let greeter = Greeter()
greeter.sayHelloWorld()

Inject Dependencies

Chương trình trên có 1 vấn đề đó là lớp ConsoleDisplayer được khởi tạo bên trong lớp Greeter, sau này nếu chúng ta muốn thay đổi implement sang một lớp khác như GraphicDisplayer thì chúng ta phải sửa lớp Greeter, do đó chúng ta sẽ sửa lớp Greeter lại để cho phép đưa một phụ thuộc vào lớp này (xem Dependency Injection).

protocol Displayer {
  func display(message: String)
}

struct ConsoleDisplayer: Displayer {
  func display(message: String) {
    print(message)
  }
}

struct Greeter {
  let helloWorldMessage = "Hello World"
  var displayer: Displayer

  init(displayer aDisplayer: Displayer) {
    displayer = aDisplayer
  }

  func sayHelloWorld() {
    displayer.display(helloWorldMessage)
  }
}

let displayer = ConsoleDisplayer()
let greeter = Greeter(displayer: displayer)
greeter.sayHelloWorld()

In thông điệp ra UILabel

Bây giờ chúng ta đã có 1 lớp Greeter tương đối ổn định. Chúng ta có thể sử dụng lớp Greeter này bất cứ đâu. Ví dụ, chúng ta sẽ sử dụng lớp Greeter của chúng ta để hiển thị dòng chữ Hello World! lên một UILabel như dưới đây:

extension UILabel: Displayer {
  func display(message: String) {
    text = message
  }
}

let greeter = Greeter(displayer: helloWorldLabel) // helloWorldLabel is an outlet to a UILabel
greeter.sayHelloWorld()

xong đoạn này Swift extension quá chất.

Kiểm thử

Chúng ta sẽ kiểm tra tính đúng đắn của hàm sayHelloWorld bằng cách viết một đơn vị kiểm thử. Để làm điều này, chúng ta sẽ mock một lớp TestDisplayer như sau:

struct TestDisplayer: Displayer {
  var messages = [String]()
  func display(message: String) {
    messages.append(message)
  }
}

let expectedHelloWorldMessage = "Hello World!"

func testSayHelloWorld() {

  let displayer = TestDisplayer()
  let greeter = Greeter(displayer: displayer)
  greeter.sayHelloWorld()

  // check result
  XCTAssertEqual(1, displayer.messages.count, "Should display a message")
  XCTAssertEqual(expectedHelloWorldMessage, displayer.messages[0], "Should display \(expectedHelloWorldMessage) message") 
}
Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Trần Thiện Khiêm

1 bài viết.
7 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Bài viết liên quan
White
11 4
(Link) (Link) (Link) Ở 2 phần tut trước, mình đã hướng dẫn khá chi tiết cách viết một ứng dụng camera có tích hợp chức năng nhận diện khuôn mặ...
HoangPH viết gần 3 năm trước
11 4
White
0 0
RxSwift: Bài 6: RxCocoa (Part 4) Units 1. Khái niệm chung RxCocoa cung cấp nhiều tính năng mới để làm việc với Cocoa và UIKit 1 cách dễ dàng hơn....
Bùi Khánh Duy viết 2 ngày trước
0 0
White
2 0
Có nhiều cách viết blog công nghệ hơn là làm bánh hay làm tình. Những ngày này Hà Nội mưa liên miên, được cái mát giời, mình lại tức cảnh sinh tìn...
VietHQ viết 7 tháng trước
2 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
1 bài viết.
7 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!