“Start”, “run” veya “execute” yöntemi iyi bir uygulama mıdır?


30

Şu anda Başlat yöntemini uygulayan birçok sınıfa sahip bir kod tabanı üzerinde çalışıyorum. Bu bana her zaman kötü bir uygulama olarak düşündüğüm iki aşamalı bir yapıya benziyor. Bu ve bir kurucu arasındaki farkı söyleyemem.

Normal obje yapımı yerine start metodu kullanmak ne zaman uygundur?

Yapıcıyı ne zaman kullanmayı tercih etmeliyim?

Düzenleme: konuyla alakalı olduğunu sanmıyorum ama programlama dili C #, Java ya da C ++ 'a eşit derecede uygulanabilir.


3
Biraz daha içerik ekler misiniz? Dil? Tek dişli diş vs? startve yapıcı arasındaki fark ? etc ...

@MichaelT Neden sorduğunuzu anlayabiliyorum, ancak uygun olduğunda arkasındaki genel ilkeyle ilgileniyorum. Üzerinde çalıştığım kod tabanından belirli örnekler verirsem, cevapların özel sorularıma değil ayrıntılara odaklanacağını düşünüyorum.
Dave Hillier

2
@DaveHillier Örneğin, perl'de init, newişlev dışında bir tür yönteme sahip olmak standart bir uygulamadır (ve iyi bir yöntemdir ) - perldoc.perl.org/perlobj.html . Bir dilin deyimleri diğer dillerde değil, orada da işe yarayabilir.

1
StartOrtak API'lerde metotlara sahip sınıfların örnekleri arasında iplikler ve kronometreler bulunur.
luiscubal

1
Ne sorduğunu anlamak için bir kod örneğine ihtiyaç duyanlar arasında beni say.
user16764

Yanıtlar:


44

Bir Start()yöntem (gibi Run(), Execute()nesne oluşturmak maliyeti düşüktür, ancak maliyeti, benzer ya da bir şey) uygundur kullanarak bunu yüksektir. Örneğin: En iyi yol optimizasyon algoritmasını içeren bir sınıf. Bir dizi parametre ile ayarlamak önemsizdir ( suchandsuch değerlendirme yöntemiyle Xkareler ile Ykareler), ancak yürütülmesi biraz zaman alabilir. Bu nesnelerden 20 tane oluşturmak istiyorsanız, hepsi oluşturulana kadar yürütmeyi ertelemek isteyebilirsiniz - bu, örneğin onları daha kolay bir şekilde paralellemenizi sağlar.

Alternatif olarak, nesnenin ne zaman başlaması gerektiğini bilmediğiniz zaman faydalı olabilir - belki de kullanıcı girişi veya bir olasılık listesinden seçilen mantığı temel aldığı için faydalı olabilir.

Bu, elbette, Start()nesnede faydalı bir yöntem olduğunu ve bir Initialize()yönteme eşdeğer olmadığını varsaymaktadır . Daha fazla parametre ayarlamak için sadece ekstra bir yöntemse, olmamalıdır.


1
Bir başlangıç ​​yönteminin başka bir kullanımı, yapılan eylemin ayrıca yeni bir çalışan iş parçacığı veya bir zamanlayıcı oluşturmasıdır. Yapıcı bu tür ağır kaldırma işlemi yapmamalı veya önemli yan etkiler yaratmamalıdır (yeni bir diş açmak gibi).
Ziv

50

Code Complete (ve diğer birçok yazılım mühendisliği kaynağı), sınıflarınızı gerçek dünyadaki nesnelerle eşleştirmeye vurgu yapar. Bunun temel nedeninin, somut olmayan bir fikirden kaçınmak yerine, ne uyguladığınıza dair gerçek bir anlayışa sahip olmanızı daha olası kıldığına inanıyorum.

Bu teoriye abone iseniz, Start()herhangi bir sınıfa bir yöntem eklerken yanlış bir şey göremiyorum , gerçek bir nesne miydi, aynı zamanda dinlenmeye de sahip. Çalışmıyorken nesnenizin olması bir anlam ifade etmiyorsa (veya nesnenizin hiç çalışması için bir anlam ifade etmiyorsa), bunun kötü bir uygulama olduğunu söyleyebilirim.


16
İyi bir benzetme. Daha Start()sonra olması gereken bir açma / kapama anahtarına (bir ışık anahtarı gibi) Stop()veya bir basma düğmesine (bir kopya makinesindeki Yazdır düğmesi gibi) karşılık geldiği ve daha sonra bitene kadar çalışabileceği belirtilmelidir.
Bobson

3
+1 iyi dedi ve P.SE'ye hoş geldiniz, bunun gibi cevaplar harika bir başlangıç.
Jimmy Hoffa,

14

Tembel başlatma kullanabilirsiniz .

Bilgisayar programlamasında tembel başlatma, bir nesnenin yaratılmasının, bir değerin hesaplanmasının veya diğer bazı pahalı işlemlerin ilk gerekli olana kadar ertelenmesinin taktiğidir.

Bu şekilde geçici eşleştirmeden kaçınırsınız, yani sınıfınızın tüketicisi belirli yöntemleri belirli bir sırayla çağırmalıdır. Önce aramak start()zorunda kalmak, sınıfın kurum içinde nasıl işlediğini bilmek zorunda bir yöntemdir, ki bu kötüdür, çünkü bunu gelecekte değiştirebilirsin.

İlk gerekli olana kadar pahalı başlatma işlemini geciktirin.

Örnek:

public class FooClass{

    private ExpensiveResource resource;
    private CheapResource cheap;

    public  FooClass(String someParameter){
        // constructor: initialize CheapResource cheap 
            // but NOT ExpensiveResource resource
    }

    public ExpensiveResource getExpensiveResource(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource
    }

    public String getExpensiveResourceName(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource.getName();
    }   

    public CheapResource getCheapResource(){
        return this.cheap;
    }

    private initializeExpensiveResource(){
        // do expensive initialization of field "resource"
    }

}

public class Test{
    public static void main (String args[]){

        FooClass foo = new FooClass("some string");
        CheapResource cr = foo.getCheapResource();
        String s = foo.getExpensiveResourceName(); 
          // just now is the expensive resource initialized

    }
}

5
Kayda değer bir temeli başlatmanın bir başka yararı, sanal bir proxy oluşturmak için çok az çaba sarf etmesidir . Duruma bağlı olarak, bir kaynağın yüklenmesini beklerken bir şey görüntülemek için çok yararlı olabilir (özellikle uzak görüntüler gibi şeyler için kullanışlıdır). Asıl soruya dayanarak, aslında OP'nin hedeflediği şeyin bu olduğunu sanmıyorum, ama söylemeye değer olduğunu düşündüm.
Dan Albert,

@DanAlbert haklısın, istediğim şey bu değildi ama yine de ilginç
Dave Hillier
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.