Skip to main content

Command Palette

Search for a command to run...

Interface কি এবং Interface ইমপ্লিমেন্ট

Published
5 min readView as Markdown
Interface কি এবং Interface ইমপ্লিমেন্ট
I

A highly motivated and experienced full-stack developer with a proven track record of developing and deploying web applications. Skilled in a range of programming languages and frameworks, as well as database technologies. Comfortable working in a fast-paced environment and able to adapt to new technologies quickly. A team player who is also able to work independently when required.

Interface এর মূল ধারণা

Interface হল Go প্রোগ্রামিং এর একটি অসাধারণ ফিচার যা আমাদের কোডকে flexible এবং reusable বানাতে সাহায্য করে। সহজভাবে বলতে গেলে, interface হল মেথড সিগনেচারের একটি সেট যা বলে "যে কোনো টাইপ যদি এই মেথডগুলো ইমপ্লিমেন্ট করে, তাহলে সে এই interface এর মত আচরণ করতে পারে।"

Interface এর সংজ্ঞা

Go তে interface এভাবে ডিফাইন করা হয়:

type Writer interface {
    Write([]byte) (int, error)
}

এই উদাহরণে, Writer interface বলছে: "যেকোনো টাইপ যার Write([]byte) (int, error) মেথড আছে, সে একটি Writer।"

Interface ইমপ্লিমেন্ট করা কি?

অন্যান্য প্রোগ্রামিং ল্যাঙ্গুয়েজের তুলনায় Go তে interface ইমপ্লিমেন্ট করার প্রক্রিয়া আলাদা। Go তে implicit implementation হয় - অর্থাৎ, আপনাকে কখনো এক্সপ্লিসিটলি ঘোষণা করতে হয় না যে "আমার টাইপ এই interface ইমপ্লিমেন্ট করে।" আপনি শুধু interface এর মেথডগুলো আপনার টাইপে ডিফাইন করলেই হয়ে গেল।

উদাহরণ:

// FileWriter টাইপ
type FileWriter struct {
    filename string
}

// Write মেথড ইমপ্লিমেন্ট করা
func (fw FileWriter) Write(data []byte) (int, error) {
    return os.WriteFile(fw.filename, data, 0644)
}

এখানে, FileWriter কোথাও ঘোষণা করেনি যে সে Writer interface ইমপ্লিমেন্ট করছে। কিন্তু যেহেতু এর Write মেথড আছে যার signature ঠিক Writer interface এর মত, তাই FileWriter অটোমেটিক্যালি Writer interface ইমপ্লিমেন্ট করে।

ব্যবহারিক উদাহরণ

এই উদাহরণে, আমরা দেখব কিভাবে একটি function interface ব্যবহার করে বিভিন্ন টাইপের অবজেক্ট নিয়ে কাজ করতে পারে:

// SaveData যেকোনো Writer interface গ্রহণ করে
func SaveData(w Writer, data []byte) error {
    _, err := w.Write(data)
    return err
}

// বিভিন্ন টাইপ যা Writer interface ইমপ্লিমেন্ট করে
func main() {
    // ফাইলে লেখা
    fileWriter := FileWriter{"data.txt"}
    SaveData(fileWriter, []byte("Hello, World!"))

    // বাফারে লেখা
    var buf bytes.Buffer
    SaveData(&buf, []byte("Hello, Buffer!"))

    // নেটওয়ার্কে লেখা
    conn, _ := net.Dial("tcp", "example.com:80")
    SaveData(conn, []byte("Hello, Network!"))
}

একই SaveData function বিভিন্ন ধরনের Writer এর সাথে কাজ করছে: ফাইল, মেমরি বাফার, নেটওয়ার্ক কানেকশন - কারণ এরা সবাই Writer interface ইমপ্লিমেন্ট করে।

Interface ইমপ্লিমেন্টেশন চেক

আপনি কম্পাইল টাইমে চেক করতে পারেন আপনার টাইপ একটি interface ইমপ্লিমেন্ট করে কিনা:

// কম্পাইল টাইম চেক
var _ Writer = FileWriter{}  // যদি FileWriter Writer interface ইমপ্লিমেন্ট না করে, কম্পাইল এরর হবে

Standard Library তে Interface

Go standard library তে অনেক দরকারি interface আছে:

  • io.Reader: ডাটা পড়ার জন্য

  • io.Writer: ডাটা লেখার জন্য

  • fmt.Stringer: string representation দেওয়ার জন্য

  • http.Handler: HTTP request হ্যান্ডেল করার জন্য

Interface কে Interface ইমপ্লিমেন্ট করা

Interface অন্য interface কে ইমপ্লিমেন্ট করতে পারে, যাকে interface embedding বলে:

type ReadWriter interface {
    Reader
    Writer
}

এখানে ReadWriter interface দুটো interface কে embed করেছে: Reader এবং Writer। যেকোনো টাইপ যা Read এবং Write উভয় মেথডই ইমপ্লিমেন্ট করে, সে ReadWriter interface ইমপ্লিমেন্ট করে।

Empty Interface

Go তে, interface{} (বা Go 1.18+ এ any) হল এমন একটি interface যার কোনো মেথড নেই। যেহেতু কোনো মেথড নেই, তাই সব টাইপই এটা ইমপ্লিমেন্ট করে। এটা generic programming এর জন্য ব্যবহার করা হয়:

func PrintAnything(v interface{}) {
    fmt.Println(v)
}

PrintAnything(42)          // int
PrintAnything("hello")     // string
PrintAnything([]float64{}) // slice

Type Assertion এবং Type Switch

Interface value থেকে আসল টাইপ বের করার জন্য type assertion ব্যবহার করা হয়:

func ProcessValue(v interface{}) {
    // Type assertion
    str, ok := v.(string)
    if ok {
        fmt.Println("String value:", str)
    }

    // Type switch
    switch val := v.(type) {
    case int:
        fmt.Println("Integer:", val)
    case string:
        fmt.Println("String:", val)
    default:
        fmt.Println("Unknown type")
    }
}

Interface এর সুবিধা

1. Decoupling (লুজ কাপলিং)

Interface ব্যবহার করে, আমরা concrete implementation থেকে আমাদের কোড আলাদা করতে পারি। আমাদের function গুলো শুধু জানে সে কোন interface নিয়ে কাজ করবে, আসল টাইপ কি সেটা জানার দরকার নেই।

// Database interface
type UserStorage interface {
    SaveUser(User) error
    GetUser(id int) (User, error)
}

// UserService শুধু interface নিয়ে কাজ করে
type UserService struct {
    storage UserStorage
}

// বিভিন্ন implementation ব্যবহার করা যায়:
// - MySQLStorage
// - MongoDBStorage
// - InMemoryStorage (টেস্টিং এর জন্য)

2. Testability

Interface ব্যবহার করে, আমরা মক অবজেক্ট ব্যবহার করে সহজে টেস্ট করতে পারি:

// টেস্টিং এর জন্য MockStorage
type MockStorage struct{}

func (m MockStorage) SaveUser(u User) error {
    // এখানে আসল ডাটাবেস কল না করে টেস্টিং লজিক
    return nil
}

func TestUserService(t *testing.T) {
    service := UserService{
        storage: MockStorage{},  // আসল ডাটাবেস এর বদলে মক
    }
    // টেস্ট লজিক...
}

3. Extensibility

Interface ব্যবহার করে, আমরা কোড পরিবর্তন ছাড়াই নতুন ফাংশনালিটি যোগ করতে পারি:

// বর্তমান কোড
func WriteData(w Writer, data []byte) error {
    return w.Write(data)
}

// পরে, নতুন টাইপ যোগ করা
type EncryptedWriter struct {
    inner Writer
    key   []byte
}

func (ew EncryptedWriter) Write(data []byte) (int, error) {
    encrypted := encrypt(data, ew.key)
    return ew.inner.Write(encrypted)
}

// WriteData function পরিবর্তন করার দরকার নেই

Interface ইমপ্লিমেন্টেশন - বিহাইন্ড দ্য সীন

Go কম্পাইলার interface ইমপ্লিমেন্টেশন ম্যাচ করার জন্য method সিগনেচার কম্পেয়ার করে। এটা রানটাইমে একটা টেবিল মেইনটেইন করে যেটা দেখায় কোন টাইপ কোন interface ইমপ্লিমেন্ট করে।

মেমরিতে, একটা interface value দুটো পয়েন্টার ধারণ করে:

  1. টাইপের মেটাডাটার পয়েন্টার

  2. আসল ডাটার পয়েন্টার

Interface value:
┌─────────────┬─────────────┐
 Type info    Data pointer│
 pointer                  
└─────────────┴─────────────┘
                     
                     
┌─────────────┐  ┌─────────────┐
 Type           Actual data 
 metadata                   
└─────────────┘  └─────────────┘

Interface Design টিপস

  1. ছোট interface বানান: মেথড সংখ্যা কম রাখুন, এতে reusability বাড়ে।

  2. Accept interfaces, return structs: Function parameter হিসেবে interface নিন, কিন্তু রিটার্ন টাইপ হিসেবে concrete type ব্যবহার করুন।

  3. Interface নিজের প্যাকেজে ডিফাইন করুন যেখানে ব্যবহার হবে: যে interface আপনি ব্যবহার করবেন, সেটা সেই প্যাকেজে ডিফাইন করুন, যে প্যাকেজ implementation দেয় সেখানে নয়।

কমন Interface প্যাটার্ন

1. Reader/Writer প্যাটার্ন

// ডাটা সোর্স
type Reader interface {
    Read([]byte) (int, error)
}

// ডাটা ডেস্টিনেশন
type Writer interface {
    Write([]byte) (int, error)
}

// ডাটা কপি করা
func Copy(dst Writer, src Reader) error {
    buf := make([]byte, 1024)
    for {
        n, err := src.Read(buf)
        if err != nil {
            return err
        }
        _, err = dst.Write(buf[:n])
        if err != nil {
            return err
        }
    }
}

2. Visitor প্যাটার্ন

// Visitor interface
type Visitor interface {
    Visit(Element) error
}

// Element interface
type Element interface {
    Accept(Visitor) error
}

উপসংহার

Interface হল Go প্রোগ্রামিং এর একটি শক্তিশালী ফিচার যা আমাদের কোডকে modular, flexible এবং testable বানাতে সাহায্য করে। Interface ইমপ্লিমেন্ট করার জন্য আমাদের শুধু সঠিক মেথড সিগনেচার যুক্ত করতে হয়, interface ফলো করার ঘোষণা দেওয়ার দরকার নেই।

Interface এর সবচেয়ে বড় শক্তি হল এটা আমাদের সহজে নতুন ফাংশনালিটি যোগ করতে দেয় এবং পুরানো কোড পরিবর্তন করার দরকার হয় না। ব্যবহারিক প্রোগ্রামিং এর জন্য interface বুঝা এবং সঠিকভাবে ব্যবহার করা খুবই গুরুত্বপূর্ণ।

2 views

More from this blog

Low Level Design: গভীর থেকে বোঝা এবং আয়ত্ত করা

ভূমিকা: কেন এই Article? তুমি হয়তো programming শিখেছ। Variable, loop, function, data structure - সব জানো। কিন্তু যখন একটা বড় system বানাতে বসো, তখন মনে হয় কোথা থেকে শুরু করব? কীভাবে organize করব? Code লিখতে লিখতে হারিয়ে যাও একটা maze-এ। এই feeling...

Oct 15, 202520 min read71
Low Level Design: গভীর থেকে বোঝা এবং আয়ত্ত করা

Go-তে Interface কীভাবে Code Decouple করে?

একটা HTTP Server দিয়ে পুরো ব্যাপারটা বুঝে নেওয়া যাক আমরা সবাই জানি Go একটা সিম্পল ল্যাঙ্গুয়েজ, কিন্তু interface নিয়ে অনেকেরই confusion থাকে। আজকে আমরা দেখব কীভাবে interface আসলে তোমার code-কে flexible এবং maintainable বানায়। একটা real-world HTT...

Oct 14, 202520 min read5
Go-তে Interface কীভাবে Code Decouple করে?

তোমার Project-এ Coupled Code কীভাবে খুঁজে বের করবে?

Coupled code খোঁজা মানে হচ্ছে তোমার codebase-এ এমন জায়গা খুঁজে বের করা যেখানে একটা অংশ আরেকটার উপর বেশি depend করছে। এটা একটা detective work — তুমি clue খুঁজবে, pattern দেখবে, এবং সমস্যা চিহ্নিত করবে। চলো step by step শিখি কীভাবে এটা করতে হয়। কেন ...

Oct 14, 202510 min read2

Go-তে Object (Struct Instance) তৈরির সম্পূর্ণ গাইড

Go programming শেখার সময় একটা জিনিস খুব তাড়াতাড়ি বুঝতে হয় - কীভাবে object তৈরি করতে হয়। অন্য language যেমন Java বা Python এ class আছে, কিন্তু Go-তে আছে struct। আর struct এর instance বানানোই হলো object তৈরি করা। আজকের এই blog এ আমরা দেখব Go-তে ob...

Oct 13, 202524 min read3
Go-তে Object (Struct Instance) তৈরির সম্পূর্ণ গাইড
I

Imran Hasan

61 posts

Full-stack developer with experience in developing and managing web applications. Skilled in React, Node.js, HTML, CSS, and JavaScript. Experience in managing website hosting and security.