ছোট ফাংশন বনাম একই কার্যক্রমে নির্ভরশীল কার্যকারিতা রাখা


15

আমার একটি ক্লাস রয়েছে যা নোডের একটি অ্যারে সেট করে এবং গ্রাফের মতো কাঠামোতে একে অপরের সাথে সংযুক্ত করে। এটি কি সেরা:

  1. এক ফাংশনে নোডগুলি আরম্ভ এবং সংযোগ করতে কার্যকারিতা রাখুন
  2. দুটি পৃথক ফাংশনে সূচনা এবং সংযোগ কার্যকারিতা রাখুন (এবং একটি নির্ভরশীল আদেশ রয়েছে যার উপর ফাংশনগুলি কল করতে হবে - তবে এই ফাংশনগুলি ব্যক্তিগত বলে মনে রাখবেন))

পদ্ধতি 1: (এক ফাংশনে দু'টি কাজই খারাপ, তবে এটি নির্ভরশীল কার্যকারিতাটি একত্রে একত্র করে রাখে - নোডগুলি প্রথমে আরম্ভ না করে কখনও সংযুক্ত করা উচিত নয়))

init() {
    setupNodes()
}

private func setupNodes() {
    // 1. Create array of nodes
    // 2. Go through array, connecting each node to its neighbors 
    //    according to some predefined constants
}

পদ্ধতি 2: (এটি স্ব-ডকুমেন্টিং হিসাবে এই অর্থে আরও ভাল, বিট কানেক্টনডস () সেটআপ নোডের আগে কখনও কল করা উচিত নয়), সুতরাং শ্রেণি অভ্যন্তরের সাথে কাজ করা যে কোনও ব্যক্তিকে এই আদেশ সম্পর্কে জানতে হবে needs)

init() {
    setupNodes()
}

private func setupNodes() {
    createNodes()
    connectNodes()
}

private func createNodes() {
    // 1. Create array of nodes
}

private func connectNodes() {
    // 2. Go through array, connecting each node to its neighbors 
    //    according to some predefined constants
}

কোনও চিন্তা শুনে উত্তেজিত।



মধ্যবর্তী অবজেক্টগুলি কেবলমাত্র চূড়ান্ত অবজেক্ট তৈরি করতে ব্যবহৃত হতে পারে তার দ্বারা এটি সমাধান করার একটি উপায় One এটি সর্বদা সঠিক সমাধান নয় তবে যদি ইন্টারফেস ব্যবহারকারীর কোনও উপায়ে মধ্যবর্তী অবস্থার হেরফের করতে হয় তবে তা কার্যকর।
জোয়েল করনেট

উত্তর:


23

আপনি যে সমস্যার সাথে কাজ করছেন তাকে অস্থায়ী সংযুক্তি বলা হয়

আপনি এই কোডটি কীভাবে বোধগম্য তা নিয়ে উদ্বিগ্ন হওয়ার অধিকারটিই:

private func setupNodes() {
    createNodes();
    connectNodes();
}

আমি সেখানে কী ঘটছে তা অনুমান করতে পারি তবে এটি আরও কিছুটা কী পরিষ্কার চলছে তা যদি আমাকে জানান:

private func setupNodes() {
    self.nodes = connectNodes( createNodes() );
}

উদাহরণস্বরূপ ভেরিয়েবলগুলি সংশোধন করার সাথে কম সংযুক্ত হওয়ার এটির অতিরিক্ত সুবিধা রয়েছে তবে আমার কাছে পঠনযোগ্য হওয়া এক নম্বর।

এটি connectNodes()নোডের উপর নির্ভরতা সুস্পষ্ট করে তোলে ।


1
লিঙ্কের জন্য ধন্যবাদ। যেহেতু আমার ফাংশনগুলি প্রাইভেট এবং সুইফটে কনস্ট্রাক্টর - থ্রি () থেকে বলা হয়েছে - আমি মনে করি না যে আমার কোডগুলি আপনি সংযুক্ত উদাহরণগুলির মতো খারাপ হবে (কোনও বহিরাগত ক্লায়েন্টের সাথে উদাহরণ দিয়ে ইনস্ট্যান্ট করা অসম্ভব হবে) নাল উদাহরণ পরিবর্তনশীল), তবে আমারও একই গন্ধ আছে।
mcfroob

1
আপনার যুক্ত কোডটি আরও পঠনযোগ্য, তাই আমি সেই স্টাইলে রিফেক্টর করব।
এমসিফ্রুব

10

দুটি কারণে পৃথক ফাংশন :

এই পরিস্থিতির জন্য ব্যক্তিগত ফাংশনগুলি ব্যক্তিগত।

আপনার initফাংশনটি সর্বজনীন, এবং এটি ইন্টারফেস, আচরণ এবং রিটার্ন মান হ'ল রক্ষা এবং পরিবর্তন সম্পর্কে আপনার যা চিন্তা করা দরকার। ফলাফলটি আপনি যে পদ্ধতিটির বাইরে থেকে প্রত্যাশা করছেন তা একই রকম হতে চলেছে আপনি যাই প্রয়োগ প্রয়োগ কর না কেন।

যেহেতু বাকী কার্যকারিতাটি সেই ব্যক্তিগত কীওয়ার্ডের আড়ালে রয়েছে তাই এটি আপনার পছন্দমতো প্রয়োগ করা যেতে পারে ... সুতরাং আপনি একে একে সুন্দর এবং মডুলারও বানাতে পারেন, যদিও তার কিছুটা প্রথমে বলা হওয়ার আগে নির্ভর করে।

2. একে অপরের সাথে নোড সংযোগ স্থাপন কোনও ব্যক্তিগত ফাংশন নাও হতে পারে

যদি কোন পর্যায়ে আপনি অ্যারেতে অন্য নোড যুক্ত করতে চান? আপনি এখন যে সেটআপটি রেখেছেন তা ধ্বংস করে ফেলেছেন এবং এটি সম্পূর্ণ পুনরায় আরম্ভ করবেন? অথবা আপনি বিদ্যমান অ্যারেতে নোড যুক্ত করে connectNodesআবার চালাবেন ?

connectNodesনোডের অ্যারে এখনও তৈরি না করা হলে সম্ভবত একটি বুদ্ধিমান প্রতিক্রিয়া হতে পারে (একটি ব্যতিক্রম নিক্ষেপ করুন? খালি সেটটি ফেরত দিন? আপনার পরিস্থিতির জন্য কী বোঝায় তা আপনি সিদ্ধান্ত নিতে পারেন)।


আমি 1 এর মতো একইভাবে ভাবছিলাম, এবং নোডগুলি আরম্ভ না করা হলে আমি একটি ব্যতিক্রম বা কিছু নিক্ষেপ করতে পারি, তবে এটি বিশেষ স্বজ্ঞাত নয়। উত্তরের জন্য ধন্যবাদ.
mcfroob

4

আপনি এটিও খুঁজে পেতে পারেন (এই প্রতিটি কার্যক্রমে কতটা জটিল তার উপর নির্ভর করে) যে এটি অন্য শ্রেণীর বিভক্ত করার জন্য একটি ভাল সিউন।

(সুইফট এইভাবে কাজ করে তবে সিউডো-কোড নিশ্চিত নয় :)

class YourClass {
    init(generator: NodesGenerator) {
        self.nodes = connectNodes(generator.make())
    }
    private func connectNodes() {

    }
}

class NodesGenerator {
    public func make() {
        // Return some nodes from storage or make new ones
    }
}

এটি নোডগুলি পৃথক শ্রেণিতে তৈরি ও সংশোধন করার দায়িত্বগুলি পৃথক করে: NodeGeneratorকেবল নোডগুলি তৈরি / পুনরুদ্ধার করার বিষয়ে চিন্তা করে, তবে YourClassকেবলমাত্র নোডগুলি সংযুক্ত করার বিষয়ে যত্নশীল।


2

এটি ব্যক্তিগত পদ্ধতির সঠিক উদ্দেশ্য ছাড়াও, সুইফট আপনাকে অভ্যন্তরীণ ফাংশনগুলি ব্যবহার করার ক্ষমতা দেয়।

অভ্যন্তরীণ পদ্ধতিগুলি কেবলমাত্র একক কল সাইট রয়েছে এমন ফাংশনগুলির জন্য উপযুক্ত, তবে তারা পৃথক ব্যক্তিগত ফাংশন হওয়ার ন্যায্যতা প্রমাণ করে না বলে মনে হয়।

উদাহরণস্বরূপ, একটি সার্বজনীন পুনরাবৃত্ত "এন্ট্রি" ফাংশন থাকা খুব সাধারণ বিষয়, যা পূর্ব শর্তাদি পরীক্ষা করে, কিছু পরামিতি সেট করে, এবং কাজ করে এমন একটি ব্যক্তিগত পুনরাবৃত্ত ফাংশনে প্রতিনিধিদের।

এই ক্ষেত্রে এটি কীভাবে দেখা যায় তার একটি উদাহরণ এখানে দেওয়া হয়েছে:

init() {
    self.nodes = setupNodes()

    func setupNodes() {
        var nodes = createNodes()
        connect(Nodes: nodes)
    }

    private func createNodes() -> [Node]{
        // 1. Create array of nodes
    }

    func connect(Nodes: [Node]) {
        // 2. Go through array, connecting each node to its neighbors 
        //    according to some predefined constants
    }
}

ভাগ করে নেওয়ার স্থিতি পরিবর্তনের পরিবর্তে আমি কীভাবে ডেটার চারপাশে ফেরতের মান এবং পরামিতি ব্যবহার করি সেদিকে মনোযোগ দিন। বাস্তবায়নে ঝাঁপিয়ে পড়ার দরকার ছাড়াই এটি প্রথম নজরে ডেটা প্রবাহকে আরও স্পষ্ট করে তোলে।


0

আপনি যে ঘোষণা করেন তা প্রতিটি ডকুমেন্টেশন যুক্ত করার এবং এটিকে সাধারণীকরণের বোঝা বহন করে যাতে প্রোগ্রামের অন্যান্য অংশগুলি এটি ব্যবহারযোগ্য হয়। কোডটি পড়ার জন্য ফাইলের অন্যান্য ফাংশন কীভাবে এটি ব্যবহার করতে পারে তা বোঝার বোঝা বহন করে।

তবে এটি যদি আপনার প্রোগ্রামের অন্যান্য অংশ ব্যবহার না করে তবে আমি এটিকে আলাদা ফাংশন হিসাবে প্রকাশ করব না।

যদি আপনার ভাষা এটি সমর্থন করে তবে আপনার নেস্টেড ফাংশনগুলি ব্যবহার করে এখনও এক-ফাংশন-ডু-ওন-জিনিস থাকতে পারে

function setupNodes ()  {
  function createNodes ()  {...} 
  function connectNodes ()  {...}
  createNodes() 
  connectNodes() 
} 

ঘোষণার স্থানটি খুব বেশি গুরুত্বপূর্ণ এবং উপরের উদাহরণে এটি আরও পরিষ্কার করে না দিয়ে বোঝা যাচ্ছে যে অভ্যন্তরীণ ফাংশনগুলি কেবল বাহ্যিক ক্রিয়াকলাপের দেহের মধ্যেই ব্যবহৃত হতে পারে।

এমনকি যদি আপনি তাদের ব্যক্তিগত ফাংশন হিসাবে ঘোষণা করছেন তবে আমি ধরে নিই যে তারা এখনও পুরো ফাইলটিতে দৃশ্যমান। সুতরাং আপনাকে তাদের মূল ফাংশনটির ঘোষণার কাছাকাছি ঘোষণা করতে হবে এবং এমন কিছু ডকুমেন্টেশন যুক্ত করতে হবে যা স্পষ্ট করে যে এগুলি কেবল বাহ্যিক ক্রিয়াকলাপ দ্বারা ব্যবহৃত হবে।

আমি মনে করি না যে আপনাকে কঠোরভাবে একটি বা অন্যটি করতে হবে। সর্বোত্তম জিনিসটি কেস ভিত্তিতে কেস অনুসারে পরিবর্তিত হয়।

এটিকে একাধিক ফাংশনে বিভক্ত করা অবশ্যই 3 টি ফাংশন এবং সেগুলি একে অপরের সাথে কীভাবে কাজ করে তা বোঝার একটি ওভারহেড যুক্ত করে, তবে যদি যুক্তিটি জটিল হয় তবে জটিল যুক্তিটিকে ভেঙে ফেলার মাধ্যমে এই যুক্ত করা ওভারহেডটি সরলতার চেয়ে অনেক কম হতে পারে সহজ অংশে।


আকর্ষণীয় বিকল্প। আপনি যেমন বলেছিলেন, আমি মনে করি এটি ফাংশনটি কেন এইরকম ঘোষিত হয়েছিল তা কিছুটা আশ্চর্যজনক হতে পারে তবে এটি ফাংশন নির্ভরতা ভাল রাখবে।
এমসিফ্রুব

এই প্রশ্নের কিছু অনিশ্চয়তার উত্তর দিতে: 1) হ্যাঁ, সুইফট অভ্যন্তরীণ ফাংশনগুলিকে সমর্থন করে এবং 2) এতে "বেসরকারী" এর দুটি স্তর রয়েছে। privateকেবলমাত্র ঘেরের ধরণের (স্ট্রাক্ট / শ্রেণি / এনাম) মধ্যে fileprivateঅ্যাক্সেসের অনুমতি দেয় , তবে পুরো ফাইল জুড়ে অ্যাক্সেসের অনুমতি দেয়
আলেকজান্ডার - মনিকা পুনরায় স্থাপন করুন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.