Golang 시리즈 (4) 인터페이스 프로그래밍
23163 단어 GolangGolang 시리즈 학습
1. 인터페이스 [멀티태스]
다중성 (polymorphisn) 은 부모 대상을 하나 이상의 자식 대상과 같은 기술로 설정할 수 있도록 하는 기술로, 값을 부여하면 부모 대상은 현재 값을 부여한 자식 대상의 특성에 따라 다른 방식으로 작동할 수 있다.
간단하게 말하면, 하위 클래스의 바늘을 부모 클래스의 바늘에 값을 부여할 수 있도록 허용하는 것이다.
즉 인용 변수가 어느 종류의 실례 대상을 가리키는지 인용 변수가 보내는 방법은 도대체 어느 종류에서 이루어지는 방법인지 프로그램이 실행되는 동안에야 결정할 수 있다.프로그램 코드를 수정하지 않으면 프로그램이 실행될 때 귀속된 구체적인 코드를 바꾸어 프로그램이 여러 개의 실행 상태를 선택할 수 있게 하는 것이 다태성이다.다태는 컴파일할 때 다태적(정적 다태적)과 운행할 때 다태적(동적 다태적)으로 나뉘는데 컴파일할 때 다태적은 일반적으로 방법으로 재부팅하고 운행할 때 다태적(동적 다태적)은 일반적으로 방법으로 재부팅하여 실현한다.
1.1 인터페이스 개념
인터페이스 유형은 유형 시스템에서 특수한 유형으로 볼 수 있는데 실례는 이 인터페이스의 구체적인 구조체 유형을 실현한 것이다.
인터페이스 유형과 이 인터페이스를 실현한 구조체 대상 간의 관계는 변수 유형과 변수 간의 관계와 같다.
인터페이스는 한 조의 방법이 정의한 집합이고 대상의 한 조의 행위를 정의하며 구체적인 유형의 실례로 구체적인 방법을 실현한다.다시 말하면 하나의 인터페이스는 정의(규범 또는 제약)이고 방법은 실현이다. 인터페이스의 역할은 정의와 실현을 분리하고 결합도를 낮추는 것이다."Reader"와 같이 "er"끝으로 이름을 지정하는 것이 습관입니다.인터페이스와 대상의 관계는 다대다. 즉, 한 대상은 여러 인터페이스를 실현할 수 있고, 한 인터페이스도 여러 대상에 의해 실현될 수 있다.
인터페이스는 Go 언어의 전체 유형 시스템의 초석이다. 다른 언어의 인터페이스는 서로 다른 구성 요소 간의 계약의 존재이고 계약의 실현에 강제적이다. 반드시 이 인터페이스를 실현했다고 명시해야 한다. 이런 인터페이스를'침입식 인터페이스'라고 부른다.Go 언어의 인터페이스는 스텔스 존재로 이 인터페이스의 모든 함수를 실현하면 이미 이 인터페이스를 실현했다는 것을 의미하며 현식 인터페이스 설명이 필요하지 않다.
인터페이스 프로그래밍은 세 가지 측면으로 나눌 수 있는데 그것이 바로 제정자(또는 조율자), 실현자(또는 생산자), 호출자(또는 소비자)이다.
다른 디자이너가 인터페이스를 호출한 후에 인터페이스의 정의를 함부로 변경할 수 없다. 그렇지 않으면 프로젝트 개발자의 사전 약속은 의미를 잃게 된다.그러나 클래스에서 해당하는 코드를 수정하여 변경해야 할 내용을 완성할 수 있다.
1.2 비침입 인터페이스
비침입식 인터페이스: 하나의 클래스는 인터페이스가 요구하는 모든 함수만 실현하면 이 인터페이스를 실현하고 현식 성명이 필요하지 않다는 것을 나타낸다
type File struct{
//
}
//File
func (f *File) Read(buf []byte) (n int,err error)
func (f *File) Write(buf []byte) (n int,err error)
func (f *File) Seek(off int64,whence int) (pos int64,err error)
func (f *File) Close() error
// 1:IFile
type IFile interface{
Read(buf []byte) (n int,err error)
Write(buf []byte) (n int,err error)
Seek(off int64,whence int) (pos int64,err error)
Close() error
}
// 2:IReader
type IReader interface{
Read(buf []byte) (n int,err error)
}
// ,File IFile IReader ,
var file1 IFile = new(File)
var file2 IReader = new(File)
1.3 인터페이스 할당
클래스가 이 인터페이스의 모든 방법을 실현하기만 하면 이 클래스를 이 인터페이스에 할당할 수 있으며 인터페이스는 주로 다태화 방법에 사용된다.즉 인터페이스에 대한 정의 방법, 서로 다른 실현 방식이다.
인터페이스에 값을 부여합니다: 1) 인터페이스에 대상을 실례적으로 값을 부여합니다
type IUSB interface{
// IUSB
}
// , , ,
type MP3 struct{
// IUSB , MP3
}
type Mouse struct{
// IUSB , Mouse
}
// MP3
var usb IUSB =new(MP3)
usb.Connect()
usb.Close()
// Mouse
var usb IUSB =new(Mouse)
usb.Connect()
usb.Close()
2) 인터페이스를 다른 인터페이스에 할당
type Writer interface{ //
Write(buf []byte) (n int,err error)
}
type ReadWriter interface{ //
Read(buf []byte) (n int,err error)
Write(buf []byte) (n int,err error)
}
var file1 ReadWriter=new(File) //
var file2 Writer=file1 //
1.4 인터페이스 쿼리
switch 밖에서 하나의 인터페이스 유형이 어떤 인터페이스를 실현했는지 판단하려면 '쉼표 ok' 를 사용할 수 있습니다.
value, ok := Interfacevariable.(implementType)
그 중에서Interfacevariable는 인터페이스 변수(인터페이스 값)이고implementType은 이 인터페이스의 유형을 실현하기 위해value는 인터페이스 변수의 실제 유형 변수의 값을 되돌려줍니다. 만약에 이 유형이 이 인터페이스가true를 되돌려준다면value는 인터페이스 변수의 실제 유형 변수를 되돌려줍니다.
// file1 File
var file1 Writer=...
if file5,ok:=file1.(File);ok{
...
}
1.5 인터페이스 유형 쿼리
Go에서 인터페이스 값에 전달되는 변수 유형을 판단하려면 type switch를 사용하여 얻을 수 있습니다.(type)는 switch에서만 사용할 수 있습니다.
// I R
type R struct { i int }
func (p *R) Get() int { return p.i }
func (p *R) Put(v int) { p.i = v }
func f(p I) {
switch t := p.(type) { // p
case *S: // S
case *R: // R
case S: // S
case R: // R
default: // I
}
}
1.6 인터페이스 조합
// , ,
type ReadWriter interface{ // ,
Reader // Reader
Writer // Writer
}
1.7 Any 유형 [빈 인터페이스]
모든 종류가 빈 인터페이스에 일치합니다:interface {}.빈 인터페이스 형식은 방법에 대한 제약이 없습니다. (방법이 없기 때문에) 임의의 형식을 포함할 수도 있고 다른 인터페이스 형식으로 전환할 수도 있습니다.이 인터페이스에 전달된 유형 변수가 변환된 인터페이스를 실현하면 정상적으로 실행할 수 있으며, 그렇지 않으면 실행 중 오류가 발생합니다.
//interface{} Any , Java Object
var v1 interface{}=struct{X int}{1}
var v2 interface{}="abc"
func DoSomething(v interface{}) { // ,
// ...
}
1.8 인터페이스 코드 예
// animal
type Animal interface {
Speak() string
}
//Dog animal
type Dog struct {
}
func (d Dog) Speak() string {
return "Woof!"
}
//Cat animal
type Cat struct {
}
func (c Cat) Speak() string {
return "Meow!"
}
//Llama animal
type Llama struct {
}
func (l Llama) Speak() string {
return "?????"
}
//JavaProgrammer animal
type JavaProgrammer struct {
}
func (j JavaProgrammer) Speak() string {
return "Design patterns!"
}
//
func main() {
animals := []Animal{Dog{}, Cat{}, Llama{}, JavaProgrammer{}} //
for _, animal := range animals {
fmt.Println(animal.Speak()) //
}
}
2.client-go에서 인터페이스의 사용 분석
다음은
k8s.io/client-go/kubernetes/typed/core/v1/pod.go
의pod 대상으로 분석한다.2.1 인터페이스 설계 및 정의
2.1.1 인터페이스 조합
// PodsGetter has a method to return a PodInterface.
// A group's client should implement this interface.
type PodsGetter interface {
Pods(namespace string) PodInterface
}
2.1.2 인터페이스 정의
// PodInterface has methods to work with Pod resources.
type PodInterface interface {
Create(*v1.Pod) (*v1.Pod, error)
Update(*v1.Pod) (*v1.Pod, error)
UpdateStatus(*v1.Pod) (*v1.Pod, error)
Delete(name string, options *meta_v1.DeleteOptions) error
DeleteCollection(options *meta_v1.DeleteOptions, listOptions meta_v1.ListOptions) error
Get(name string, options meta_v1.GetOptions) (*v1.Pod, error)
List(opts meta_v1.ListOptions) (*v1.PodList, error)
Watch(opts meta_v1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Pod, err error)
PodExpansion
}
PodInterface
인터페이스는pod 대상이 사용하는 방법을 정의했고 일반적으로 삭제 및 수정 등이다.다른kubernetes 자원 대상의 인터페이스 정의는 유사한데, 차이점은 참여 대상과 참여 대상이 관련이 있다는 것이다.예를 들어 Create(*v1.Pod) (*v1.Pod, error)
방법이 정의한 입참출참은 *v1.Pod
이다.이 인터페이스를 실현하려면, 이 인터페이스를 실현하는 모든 방법이다.2.2 인터페이스의 실현
2.2.1 구조체의 정의
// pods implements PodInterface
type pods struct {
client rest.Interface
ns string
}
2.2.2 new 함수 [구조 함수]
// newPods returns a Pods
func newPods(c *CoreV1Client, namespace string) *pods {
return &pods{
client: c.RESTClient(),
ns: namespace,
}
}
2.2.3 방법의 실현
Get
// Get takes name of the pod, and returns the corresponding pod object, and an error if there is any.
func (c *pods) Get(name string, options meta_v1.GetOptions) (result *v1.Pod, err error) {
result = &v1.Pod{}
err = c.client.Get().
Namespace(c.ns).
Resource("pods").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do().
Into(result)
return
}
List
// List takes label and field selectors, and returns the list of Pods that match those selectors.
func (c *pods) List(opts meta_v1.ListOptions) (result *v1.PodList, err error) {
result = &v1.PodList{}
err = c.client.Get().
Namespace(c.ns).
Resource("pods").
VersionedParams(&opts, scheme.ParameterCodec).
Do().
Into(result)
return
}
Create
// Create takes the representation of a pod and creates it. Returns the server's representation of the pod, and an error, if there is any.
func (c *pods) Create(pod *v1.Pod) (result *v1.Pod, err error) {
result = &v1.Pod{}
err = c.client.Post().
Namespace(c.ns).
Resource("pods").
Body(pod).
Do().
Into(result)
return
}
Update
// Update takes the representation of a pod and updates it. Returns the server's representation of the pod, and an error, if there is any.
func (c *pods) Update(pod *v1.Pod) (result *v1.Pod, err error) {
result = &v1.Pod{}
err = c.client.Put().
Namespace(c.ns).
Resource("pods").
Name(pod.Name).
Body(pod).
Do().
Into(result)
return
}
Delete
// Delete takes name of the pod and deletes it. Returns an error if one occurs.
func (c *pods) Delete(name string, options *meta_v1.DeleteOptions) error {
return c.client.Delete().
Namespace(c.ns).
Resource("pods").
Name(name).
Body(options).
Do().
Error()
}
2.3 인터페이스 호출
예:
// clientset
clientset, err := kubernetes.NewForConfig(config)
//
pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
clientset은 인터페이스
Interface
를 실현했고 Interface
는 인터페이스 조합으로 각각의 client의 인터페이스 유형을 포함한다.예를 들어CoreV1()
방법에 대응하는 인터페이스 유형은CoreV1Interface
이다.다음은 clientset의
CoreV1()
방법으로 이루어진 것이다.// CoreV1 retrieves the CoreV1Client
func (c *Clientset) CoreV1() corev1.CoreV1Interface {
return c.coreV1
}
이 방법은 하나
로 이해할 수 있다.구조 함수의 반환값 유형은 인터페이스 유형CoreV1Interface
이고return의 반환값은 이 인터페이스 유형의 구조체 대상c.coreV1
을 실현했다.인터페이스 유형은 특수한 유형으로 인터페이스 유형과 구조체 대상 간의 관계는 변수 유형과 변수 간의 관계와 같다.그 중의 구조체 대상은 반드시 이 인터페이스 유형의 모든 방법을 실현해야 한다.
그래서clientset의
CoreV1()
방법은 하나의 CoreV1Client
구조체 대상을 되돌려주는 것이다.이 구조체의 대상은 CoreV1Interface
인터페이스를 실현했고 이 인터페이스도 하나의 인터페이스 조합이다.type CoreV1Interface interface {
RESTClient() rest.Interface
ComponentStatusesGetter
ConfigMapsGetter
EndpointsGetter
EventsGetter
LimitRangesGetter
NamespacesGetter
NodesGetter
PersistentVolumesGetter
PersistentVolumeClaimsGetter
PodsGetter
PodTemplatesGetter
ReplicationControllersGetter
ResourceQuotasGetter
SecretsGetter
ServicesGetter
ServiceAccountsGetter
}
실현된
Pods()
방법은 그중의PodsGetter
인터페이스이다.Pods()
는 CoreV1()
와 같은 구조 함수이고 구조 함수의 반환값 유형은 PodInterface
인터페이스이고 반환값은 PodInterface
인터페이스를 실현한 pods
구조체 대상이다.func (c *CoreV1Client) Pods(namespace string) PodInterface {
return newPods(c, namespace)
}
한편,
PodInterface
인터페이스 정의는 인터페이스 정의를 참고하고 pods
대상은 PodInterface
인터페이스의 방법을 실현했으며 구체적인 인터페이스 실현을 참고했다.최종적으로
pods
대상의 List()
방법을 호출했다.pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
즉 상기 코드는 특정한 인터페이스를 실현한 구조체 대상의 구조 함수를 끊임없이 호출하여 구체적인 구조체 대상을 생성하고 구조체 대상의 특정한 방법을 다시 호출하는 것이다.
3. 유니버설 인터페이스 디자인
3.1 인터페이스 정의
// ProjectManager manage life cycle of Deployment and Resources
type PodInterface interface {
Create(*v1.Pod) (*v1.Pod, error)
Update(*v1.Pod) (*v1.Pod, error)
UpdateStatus(*v1.Pod) (*v1.Pod, error)
Delete(name string, options *meta_v1.DeleteOptions) error
DeleteCollection(options *meta_v1.DeleteOptions, listOptions meta_v1.ListOptions) error
Get(name string, options meta_v1.GetOptions) (*v1.Pod, error)
List(opts meta_v1.ListOptions) (*v1.PodList, error)
Watch(opts meta_v1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Pod, err error)
PodExpansion
}
3.2 구조체 정의
// pods implements PodInterface
type pods struct {
client rest.Interface
ns string
}
3.3 구조 함수
// newPods returns a Pods
func newPods(c *CoreV1Client, namespace string) *pods {
return &pods{
client: c.RESTClient(),
ns: namespace,
}
}
3.4 구조체 실현
List()
// List takes label and field selectors, and returns the list of Pods that match those selectors.
func (c *pods) List(opts meta_v1.ListOptions) (result *v1.PodList, err error) {
result = &v1.PodList{}
err = c.client.Get().
Namespace(c.ns).
Resource("pods").
VersionedParams(&opts, scheme.ParameterCodec).
Do().
Into(result)
return
}
3.5 인터페이스 호출
pods, err := clientset.CoreV1().Pods("").List(metav1.ListOptions{})
3.6 기타 인터페이스 설계 예
type XxxManager interface {
Create(args argsType) (*XxxStruct, error)
Get(args argsType) (**XxxStruct, error)
Update(args argsType) (*XxxStruct, error)
Delete(name string, options *DeleleOptions) error
}
type XxxManagerImpl struct {
Name string
Namespace string
kubeCli *kubernetes.Clientset
}
func NewXxxManagerImpl (namespace, name string, kubeCli *kubernetes.Clientset) XxxManager {
return &XxxManagerImpl{
Name name,
Namespace namespace,
kubeCli: kubeCli,
}
}
func (xm *XxxManagerImpl) Create(args argsType) (*XxxStruct, error) {
//
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
golang의 시간대와 신기한 시간.Parse상기 코드의 테스트 결과에서 몇 가지를 얻을 수 있다. time.Now에서 얻은 현재 시간의 시간대는 컴퓨터의 현재 시간대와 같다. time.Parse는 시간 문자열을 Time으로 변환합니다. Time 변수가 어떤 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.