18. μμ보λ€λ μ»΄ν¬μ§μ μ¬μ©
λ€λ₯Έ ν¨ν€μ§μ ꡬ체 ν΄λμ€λ₯Ό μμνλ μΌμ μν
- λ©μλ νΈμΆκ³Ό λ¬λ¦¬ μμμ μΊ‘μνλ₯Ό κΉ¨λ¨λ¦Ό π μμ ν΄λμ€κ° μ΄λ»κ² ꡬνλλλμ λ°λΌ νμ ν΄λμ€μ λμμ μ΄μ μκΈΈ μ μμ
- μμ ν΄λμ€λ 릴리μ¦λ§λ€ λ΄λΆ ꡬνμ΄ λ¬λΌμ§ μ μλλ°, κ·Έλ‘ μΈν΄ νμ ν΄λμ€κ° μ€λμν μ μμ
β³οΈ μμμ μλͺ» μ¬μ©ν μ
public class InstrumentedHashSet<E> extends HashSet<E> {
private int addCount = 0;
public InstrumentedHashSet(){
}
public InstrumentedHashSet(int initCap, float loadFactor){
super(initCap, loadFactor);
}
@Override
public boolean add(E e){
addCount ++;
return super.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c){
addCount += c.size();
return super.addAll(c);
}
public int getAddCount(){
return getAddCount();
}
}
InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
s.addAll(List.of("ν±", "νν", "ν"));
μμ κ°μ μ½λμμ addAll λ©μλλ‘ μμ 3κ°λ₯Ό λνλ€κ³ νμ λ, κ²°κ³Όλ 3μ΄ μλ 6μ λ°ννλ€.
HashSetμ addAll λ©μλκ° κ° μμλ₯Ό add λ©μλλ₯Ό νΈμΆν΄ μΆκ°νλλ°, μ΄λ λΆλ¦¬λ add λ©μλλ InstrumentedHashSetμμ μ¬μ μν λ©μλλ€. κ·Έλ¬λ―λ‘ addCountμ κ°μ΄ μ€λ³΅ν΄μ λν΄μ Έ 6μ λ°ννλ κ²μ΄λ€.
μ΄μΈμλ λ©μλλ₯Ό μ¬μ μνλ λμ μμ ν΄λμ€μ μλ‘μ΄ λ©μλλ₯Ό μΆκ°ν΄ μ¬μ μμ κ΄λ ¨λ λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ λ°©λ²μ μκ°ν μλ μλ€. νμ§λ§ μ΄ λ©μλκ° μ°μ°νλ νμν΄λμ€μ μΆκ°ν λ©μλμ μκ·Έλμ²κ° κ°κ³ λ°ν νμ μ λ€λ₯΄λ€λ©΄ ν΄λΉ ν΄λμ€λ μ»΄νμΌ μ‘°μ°¨ λμ§ μμ μ μλ€. νΉμ¬λ λ°ν νμ μ΄ κ°λ€λ©΄ μμ ν΄λμ€μ μ λ©μλλ₯Ό μ¬μ μν κ²μ΄λ μ¬μ μμ κ΄λ ¨λ λ¬Έμ κ° λ λ€μ λ°μν μ μλ€.
β³οΈ μ»΄ν¬μ§μ
μμ κ°μ μμκ³Ό κ΄λ ¨λ λ¬Έμ λ₯Ό ν΄κ²°ν μ μλ λ°©λ²μ 'μ»΄ν¬μ§μ ' μ΄λ€.
κΈ°μ‘΄ ν΄λμ€λ₯Ό νμ₯νλ λμ , μλ‘μ΄ ν΄λμ€λ₯Ό λ§λ€κ³ private νλλ‘ κΈ°μ‘΄ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μ°Έμ‘°νκ² νλ©΄ λλ€.
κΈ°μ‘΄ ν΄λμ€κ° μλ‘μ΄ ν΄λμ€μ ꡬμ±μμλ‘ μ°μΈλ€λ λ»μμ μ»΄ν¬μ§μ (ꡬμ±)μ΄λΌ νλ κ²μ΄λ€.
μ ν΄λμ€μ μΈμ€ν΄μ€ λ©μλλ€μ κΈ°μ‘΄ ν΄λμ€(private νλλ‘ μ°Έμ‘°)μ λμνλ λ©μλλ₯Ό νΈμΆν΄μ κ·Έ κ²°κ³Όλ₯Ό λ°ννλ€ = μ λ¬(Forwarding)
β΄οΈ μ λ¬ ν΄λμ€
public class ForwardingSet<E> implements Set<E>{
private final Set<E> s; // private νλλ‘ κΈ°μ‘΄ ν΄λμ€μ μΈμ€ν΄μ€ μ°Έμ‘°
public ForwardingSet(Set<E> s) {this.s = s;} // Setμ μΈμ€ν΄μ€λ₯Ό μΈμλ‘ λ°λ μμ±μ
// μ λ¬ λ©μλ
public void clear() { s.clear(); }
public boolean contains(Object o) {return s.contains(o); }
public boolean isEmpty() { return s.isEmpty(); }
public int size() { return s.size(); }
public Iterator<E> iterator() { return s. iterator(); }
public boolean add(E e) { return s.add(e); }
public boolean remove(Object o) {return s.remove(o); }
public boolean containsAll(Collection<?> c) { return s.containsAll(c); }
public boolean addAll(Collection<? extends E> c) { return s.addAll(c); }
public boolean removeAll(Collection<?> c) { return s.removeAll(c); }
public boolean retainAll(Collection<?> c) { return s.retainAll(c); }
public Object[] toArray() { return s.toArray(); }
public <T> T[] toArray(T[] a) { return s.toArray(a); }
@Override public boolean equals(Object o) { return s.equals(o); }
@Override public int hashCode() {return s.hashCode(); }
@Override public String toString() { return s.toString(); }
}
β΄οΈ λνΌ ν΄λμ€
public class InstrumentedSet<E> extends ForwardingSet<E> {
private int addCount = 0;
public InstrumentedSet(Set<E> s) {
super(s);
}
@Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
@Override
public boolean addAll (Collection< ? extends E > c){
addCount += c.size();
return super.addAll(c);
}
public int getAddCount () {
return addCount;
}
}
λ€λ₯Έ Set μΈμ€ν΄μ€λ₯Ό κ°μΈκ³ μλ€λ λ»μμ InstrumentedSetκ³Ό κ°μ ν΄λμ€λ₯Ό λνΌ ν΄λμ€λΌκ³ νλ€ = Decorator Pattern
μ λ¬ λ©μλλ€μ μμ±νλ κ²μ΄ μ§λ£¨νκ² μ§λ§, μ¬μ¬μ©ν μ μλ μ λ¬ ν΄λμ€λ₯Ό μΈν°νμ΄μ€ λΉ νλμ©λ§ λ§λ€μ΄λλ©΄ μνλ κΈ°λ₯μ λ§μμ°λ μ λ¬ ν΄λμ€λ€μ μμ½κ² ꡬνν μ μλ€.
κ·Έλ λ€λ©΄ μμμ μΈμ μ¬μ©λλ κ²μΌκΉ??
λ°λμ νμ ν΄λμ€κ° μμ ν΄λμ€μ 'μ§μ§' νμ νμ μΈ μν©μμλ§ μ¬μ©νλ©΄ λλ€.
μ¦, is-a κ΄κ³μΌ λλ§ μμνλ©΄ λλ κ²μ΄λ€.
19. μμμ κ³ λ €ν΄ μ€κ³νκ³ λ¬ΈμννκΈ°. κ·Έλ μ§ μμΌλ©΄ μμ κΈμ§
μμμ© ν΄λμ€λ μ¬μ μν μ μλ λ©μλλ€μ λ΄λΆμ μΌλ‘ μ΄λ»κ² μ΄μ©νλμ§ λ¬Έμλ‘ λ¨κ²¨μΌ ν¨
20. μΆμ ν΄λμ€λ³΄λ€λ μΈν°νμ΄μ€λ₯Ό μ°μ !
λ€μ€ ꡬνμ© νμ μΌλ‘λ μΈν°νμ΄μ€κ° κ°μ₯ μ ν©
μλ°κ° μ 곡νλ λ€μ€ ꡬν λ©μ»€λμ¦μ μΈν°νμ΄μ€μ μΆμ ν΄λμ€ λ κ°μ§κ° μλ€.
- μΈν°νμ΄μ€
- μΈν°νμ΄μ€κ° μ μΈν λ©μλλ₯Ό λͺ¨λ μ μνκ³ μΌλ° κ·μ½μ μ μ§ν¨ ν΄λμ€λΌλ©΄ λ€λ₯Έ μ΄λ€ ν΄λμ€λ₯Ό μμνλ κ°μ νμ μΌλ‘ μ·¨κΈλ¨
- μΆμ ν΄λμ€
- μΆμ ν΄λμ€κ° μ μν νμ μ ꡬννλ ν΄λμ€λ λ°λμ μΆμ ν΄λμ€μ νμ ν΄λμ€κ° λμ΄μΌ ν¨
- μλ°λ λ¨μΌ μμλ§ μ§μνλ―λ‘ μλ‘μ΄ νμ μ μ μνλ λ° μ μ½μ΄ μμ
interface Vehicle {
void drive();
}
class Car {
// Carλ§μ κ³ μ ν λ©μλ
public void honk() {
System.out.println("Honk!");
}
}
// Carλ₯Ό μμλ°μΌλ©΄μ Vehicle μΈν°νμ΄μ€λ ꡬν
class SportsCar extends Car implements Vehicle {
@Override
public void drive() {
System.out.println("Driving a sports car!");
}
}
π SportsCarκ° Carλ₯Ό μμλ°μμ§λ§ κ·Έμ μκ΄μμ΄ Vehicle μΈν°νμ΄μ€λ₯Ό ꡬννκΈ° λλ¬Έμ, Vehicle νμ μΌλ‘ μ·¨κΈν μ μμ
β³οΈ μΈν°νμ΄μ€ μ₯μ
- κΈ°μ‘΄ ν΄λμ€μλ μμ½κ² μλ‘μ΄ μΈν°νμ΄μ€λ₯Ό ꡬνν΄ λ£μ μ μμ
- μΈν°νμ΄μ€κ° μꡬνλ λ©μλλ₯Ό μΆκ°νκ³ ν΄λμ€ μ μΈμ implements κ΅¬λ¬Έλ§ μΆκ°νλ©΄ λ¨
- λ§μ½ λ ν΄λμ€κ° κ°μ μΆμ ν΄λμ€λ₯Ό νμ₯νκΈΈ μνλ€λ©΄ κ·Έ μΆμ ν΄λμ€λ κ³μΈ΅ ꡬ쑰 μ λ ν΄λμ€μ κ³΅ν΅ μ‘°μμ΄μ΄μΌ ν¨
π μλ‘ μΆκ°λ μΆμ ν΄λμ€μ λͺ¨λ μμμ΄ μ΄λ₯Ό μμνκ² λ¨. κ·Έλ κ² νλ κ²μ΄ μ μ νμ§ μμ μν©μμλ κ°μ λ‘ ν μλ°μ μμ
- λ―Ήμ€μΈ(mixin) μ μμ μμ±λ§μΆ€
- mixin : νΉμ ν΄λμ€κ° μμ μμ΄ λ€λ₯Έ ν΄λμ€μ κΈ°λ₯μ μ¬μ¬μ©ν μ μλλ‘ νλ λ°©μ
- κ³μΈ΅ κ΅¬μ‘°κ° μλ νμ νλ μμν¬λ₯Ό λ§λ€ μ μμ
public interface Singer{
public void sing();
}
public interface SongWriter{
public void compose();
}
public interface SingerSongWriter extends Singer, SongWriter{
public void actSensitive();
}
Singerμ SongWriter λͺ¨λλ₯Ό νμ₯νκ³ μλ‘μ΄ λ©μλκΉμ§ μΆκ°ν μ 3μ μΈν°νμ΄μ€λ₯Ό μ μν μ μμ
β³οΈ μΈν°νμ΄μ€μ μΆμ 골격 ꡬν ν΄λμ€ ν¨κ» μ¬μ© π ν νλ¦Ώ λ©μλ ν¨ν΄
- μΈν°νμ΄μ€λ‘λ νμ μ μ + λν΄νΈ λ©μλ
- 골격 ꡬν ν΄λμ€λ λλ¨Έμ§ λ©μλκΉμ§ ꡬν
π μΈν°νμ΄μ€μ κΈ°λ³Έμ μΈ κ΅¬νμ μ 곡νλ©΄μ, μΌλΆ λ©μλλ μΆμ λ©μλλ‘ λ¨κ²¨λμ΄ νμ ν΄λμ€μμ ꡬννλλ‘ λ§λλ ν΄λμ€ - κ΄λ‘μ μΈν°νμ΄μ€μ μ΄λ¦μ΄ InterfaceλΌλ©΄ 골격 ꡬν ν΄λμ€λ AbstractInterfaceλ‘ μ§μ
public abstract class AbstractList<E> implements List<E> {
// List μΈν°νμ΄μ€μ μΌλΆ λ©μλλ 미리 ꡬν
@Override
public boolean add(E e) {
add(size(), e);
return true;
}
@Override
public boolean isEmpty() {
return size() == 0;
}
// ν΅μ¬ λ©μλλ μ¬μ ν μΆμ λ©μλλ‘ λ¨κ²¨λ
public abstract E get(int index);
public abstract int size();
public abstract void add(int index, E element);
}
public class MyArrayList<E> extends AbstractList<E> {
private E[] data;
private int size;
public MyArrayList() {
data = (E[]) new Object[10];
size = 0;
}
@Override
public E get(int index) {
return data[index];
}
@Override
public int size() {
return size;
}
@Override
public void add(int index, E element) {
data[index] = element;
size++;
}
}
21. μΈν°νμ΄μ€λ ꡬννλ μͺ½μ μκ°ν΄ μ€κ³νκΈ°
- μλ° 8μμ μΈν°νμ΄μ€μ λν΄νΈ λ©μλκ° μΆκ°λ¨ π λλ€ νμ©νκΈ° μν΄μ
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean result = false;
for(Iterator<E> it = iterator(); it.hasNext(); ) {
if(filter.test(it.next())) {
it.remove();
result = true;
}
}
return result;
}
removeIfλ Collection μΈν°νμ΄μ€μ μΆκ°λ λν΄νΈ λ©μλμ΄λ€.
μ΄ λ©μλλ λͺ¨λ Collection ꡬν체μ μ μ΄μ°λ¬μ§λ κ²μ μλλ€.
μνμΉμ SynchronizedCollection ν΄λμ€λ ν΄λΌμ΄μΈνΈκ° μ 곡ν κ°μ²΄λ‘ λ½μ κ±°λ λ₯λ ₯μ μΆκ°λ‘ μ 곡νκ³ μλ€.
νμ§λ§ removeIf λ©μλλ₯Ό μ¬μ μνκ³ μμ§ μλ€. μ¦, λͺ¨λ λ©μλ νΈμΆμ μμμ λκΈ°νν΄μ£Όμ§ λͺ»νλ κ²μ΄λ€.
removeIfμ ꡬνμ λκΈ°νμ κ΄ν΄ μ무κ²λ λͺ¨λ₯΄λ―λ‘ λ½ κ°μ²΄λ₯Ό μ¬μ©ν μ μμ΄ removeIfλ₯Ό νΈμΆνλ©΄ ConcurrentModificationExceptionμ΄ λ°μνκ±°λ λ€λ₯Έ μκΈ°μΉ λͺ»ν κ²°κ³Όλ‘ μ΄μ΄μ§ μ μλ€.
μ΄λ¬ν λ¬Έμ λ₯Ό μλ°©νκΈ° μν΄ μλ°μμλ ꡬνν μΈν°νμ΄μ€μ λν΄νΈ λ©μλλ₯Ό μ¬μ μνκ³ , λ€λ₯Έ λ©μλμμλ λν΄νΈ λ©μλλ₯Ό νΈμΆνκΈ° μ μ νμν μμ μ μννλλ‘ νλ€.
22. μΈν°νμ΄μ€λ νμ μ μ μνλ μ©λλ‘λ§ μ¬μ©νκΈ°
ν΄λμ€κ° μ΄λ€ μΈν°νμ΄μ€λ₯Ό ꡬννλ€ = μμ μ μΈμ€ν΄μ€λ‘ 무μμ ν μ μλμ§λ₯Ό ν΄λΌμ΄μΈνΈμ μκΈ°ν΄μ£Όλ κ²
μμ 곡κ°μ© μλ¨μΌλ‘ μ¬μ© X
- μμ μΈν°νμ΄μ€ = static final νλλ‘λ§ κ°λ μ°¬ μΈν°νμ΄μ€
- ν΄λμ€ λ΄λΆμμ μ¬μ©νλ μμλ μΈλΆ μΈν°νμ΄μ€κ° μλλΌ λ΄λΆ ꡬνμ ν΄λΉν¨
- μμ μΈν°νμ΄μ€λ₯Ό ꡬννλ κ²μ λ΄λΆ ꡬνμ ν΄λμ€μ APIλ‘ λ ΈμΆνλ νμμ΄λ―λ‘ μ¬μ©μμκ² νΌλμ μ€ μ μκ±°λ ν΄λΌμ΄μΈνΈ μ½λκ° λ΄λΆ ꡬνμ ν΄λΉνλ μ΄ μμλ€μ μ’ μλκ² ν¨
- μμλ₯Ό 곡κ°ν λͺ©μ μ΄λΌλ©΄ κ·Έ ν΄λμ€λ μΈν°νμ΄μ€ μ체μ μΆκ°ν΄μΌ ν¨
- μ΄κ±° νμ μΌλ‘ λνλ΄κΈ° μ ν©ν μμλΌλ©΄ μ΄κ±° νμ (ENUM)μΌλ‘ !
- μΈμ€ν΄μ€νν μ μλ μ νΈλ¦¬ν° ν΄λμ€μ λ΄μ 곡κ°νκΈ°
π μ μλ μμλ₯Ό ν΄λΌμ΄μΈνΈμμ μ¬μ©νλ €λ©΄ ν΄λμ€ μ΄λ¦κΉμ§ λͺ μν΄μΌ ν¨ = PhysicalConstants.AVOGARDOS_NUMBER
// μμ μ νΈλ¦¬ν° ν΄λμ€
public class PhysicalConstants {
private PhysicalConstants() {} // μΈμ€ν΄μ€ν λ°©μ§
static final double AVOGADROS_NUMBER = 6.022;
static final double BOLTZMANN_CONSTANT = 1.38;
static final double ELECTRON_MASS = 9.109;
}
'Java > π Effective Java' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[π Effective Java] μ λ€λ¦ δΈ (0) | 2024.10.12 |
---|---|
[π Effective Java] ν΄λμ€μ μΈν°νμ΄μ€ δΈ (1) | 2024.10.06 |
[π Effective Java] ν΄λμ€μ μΈν°νμ΄μ€ δΈ (1) | 2024.09.25 |
[π Effective Java] λͺ¨λ κ°μ²΄μ κ³΅ν΅ λ©μλ δΈ (0) | 2024.09.22 |
[Effective Java] λͺ¨λ κ°μ²΄μ κ³΅ν΅ λ©μλ δΈ (0) | 2024.09.21 |