Java/๐Ÿ“• Effective Java

[Effective Java] ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค ไธŠ

soogoori 2024. 9. 25. 23:13

15. ํด๋ž˜์Šค์™€ ๋ฉค๋ฒ„์˜ ์ ‘๊ทผ ๊ถŒํ•œ์„ ์ตœ์†Œํ™” 

์ ‘๊ทผ ์ œํ•œ์ž๋ฅผ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ •๋ณด ์€๋‹‰(์บก์Šํ™”)์˜ ํ•ต์‹ฌ 

 

  • ๋ชจ๋“  ํด๋ž˜์Šค์™€ ๋ฉค๋ฒ„์˜ ์ ‘๊ทผ์„ฑ์„ ๊ฐ€๋Šฅํ•œ ํ•œ ์ขํ˜€์•ผ ํ•จ
  • ํŒจํ‚ค์ง€ ์™ธ๋ถ€์—์„œ ์“ธ ์ด์œ ๊ฐ€ ์—†๋‹ค๋ฉด package-private์œผ๋กœ ์„ ์–ธ
  • ํ•œ ํด๋ž˜์Šค์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” package-private ํ†ฑ๋ ˆ๋ฒจ ํด๋ž˜์Šค๋‚˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค ์•ˆ์— private static์œผ๋กœ ์ค‘์ฒฉ์‹œํ‚ค๊ธฐ
  • โœจ public์ผ ํ•„์š”๊ฐ€ ์—†๋Š” ํด๋ž˜์Šค์˜ ์ ‘๊ทผ ์ˆ˜์ค€์„ package-private ํ†ฑ๋ ˆ๋ฒจ ํด๋ž˜์Šค๋กœ ์ขํžˆ๊ธฐ 

โœณ๏ธ ์ ‘๊ทผ ์ˆ˜์ค€ 

  • private : ๋ฉค๋ฒ„๋ฅผ ์„ ์–ธํ•œ ํ†ฑ๋ ˆ๋ฒจ ํด๋ž˜์Šค์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ 
  • package-private : ๋ฉค๋ฒ„๊ฐ€ ์†Œ์†๋œ ํŒจํ‚ค์ง€ ์•ˆ์˜ ๋ชจ๋“  ํด๋ž˜์Šค์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅ. ์ ‘๊ทผ ์ œํ•œ์ž๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์•˜์„ ๋•Œ ์ ์šฉ๋˜๋Š” ํŒจํ‚ค์ง€ ์ ‘๊ทผ ์ˆ˜์ค€.
  • protected : package-private์˜ ์ ‘๊ทผ ๋ฒ”์œ„๋ฅผ ํฌํ•จํ•˜๋ฉฐ, ์ด ๋ฉค๋ฒ„๋ฅผ ์„ ์–ธํ•œ ํด๋ž˜์Šค์˜ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ๋„ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • public : ๋ชจ๋“  ๊ณณ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅ 

 

โœณ๏ธ ์ ‘๊ทผ ๊ถŒํ•œ ์ •ํ•˜๊ธฐ 

  • ํด๋ž˜์Šค์˜ ๊ณต๊ฐœ API ์„ค๊ณ„ ํ›„(=public) ๊ทธ ์™ธ์˜ ๋ชจ๋“  ๋ฉค๋ฒ„๋Š” private์œผ๋กœ ๋งŒ๋“ค๊ธฐ
  • ๊ฐ™์€ ํŒจํ‚ค์ง€์˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค๊ฐ€ ์ ‘๊ทผํ•ด์•ผํ•˜๋Š” ๋ฉค๋ฒ„์— ํ•œํ•˜์—ฌ package-private์œผ๋กœ ํ’€์–ด์ฃผ๊ธฐ
  • protected ๋ฉค๋ฒ„ ์ˆ˜๋Š” ์ ์„์ˆ˜๋ก ์ข‹์Œ ๐Ÿ‘‰ ๋ฉค๋ฒ„์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€์ƒ ๋ฒ”์œ„๊ฐ€ ๋„“์–ด์ง€๋ฏ€๋กœ
  • ์ƒ์œ„ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•  ๋•Œ๋Š” ์ ‘๊ทผ ์ˆ˜์ค€์„ ์ƒ์œ„ ํด๋ž˜์Šค์—์„œ๋ณด๋‹ค ์ข๊ฒŒ ์„ค์ • ๋ถˆ๊ฐ€ 
    • ์ƒ์œ„ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋Š” ํ•˜์œ„ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋กœ ๋Œ€์ฒดํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ
  • โœจ public ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ํ•„๋“œ๋Š” ๋˜๋„๋ก public์ด ์•„๋‹ˆ์–ด์•ผ ํ•จ
    • ๊ทธ ํ•„๋“œ์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ๊ฒƒ ๋ถˆ๋ณ€์‹ ๋ณด์žฅ X
    • ํ•„๋“œ๊ฐ€ ์ˆ˜์ •๋  ๋•Œ ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•  ์ˆ˜ ์—†๊ฒŒ ๋˜๋ฏ€๋กœ public ๊ฐ€๋ณ€ ํ•„๋“œ๋ฅผ ๊ฐ–๋Š” ํด๋ž˜์Šค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์Šค๋ ˆ๋“œ ์•ˆ์ „ X
    • ์ƒ์ˆ˜๋ผ๋ฉด public static final ํ•„๋“œ๋กœ ๊ณต๊ฐœ ๊ฐ€๋Šฅ ๐Ÿ‘‰ ๋Œ€๋ฌธ์ž ์•ŒํŒŒ๋ฒณ ๋˜๋Š” ๊ฐ ๋‹จ์–ด ์‚ฌ์ด์— _ ์‚ฌ์šฉ
  • โœจ ๊ธธ์ด๊ฐ€ 0์ด ์•„๋‹Œ ๋ฐฐ์—ด์€ ๋ชจ๋‘ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ํด๋ž˜์Šค์—์„œ public static final ๋ฐฐ์—ด ํ•„๋“œ๋ฅผ ๋‘๊ฑฐ๋‚˜ ์ด ํ•„๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ ‘๊ทผ์ž ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ด์„œ๋Š” ์•ˆ๋จ
public static final Thing[] VALUES = { ... }; // ๋ฐฐ์—ด์˜ ๋‚ด์šฉ ์ˆ˜์ • ๊ฐ€๋Šฅ

๐Ÿ‘† ๋ฐฐ์—ด ์ฐธ์กฐ๋Š” ์ˆ˜์ • ๋ถˆ๊ฐ€ (VALUES ๋ณ€์ˆ˜๋ฅผ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด๋กœ ์žฌํ• ๋‹น ๋ถˆ๊ฐ€)  /  ๋ฐฐ์—ด์˜ ์š”์†Œ๋Š” ์ˆ˜์ • ๊ฐ€๋Šฅ 

 

 

์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๋กœ ํ•ด๊ฒฐ 

private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES = 
	Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));

๐Ÿ‘‰ ์•ž์„  ์ฝ”๋“œ์˜ public ๋ฐฐ์—ด์„ private์œผ๋กœ ๋งŒ๋“ค๊ณ  public ๋ถˆ๋ณ€ ๋ฆฌ์ŠคํŠธ ์ถ”๊ฐ€ 

 

private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
	return PRIVATE_VALUES.clone();
}

๐Ÿ‘‰ private์œผ๋กœ ๋ฐฐ์—ด์„ ๋งŒ๋“ค๊ณ  ๊ทธ ๋ณต์‚ฌ๋ณธ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” public ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€ (๋ฐฉ์–ด์  ๋ณต์‚ฌ)

 

 

 

16. public ํด๋ž˜์Šค์—์„œ๋Š” public ํ•„๋“œ๊ฐ€ ์•„๋‹Œ ์ ‘๊ทผ์ž ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ 

Class Point {
    public double x;
    public double y;
}

๋งŒ์•ฝ ์œ„์™€ ๊ฐ™์ด public ์œผ๋กœ ์ž‘์„ฑํ•œ๋‹ค๋ฉด ... 

  • ๋ฐ์ดํ„ฐ ํ•„๋“œ์— ์ง์ ‘ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ์บก์Šํ™”์˜ ์ด์  ์ œ๊ณต X
  • API๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ ์„œ๋Š” ๋‚ด๋ถ€ ํ‘œํ˜„ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†์Œ
    • ๋‚ด๋ถ€์ ์œผ๋กœ ์ขŒํ‘œ๋ฅผ double๋กœ ํ‘œํ˜„ํ•˜์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด, ์™ธ๋ถ€์—์„œ ์ด๋ฏธ x, y ํ•„๋“œ์— ์ง์ ‘ ์ ‘๊ทผํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด API ์ž์ฒด๋ฅผ ๋ฐ”๊ฟ”์•ผ ํ•˜๋Š” ์ƒํ™ฉ ๋ฐœ์ƒ
  • ๋ถˆ๋ณ€์‹ ๋ณด์žฅ X
  • ์™ธ๋ถ€์—์„œ ํ•„๋“œ์— ์ ‘๊ทผํ•  ๋•Œ ๋ถ€์ˆ˜ ์ž‘์—… ์ˆ˜ํ–‰ X

 

๐Ÿ‘‰ private์œผ๋กœ ๋ฐ”๊พธ๊ณ , public ์ ‘๊ทผ์ž (getter) ์‚ฌ์šฉ !

 

package-private ํด๋ž˜์Šค ํ˜น์€ private ์ค‘์ฒฉ ํด๋ž˜์Šค๋ผ๋ฉด ๋ฐ์ดํ„ฐ ํ•„๋“œ๋ฅผ ๋…ธ์ถœํ•ด๋„ ๊ดœ์ฐฎ์Œ !

 

 

 

17. ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์„ ์ตœ์†Œํ™” 

โœณ๏ธ ๋ถˆ๋ณ€ ํด๋ž˜์Šค๋ž€ ...

๐Ÿ‘‰ ์ธ์Šคํ„ด์Šค์˜ ๋‚ด๋ถ€ ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋Š” ํด๋ž˜์Šค 

 

 

โœณ๏ธ ํด๋ž˜์Šค๋ฅผ ๋ถˆ๋ณ€์œผ๋กœ ๋งŒ๋“ค๋ ค๋ฉด .. 

  • ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฉ”์„œ๋“œ(๋ณ€๊ฒฝ์ž)๋ฅผ ์ œ๊ณต X
  • ํด๋ž˜์Šค ํ™•์žฅํ•  ์ˆ˜ ์—†๊ฒŒ ํ•จ 
  • ๋ชจ๋“  ํ•„๋“œ๋ฅผ final๋กœ ์„ ์–ธ
  • ๋ชจ๋“  ํ•„๋“œ๋ฅผ private์œผ๋กœ ์„ ์–ธ
  • ์ž์‹  ์™ธ์—๋Š” ๋‚ด๋ถ€์˜ ๊ฐ€๋ณ€ ์ปดํฌ๋„ŒํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก ํ•จ

โœณ๏ธ ๋ถˆ๋ณ€ ํด๋ž˜์Šค์˜ ์žฅ๋‹จ์   

  • ๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ๊ทผ๋ณธ์ ์œผ๋กœ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜์—ฌ ๋”ฐ๋กœ ๋™๊ธฐํ™”ํ•  ํ•„์š” X
  • ๋ถˆ๋ณ€ ํด๋ž˜์Šค๋ผ๋ฉด ํ•œ ๋ฒˆ ๋งŒ๋“  ์ธ์Šคํ„ด์Šค๋ฅผ ์ตœ๋Œ€ํ•œ ์žฌํ™œ์šฉ ๐Ÿ‘‰ public static final
  • ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์บ์‹ฑํ•˜์—ฌ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ค‘๋ณต ์ƒ์„ฑํ•˜์ง€ ์•Š๊ฒŒ ํ•ด์คŒ ๐Ÿ‘‰ ์ •์  ํŒฉํ† ๋ฆฌ
  • ๋ถˆ๋ณ€ ๊ฐ์ฒด๋ผ๋ฆฌ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ ๊ณต์œ  ๊ฐ€๋Šฅ
  • ๊ฐ’์ด ๋‹ค๋ฅด๋ฉด ๋ฐ˜๋“œ์‹œ ๋…๋ฆฝ๋œ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•จ ๐Ÿ‘‰ ๊ฐ’์˜ ๊ฐ€์ง“์ˆ˜๊ฐ€ ๋งŽ์œผ๋ฉด ๋งŒ๋“œ๋Š” ๋ฐ ํฐ ๋น„์šฉ ๋“ฆ

โœณ๏ธ ๋ถˆ๋ณ€ ํด๋ž˜์Šค ์„ค๊ณ„ ๋ฐฉ๋ฒ• 

  • ์ž์‹ ์„ ์ƒ์†ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•ด์•ผ ํ•จ
    • final ํด๋ž˜์Šค๋กœ ์„ ์–ธ
    • ๋ชจ๋“  ์ƒ์„ฑ์ž๋ฅผ private ํ˜น์€ package-private์œผ๋กœ ๋งŒ๋“ค๊ณ  public ์ •์  ํŒฉํ† ๋ฆฌ ์ œ๊ณต
public class Complex{
	private final double re;
	private final double im;
    
    private Complex(double re, double im){
    	this.re = re;
        this.im = im;
    }
    
    public static Complex valueOf(double re, double im){
    	return new Complex(re, im);
    }
    
    ... // ์ƒ๋žต
}
  • setter ๋งŒ๋“ค์ง€ ๋ง๊ธฐ
  • ๋‹ค๋ฅธ ํ•ฉ๋‹นํ•œ ์ด์œ ๊ฐ€ ์—†๋‹ค๋ฉด ๋ชจ๋“  ํ•„๋“œ๋Š” private final
  • ์ƒ์„ฑ์ž๋Š” ๋ถˆ๋ณ€์‹ ์„ค์ •์ด ๋ชจ๋‘ ์™„๋ฃŒ๋œ, ์ดˆ๊ธฐํ™”๊ฐ€ ์™„๋ฒฝํžˆ ๋๋‚œ ์ƒํƒœ์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•จ