130 likes | 319 Views
Computer Science 313 – Advanced Programming Topics. Lecture 28: Principle of Least Knowledge. Public Fields are Evil. Always make fields private (or protected) Cannot control field ’s uses Can be used by any class Modified anywhere in program Cannot track any of this
E N D
Computer Science 313 – Advanced Programming Topics Lecture 28:Principle of Least Knowledge
Public Fields are Evil • Always make fields private(or protected) • Cannot control field’s uses • Can be used by any class • Modified anywhere in program • Cannot track any of this • Makes future changes difficult • Cannot remove or replace field • Code may rely on its exact type • Code base stuck & so is limited
Getters Are Also Evil • After calling getter: • Cannot control field’s uses • Can be used by any class • Modified anywhere in program • Cannot track any of this • Makes future changes difficult • Cannot remove or replace field • Code may rely on its exact type • Code base stuck & so is limited
Coupling • “Measure” of how independent classes are • Classes using own fields & methods are independent • Changes to independent classes are simple • Any change to dependent class causes ripples • Consider all classes dependent on one being changed • May affect classes dependent on those classes • Completely independent classes unrealistic • One class for entire program required to do this • Instead focus on how to minimize coupling
Principle of Least Knowledge • More commonly called Law of Demeter • (Stupid meaningless name that need not exist) • Only call methods belonging to: • Current object (e.g., this) • Current object’s fields • Object allocated within the method • One of the parameters to the method • May not limit dependent classes • But certainly makes tracking them down easier
Violating the Principle • Fixing something, but what is problem? • Using getters, fields can travel everywhere • Dependent classes hard to find & count • Most common Java violation of this rule:System.err.print(“Bar);System.out.println(“Foo”); • Would this code really be any better?System.getErr().print(“Bar”);System.getOut().println(“Foo”);
Getters are not the Solution • Getter could make finding uses harder! public void printOutEntireDictionary(Dict d) {PrintWritere = System.getOut();PrintWritero = System.getErr();PrintWriters = new PrintWriter(new File…));for (Entry<String,String> ent : d) {s.println(ent.getKey()+ent.getValue());e.println(ent.getKey()+“\t”+ent.getValue());o.println(ent.getKey()+“”+ent.getValue());translateToGerman(ent, s);translateToSpanish(ent, o);translateToSpanish(ent, e);
What Can Be Done? public void buildPool(Store s) { Fish attack = null; try { attack = s.getSharks();attack.addLasers(); } catch (Exception e) { attack = s.getSeaBass();attack.mutate();attack.makeIllTempered(); }pool.populate(attack);}
What Can Be Done? public void buildPool(Store s) { Fish attack = null; try { attack = s.getSharks();attack.addLasers(); } catch (Exception e) { attack = s.getSeaBass();attack.mutate();attack.makeIllTempered(); }pool.populate(attack);}
Ugly Solution public void armFish(Fish f) {f.addLasers();}public void buildPool(Store s) { Fish attack = null; try { attack = s.getSharks();armFish(attack); } catch (Exception e) { attack = s.getSeaBass(); : :
Prettier Façade Solution public void buildPool(EvilStore s) { Fish attack = null; try { attack = s.getSharksWithLasers(); } catch (Exception e) { attack = s.getITMutatedSeaBass(); }pool.populate(attack);}
For Next Class • Keep working on Lab #5 due in 1 hour • Read pages 275-286 for Monday • Discusses another very useful design pattern • Could make classes easier, if you had known • Overlaps with other patterns, which are similar?