Смяна на ключове, загуба на стойности
TL;DR: Когато използвате променливи обекти като ключове в хеширани колекции, промяната им прекъсва договорите.
Когато използвате променливи обекти като ключове в хеширани колекции , промяната на техния ключ след добавяне на свързан обект може да го направи невъзстановим.
Това се случва, защото хеш кодът се променя и колекцията не може да намери обекта в правилната кофа.
class MutableKey { int id; MutableKey(int newId) { this.id = newId; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object objectToCompare) { if (this == objectToCompare) return true; MutableKey that = (MutableKey) objectToCompare; return id == that.id; } } MutableKey key = new MutableKey(42); Map<MutableKey, String> map = new HashMap<>(); map.put(key, "Yes Album"); // The key mutates key.id = 90125; // Now you cannont retrieve the album System.out.println(map.get(key)); // Output: null
class ImmutableKey { private final int id; ImmutableKey(int newId) { this.id = newId; } @Override public int hashCode() { return this.id; } @Override public boolean equals(Object objectToCompare) { if (this == objectToCompare) return true; ImmutableKey that = (ImmutableKey) objectToCompare; return id == that.id; } } ImmutableKey key = new ImmutableKey(42); Map<ImmutableKey, String> map = new HashMap<>(); map.put(key, "Yes Album"); System.out.println(map.get(key)); // Output: Yes Album
Можете да откриете тази миризма, като проверите дали използвате променливи обекти като ключове в колекции, базирани на хеш.
Автоматизирани инструменти като линтери или инспекции на IDE също могат да маркират променливи ключове.
Биекцията между реалния свят и вашата програма е важна, защото гарантира, че вашите обекти точно отразяват връзките, които трябва да представляват.
В реалния свят ключовете често са неизменни (напр. идентификатори, имена).
Когато моделирате тези ключове като променливи обекти, нарушавате съответствието едно към едно между реалния свят и вашата програма в MAPPER .
Когато прекъснете тази биекция с помощта на променливи ключове, вие правите картата непоследователна, което води до грешки при извличане и неочаквано поведение.
Генераторите на AI може да създадат тази миризма, ако генерират променливи обекти като ключове, без да обмислят последиците.
Това рядко се случва, тъй като AI генераторите страдат от примитивна мания .
Генераторите на AI могат да открият тази миризма с инструкции за анализиране на използването на променливи обекти в колекции, базирани на хеш, и да маркират потенциални проблеми.
Можете да инструктирате AI да търси класове без крайни полета или методи, които променят състоянието на обекта след създаването.
Запомнете: AI Assistants правят много грешки
Без подходящи инструкции | С конкретни инструкции |
---|---|
Когато използвате променливи обекти като ключове, рискувате да нарушите договора между състоянието на ключа и хеш кода.
Използвайте неизменни обекти, за да избегнете този проблем.
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxiv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxiv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxvi
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xviii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxvi
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xlii
Code Smells са мое мнение .
Снимка от Катирин Трип в Unsplash
Най-важното свойство на програмата е дали тя изпълнява намерението на своя потребител.
КАР Хоаре
Тази статия е част от поредицата CodeSmell.