2012-08-28 11 views
35

मैं एक परियोजना पर काम कर रहा हूं, और वर्तमान में लॉग 4j के साथ कुछ लॉगिंग लागू करने पर काम कर रहा हूं और मैं इस बारे में उत्सुक था कि मुझे लॉग को लागू करने के बारे में कैसे जाना चाहिए।सार कक्षाओं के साथ जावा लॉगिंग

उपयोग उस वर्ग के लिए सुपर क्लास से एकल प्रवेश और सभी उप वर्गों

पहला विकल्प:

public abstract class AbstractFoo { 
    protected static Log LOG = LogFactory.getLog(AbstractFoo.class); 

    ... 
} 

public class Foo extends AbstractFoo { 
    public void someMethod() { 
     LOG.info("Using abstract log"); 
    } 
} 

दूसरा ऑप्शन

दो कार्यान्वयन मैं चारों ओर लात हूँ इस प्रकार हैं

प्रत्येक वर्ग, सुपर और सबस के लिए अलग-अलग लॉग का उपयोग करें:

public abstract class AbstractFoo { 
    private static Log LOG = LogFactory.getLog(AbstractFoo.class); 

    ... 
} 

public class Foo extends AbstractFoo { 
    private static Log LOG = LogFactory.getLog(Foo.class);   

    public void someMethod() { 
     LOG.info("Using own log"); 
    } 
} 

क्या अधिक समझ में आता है और क्यों?

उत्तर

58

मैं या तो नहीं करूँगा। इसके बजाय मैं इसे दोनों मामलों में सही वर्ग का उपयोग कर दूंगा।

public abstract class AbstractFoo { 
    protected final Log log = LogFactory.getLog(getClass()); 

    ... 
} 

public class Foo extends AbstractFoo { 
    public void someMethod() { 
     log.info("Using abstract log"); 
    } 
} 

यदि आप बहुत सारे लॉगिंग नहीं कर रहे हैं (जो कि एक अच्छा विचार है) तो आप इसके बजाय एक विधि का उपयोग कर सकते हैं।

public abstract class AbstractFoo { 
    protected Log log() { return LogFactory.getLog(getClass()); } 

    ... 
} 

यदि कोई कक्षा है जो इसे बहुत कहती है तो आप इसे कैश किए गए उदाहरण देने के लिए ओवरराइड कर सकते हैं।

+1

अब तक मैंने दो दृष्टिकोण देखे हैं: स्थिर लॉगर्स (प्रश्न में) और गैर स्थैतिक लॉगर्स (जैसा कि आपके उदाहरण में है)। स्थिर लॉगर्स बेहतर समाधान नहीं हैं (सभी उदाहरणों के लिए लॉगर का एक उदाहरण)? –

+4

स्थैतिक लॉगर्स बेहतर हैं अगर वे सभी उदाहरणों के लिए समान हैं। अमूर्त वर्ग के मामले में, उदाहरणों की कक्षा सभी समान नहीं हैं। –

+0

मुझे यह पसंद है, यह दोनों विकल्पों को गठबंधन करने का एक अच्छा तरीका प्रतीत होता है।आप एक ही लॉग के साथ समाप्त होते हैं लेकिन यह उचित वर्ग से बांधता है। +1 – shuniar

2

दोनों समझ में आते हैं। यह आपके आवेदन पर निर्भर करता है।

मुझे लगता है कि अधिकतर प्रयुक्त अभ्यास प्रत्येक वर्ग के लिए निजी लॉगर होना है। यह आपको प्रति वर्ग और प्रति पैकेज दोनों लॉगिंग कॉन्फ़िगर करने की अनुमति देता है। याद रखें, AbstractFoo और Foo विभिन्न पैकेजों से संबंधित हो सकता है और शायद आप केवल Foo से लॉग देखना चाहते हैं।

अगर आप protected फ़ील्ड लिखना चाहते हैं तो हमेशा दो बार सोचें। यह पूरी तरह से प्रतिबंधित नहीं है लेकिन एक प्रसिद्ध बुरी प्रथा है। यह आपके कोड को कम पठनीय और बनाए रखने में मुश्किल बनाता है।

1

यदि आप अमूर्त वर्ग में लॉगर बनाते हैं, तो लॉग सभी सारणीफू से उत्पन्न होने के रूप में टैग किए जाएंगे। यदि आप चाहते हैं कि बच्चे वर्ग के साथ टैग किए गए लॉग को देखना है, जिसमें लॉग आया है, तो बच्चों के वर्गों के लिए लॉगर्स बनाएं।

public abstract class AbstractFoo { 
    protected Log getLogger(); 
    public doSomething() { 
      getLogger().info("log something"); 
    } 
} 

public class Foo extends AbstractFoo { 
    private static final Log log = Log.getLogger(Foo.class); 

    protected Log getLogger() { 
     return log; 
    } 
    public doSomethingElse() { 
      log.info("log somethingElse"); 
    } 
} 
+0

"यदि आप अमूर्त वर्ग में लॉगर बनाते हैं, तो लॉग सभी सार तत्व से उत्पन्न होने के रूप में टैग किए जाएंगे" -> नहीं, अगर आप @Peter_Lawrey द्वारा स्वीकृत उत्तर का उपयोग करते हैं तो सत्य नहीं है। फिर आपको हमेशा लॉगिंग करने वाले वर्ग के साथ टैग किए गए लॉग प्राप्त होते हैं। – cellepo

+0

लॉरी के जवाब के साथ 'समस्या' यह है कि वे अब उदाहरण आधारित लॉगर्स हैं, जो कि विचार नहीं है। – MeBigFatGuy

5

यह मेरा समाधान (अंतिम स्थिर लकड़हारा) है। बेस श्रेणी स्तर पर लकड़हारा जोड़े और हर व्युत्पन्न वर्ग का उपयोग कर सुपर से यह सेट()। कोड है:

public abstract class AbstractFoo { 

    protected Log log; // base abstract class has a Log object. 

    public AbstractFoo(Log logger) { // parameterized constructor for logger, to be used by the derived class. 
     this.log = logger; 
    } 

    public doSomething() {  // common method for all the derived classes. 
     log.info("log something"); 
    } 
    // rest of business logic. 
} 

public class Foo extends AbstractFoo { 

    public Foo(){ 
     super(LogFactory.getLog(AbstractFoo.class)); 
    } 

    public void someMethod() { 
     log.info("Using own log");  // this uses its own logger. 
    } 
} 
1

ही कंस्ट्रक्टर्स के साथ खेल के द्वारा प्राप्त किया जा सकता है:

संबंधित मुद्दे