Tucker's Golang programming Ch27 ~ Ch30
This post is a translation of the original Korean post.
This text is a summary of chapters 27 to 30 of the book “Golden Rabbit: [ Tucker’s Golang programming ]”.
Ch27 ~ Ch30
- Object-Oriented Design Principles SOLID
- Tests and benchmarks
- Web server with Go
- Creating a RESTful API server
# Object-oriented design principles SOLID
Principles to reduce coupling and increase cohesion for good design.
- Coupling ⬇️
- The degree to which modules are strongly coupled to each other and cannot be separated.
- Cohesion ⬆️
- The degree to which a module can stand on its own.
# Single responsibility principle
“Every object should have only one responsibility.”
- There should be only one reason for a change to an object or module.
# Open-Closed principle
“Open to extensions, closed to changes.”
- Adding features should minimize changes to existing code
# Liskov substitution principle
“If q(x) is a property that can be proved for an object x of type T, then q(y) must be provable for objects y of a subtype S of T.”
Must honor function contract relations
- The implementation must behave according to the caller’s intent (expected behavior).
Inheritance can easily violate the principle of liskov substitution.
- Methods in the parent class and overridden methods in the child class can have different behavior.
e.g. Function to increase the horizontal size of an image (argument: Rectangle type)
- Image object is of type Rectangle (interface) and has method setWidth
- Call setWidth of the image object
- ⚠️ problem occurs
- The Square type, which inherits (implements) the Rectangle type, is passed as a parameter.
- The Square type’s setWidth changes both width and height.
- We only wanted to increase the width, but it also increased the height (‼️ unexpected behavior)
# Interface segregation principle
“Clients should not rely on methods they don’t use.”
- Separate interfaces so that there are no dependencies on unnecessary methods.
# Dependency inversion principle
“By reversing the traditional dependency relationship in which a higher layer depends on a lower layer, a higher layer can be made independent of the implementation of a lower layer.”
- Materialized objects should have dependency relationships with abstracted objects
Principle
- Parent, child modules all depend on abstract modules.
- An abstract module should not depend on a concrete module. A concrete module must depend on an abstract module.
benefit
- Less coupling, increasing portability
- Maintain independence from each other
# Tests and benchmarks
# Test code
|
|
- The filename must end with
_text.go
. - Must import the testing package
- The function name must start with
Test
.- Only one parameter must exist,
t *test.T
- Only one parameter must exist,
stretchr/testify
- The assert object
- Contains a variety of methods to make it easy to create test code
- Equal(), Greater(), Len(), NotNilf(), NotEqualf()
- Contains a variety of methods to make it easy to create test code
- mock package
- Provides mock objects that mimic the behavior of the module
- suite package
- Makes it easy to do test prep work or clean up afterward
Test Driven Development
Write tests -> test fails -> write code -> test succeeds -> improve (based on SOLID principles)
- Repeat the above process
# Benchmark code
Measure the performance of your code
|
|
- Should take the form of
func BenchmarkXxxx(b *testing.B)
# Create a webserver in Go
# Web server
- Register the handler
- Register with http.HandleFunc() -> DefaultServeMux
- http.NewServeMux()
- Creating a ServeMux Object
- Call HandleFunc() of the created ServeMux object to register it
- Start the web server
- http.ListenAndServe(addr string, handler http.Handler)
- addr
- port number
- handler
- Use
*http.ServeMux
, an implementation of http.Handler. - If nil, use DefaultServeMux internally
- Use
- addr
- http.ListenAndServe(addr string, handler http.Handler)
Structure
# FileServer
|
|
- Serve the file corresponding to the request URL.Path inside “/static”
- Remove “/static/” from the request URL.Path with
http.StripPrefix
.
- Remove “/static/” from the request URL.Path with
# Test code
|
|
# Sending JSON data
Encoder, Decoder
- Encoder
- has
io.Writer
- has
- Decoder
- has
io.Reader
- has
- Encodes and decodes stream data instead of storing it all at once.
Marshal, Unmarshal
- Marshal
- Takes a value of any type and converts it to a byte slice.
- Unmarshal
- Takes a byte slice and stores the parsed result in any type (address value)
- Memory intensive because all data is stored in byte slices.
ref: https://blog.devgenius.io/to-unmarshal-or-to-decode-json-processing-in-go-explained-e92fab5b648f
# HTTPS
Uses public key cryptography
Certified by an external authorized organization
For phishing sites, hackers can create a public key and decrypt it with their own secret key.
- Certificate authority authenticates the website and issues a public key that encrypts the website’s public key (included in the certificate)
Generate a key and issue a certificate
|
|
Run the HTTPS server
|
|
# Create a RESTful API server
REST (Representational State Transfer)
- A way to represent data and behavior with URLs and methods.
Features
- A combination of URLs and methods define what data and what behavior to perform.
- Server (backend) is a data provider and only provides data, client (frontend) processes and displays data on screen
- Stateless
- The server does not maintain the state of the client
- Caching
- Simpler server makes it easier to enforce cache policies
Code
|
|