前書き
最近、私はここ数年で書かれたビジネスについて考えました、そしてそれらはすべてプロセス指向の思考で実現されます。プロセス指向
1つは、誰もがこのように書いていて、より良い実現があるかどうかについてほとんど考えないからです。
2つ目は、ビジネスがシンプルで、プロセス指向プログラミングを使用して簡単に実装できることです。
第三に、ビジネスは迅速にオンラインになる必要があり、プロセス指向のアプローチはより速く、より直接的です
しかし、デメリットも明らかです。ビジネスが蓄積し続けるにつれて、プロジェクトの変更はより困難になります。前任者がどのように書いたか、そしてどのような影響があるかを絶えず整理する必要があります。機能を確認するために多くのテストを行う必要があります。正常です。同様の要件や反復的な要件でさえ、すぐにオンラインになることを保証できない場合があります。また、多くの人的資源を消費しても、漏れがないことを保証することは困難です。このとき、私はオブジェクト指向を考えます。
4つの特徴
オブジェクト指向プログラミングには4つの大きな特徴があります
- カプセル化機能
カプセル化は、情報隠蔽またはデータアクセス保護とも呼ばれます。制限付きアクセスインターフェイスを公開することにより、クラスは、クラスが提供するメソッドを介してのみ内部情報またはデータにアクセスすることを外部に許可します。Javaのprivate、protected、publicキーワードなど、サポートするアクセス制御構文を提供するプログラミング言語が必要です。カプセル化機能の重要性は、一方ではデータが任意に変更されるのを防ぎ、コードの保守性を向上させることです。他方では、限られた数の必要なインターフェイスのみを公開し、クラスの使いやすさを向上させます。 。 - 抽象機能
カプセル化は、主に情報を非表示にし、データを保護する方法について説明します。抽象化は、メソッドの特定の実装を非表示にする方法について説明します。これにより、ユーザーはメソッドが提供する機能だけを気にする必要があり、これらの方法を知る必要はありません。機能が実装されています。抽象化は、インターフェースクラスまたは抽象クラスを介して実現できますが、それをサポートするために特別な文法メカニズムは必要ありません。抽象的存在の意味は、一方ではコードのスケーラビリティと保守性を改善し、定義を変更せずに実装を変更し、コード変更の範囲を縮小することです。他方では、それは注意が必要な情報を効果的に除外できる複雑なシステムを処理します。 - 継承特性
継承は、クラス間のis-a関係を表すために使用され、単一継承と多重継承の2つのモードに分けられます。単一継承とは、サブクラスが1つの親クラスのみを継承することを意味し、多重継承とは、サブクラスが複数の親クラスを継承できることを意味します。この機能を継承するために、プログラミング言語はそれをサポートするための特別な構文メカニズムを提供する必要があります。継承は、主にコードの再利用の問題を解決するために使用されます。 - ポリモーフィズムの特性
ポリモーフィズムとは、サブクラスが親クラスを置き換えることができることを意味します。実際のコード実行プロセスでは、サブクラスのメソッドが呼び出されます。ポリモーフィズムのこの機能には、継承、インターフェイスクラス、ダックタイピングなど、実現するための特別な構文メカニズムを提供するプログラミング言語も必要です。ポリモーフィズムは、コードのスケーラビリティと再利用性を向上させることができ、多くのデザインパターン、デザイン原則、およびプログラミングスキルのコード実現の基礎となります。
成し遂げる
オブジェクト指向プログラミングを使用してビジネスロジックを実装する場合は、この言語を使用して4つの主要な機能を実装する方法を習得する必要があります。この知識を習得することで、デザインパターンを柔軟に活用し、優れたアーキテクチャを設計することができます。将来、新しい言語を学ぶときは、オブジェクト指向の実装に焦点を当てる必要があります。次のコンテンツを表示するには、基本的なGo言語の知識を習得する必要があります。
カプセル化
Goでのカプセル化の実装方法は、構造を使用し、対応するメソッドを構造に追加することです。
一般的な実装手順は次のとおりです。
- 構造とフィールドの最初の文字を小文字にします。
- コンストラクターと同様に、構造体が配置されているパッケージに、最初の文字を大文字にしてファクトリモード関数を提供します。
- 最初の文字を大文字にしたSetメソッドを提供します(他の言語のpublicと同様)。これは、属性に値を判断して割り当てるために使用されます。
- 属性の値を取得するための最初の大文字を含むGetメソッド(他の言語のpublicと同様)を提供します。
例:従業員の場合、年齢や給与などのプライバシーを自由に確認したり、入力した年齢に対して合理的な検証を行ったりすることはできません。コード構造は次のとおりです。
package model
import "fmt"
type person struct {
Name string
age int //其它包不能直接访问..
sal float64
}
//写一个工厂模式的函数,相当于构造函数
func NewPerson(name string) *person {
return &person{
Name: name,
}
}
//为了访问age 和 sal 我们编写一对SetXxx的方法和GetXxx的方法
func (p *person) SetAge(age int) {
if age > 0 && age < 150 {
p.age = age
} else {
fmt.Println("年龄范围不正确..")
//给程序员给一个默认值
}
}
func (p *person) GetAge() int {
return p.age
}
func (p *person) SetSal(sal float64) {
if sal >= 3000 && sal <= 30000 {
p.sal = sal
} else {
fmt.Println("薪水范围不正确..")
}
}
func (p *person) GetSal() float64 {
return p.sal
}
このコードに関して、説明する必要がある2つのポイントがあります
- 大文字の使用について
- 小文字で始まる関数はこのパッケージでのみ表示され、大文字で始まる関数は他のパッケージで使用できます。このルールは、型と変数の可視性にも適用されます。
- 大文字の使用は可視性に影響します。大文字の先頭はpublicに相当し、小文字の先頭はprivateに相当します。このアプローチでは、publicキーワードとprivateキーワードが削除されるだけでなく、命名スタイルも統一されます。
- 構造メソッドパラメータ
- オブジェクトをポインタで渡す必要がある場合、オブジェクトが小さい場合(たとえば、4バイト)であるため、これは追加コストになる場合があり、ポインタで渡すのは費用効果が高くありません。
- オブジェクトを変更する必要がある場合にのみ、ポインターを使用する必要があります。
継承
Go言語は、オブジェクト指向思考の継承構文をまったくサポートしていません。
別の側面から見ると、Go言語も継承を提供しますが、構成文法を使用するため、匿名構成と呼びます。
例えば:
package main
import "fmt"
type Base struct {
Name string
}
func (b *Base) SetName(name string) {
b.Name = name
}
func (b *Base) GetName() string {
return b.Name
}
// 组合,实现继承
type Child struct {
base Base // 这里保存的是Base类型
}
// 重写GetName方法
func (c *Child) GetName() string {
c.base.SetName("modify...")
return c.base.GetName()
}
// 实现继承,但需要外部提供一个Base的实例
type Child2 struct {
base *Base // 这里是指针
}
//
type Child3 struct {
Base
}
type Child4 struct {
*Base
}
func main() {
c := new(Child)
c.base.SetName("world")
fmt.Println(c.GetName())
c2 := new(Child2)
c2.base = new(Base) // 因为Child2里面的Base是指针类型,所以必须提供一个Base的实例
c2.base.SetName("ccc")
fmt.Println(c2.base.GetName())
c3 := new(Child3)
c3.SetName("1111")
fmt.Println(c3.GetName())
c4 := new(Child4)
c4.Base = new(Base)
c4.SetName("2222")
fmt.Println(c4.GetName())
}
このコードに関して、いくつかの点を説明する必要があります
- 匿名と非匿名の両方の組み合わせを使用できます。非匿名の組み合わせを使用する場合は、呼び出し時に指定された変数名を表示する必要があります。匿名の組み合わせを使用する場合は、指定した変数名を表示する必要はありません。もちろん、c3.Base.Nameなどの呼び出しを表示することもできます。
- Go言語では、ポインターの形式で型から「派生」することもできます。Child4など、このGoコードには「派生」効果がありますが、Child4がインスタンスを作成するときに、外部ポインターを提供する必要があります。 Baseクラスのインスタンス。
- 「派生クラス」Child3が「基本クラス」Baseのメンバーメソッドを書き換えない場合、対応するメソッドは「継承」されます。たとえば、上記の例では、c3.GetName()を呼び出してc3を呼び出す効果があります。 Base.GetName()全会一致。「派生クラス」では、子が「基本クラス」ベースのメンバーメソッドを書き換えます。c.GetName()は派生クラスのメソッドを呼び出します。基本クラスのメソッドを呼び出す場合は、呼び出しを表示できます。 。
- 「派生クラス」と「基本クラス」の変数名が同じである場合、派生クラスのNameメンバーへのすべてのアクセスは、最も外側のName変数にのみアクセスし、基本クラスのName変数は上書きされるのと同じです。 。表示参照を使用できます。
ポリモーフィズム
Go言語では、クラスはインターフェースに必要なすべての関数を実装するだけでよく、このクラスはインターフェースを実装すると言います。クラスがインターフェースを実装している場合、オブジェクトインスタンスをインターフェースに割り当てることができます。
例えば:
package main
import "fmt"
type Money interface {
show() string
}
type OldMoney struct {
}
func (oldMoney *OldMoney) show() string {
return "I am old money"
}
type NewMoney struct {
}
func (newMoney *NewMoney) show() string {
return "I am new money"
}
func PrintMoney(l []Money) {
for _, item := range l {
fmt.Println(item.show())
}
}
func main() {
moneyList := []Money{
new(OldMoney), new(NewMoney), new(OldMoney)}
PrintMoney(moneyList)
}
このコードに関して、注意すべき点がいくつかあります。
-
インターフェイスの割り当てでは、2つのインターフェイスが同等である必要はありません。インターフェイスAのメソッドリストがインターフェイスBのメソッドリストのサブセットである場合、インターフェイスBをインターフェイスAに割り当てることができます。
-
Go言語は、次の関数に基づいて新しいshow()メソッドを自動的に生成できます。func(oldMoney OldMoney)show()string:func(oldMoney * OldMoney)show()stringしたがって、値を割り当てるときは、参照またはオブジェクトを使用し、関数パラメータはタイプと見なす必要があります。
結論として
オブジェクト指向プログラミングにGoを使用して、Go言語の特性を簡単に確認するのは非常に簡単です。後でGoで23のデザインパターンを実装します。
データ
- Go言語でのカプセル化の理解と実装の詳細(Golangの古典的なプログラミングの場合)
- golangの継承とインターフェース
- golangの継承
- Golangの構成と匿名性の違い
- 27.ゴランのポリモーフィズム
やっと
私の記事が気に入ったら、私の公式アカウント(プログラマーMala Tang)をフォローしてください。
私の個人的なブログは次のとおりです:https://shidawuhen.github.io/
以前の記事のレビュー: