CSC321.01 2016S, Class 20: Good Design, Revisited
=================================================

_Overview_

* Preliminaries.
    * Admin.
    * Upcoming Work.
    * Extra Credit.
    * Questions.
* Design Patterns.
* The GoF List.
* Some Questions.
* SOLID.

Preliminaries
-------------

### Admin


### Questions

Writing prompt
--------------

Write a short essay reflecting on the ethics of engineering software as
a service, due the last day of class.

* Intent: Broad choice of topics.  
* Preferred electronic.  PDF, Word .doc, Word .rtf, Word .docx,
  Libre Office odt, plain text, LaTeX source (plus PDF), 

Parameters

* Address your question from the perspective of a software engineer or entrepreneur (not a user).
* Write approximately 400-800 words. Your essay should be tight: Don't waste words!
* Cite at least two of the assigned readings (from the two sets of readings) and at least three additional sources.
    * Your additional sources could be our textbook or a reading from another, relevant class.
    * Your additional sources could be a research article, magazine article, news article, or even a substantial blog post. The ACM magazines are all good sources, depending on your topic of interest.
* Use APA or ACM style for your citations.
* Use a 10-12 point font and double spacing (about 2-3 pages). Do not use a separate cover page.
* Submit the final version of your essay via email to me by 11:00 p.m. on March 11.
* You will have the opportunity to revise your essay once during the second
  half of the semester.
* I will retain a copy of the final version of your essay for the departmental 
  discussions on writing in the CS curriculum and ethics in the CS curriculum.
* You may rely upon your regular journals, provided you cite yourself.
* You can post it to a 'blog or elsewhere if you would like.

Design Patterns
---------------

* Growth of OOP as a mechanism for looking at large software systems.
* Programmers struggle to apply/understand some principles of OOD
* Christopher Alexander's "A Pattern Language"
    * A typical problem in architectural design; known solutions
* A group of leading OOdesigners put together "Design Patterns"
    * A problem (or class of problems)
    * A typical solution in an object-oriented framework
* Multiple benefits
    * A mechanism for saying "I designed this well" (don't sue!)
    * Separate known problems from new problems
        * Inform novices of known problems
    * Avoid reinventing the wheel, and reinventing it badly
    * For experts: More efficient way to discuss solutions.
* Multiple approaches to patterns
    * Proscriptive - When you see this pattern, you must use this solution
    * Enlighightening - Ways to help you think, but not necessary in all
      cases.
* Increasingly, you will find that the original GoF patterns
    * A part of every functional language
    * Part of current language design

Sam's Favorite Patterns
-----------------------

Factory - You have a program (or method or ...) that will need to build 
lots of widgets - pass in a function/object that does the actual building.

    public class HardGame
    {
      WidgetMaker widgetMaker;
      public void run()
      {
        int difficulty = 1;
        every second
          {
            Widget w = widgetmaker.spawn(difficulty);
            screen.place(w, 0, 0);
            difficulty += random(2);
          }
      }
    } // class HardGame

    public interface WidgetMaker
    {
      Widget spawn(int difficulty);
    } // 

    public class HorribleAlien implements Widget
    {
      public HorribleAlien(int type, int size, int firepower)
      {
        ...
      }
    }
    public class HorribleAlienMaker implements WidgetMaker
    {
      public Widget spawn(int difficulty)
      {
        return new HorribleAlien(random(3), difficulty*2, difficulty);
    }

    public class FluffySheepMaker implemets WidgetMaker
    {
      ..
    } 

Factories are really useful when you are doing GUIs.

### Adapter/Proxy/....

Problem: You have to write an class/object that meets a particular
interface.  E.g.,

        // Things you can add to other things of the same type
        public interface Addable<T subtype Addable<T>>
        {
          public T add(T other);
        }

And you have objects that were designed separately from the interface,
but should be easily adapted to meet the interface

        public class BigInteger
        {
          public BigInteger add(BigInteger other);
        }

        public class AddableBigInteger implements Addable
        {
          BigInteger contents;
          public AddableBigInteger add(AddableBigInteger other)
          {
            return this.contents.add(other.contents);
          }
        }

        public class AddableBigInteger
          extends BigInteger
          implements Addable
        {
          ...
        }

Singletons, Nulls, etc.

* I think you mostly understood.

Decorators: Add functionality to all the classes that implement a
particular interface.

    public interface Comparator<T implements Comparator<T>>
    {
      public int compare(T left, T right);
    }

    public class CountingComparator<...>
      implements Comparator<...>
    {
      int count;

      Compartor comp;
      public CountingComparator(Comparator comp)
      {
        this.comp = comp;
      }

     public int getCount()
     {
       return this.count;
     }

     public int resetCount()
     {
       this.count = 0;
     }

     public int compare(T left, T right)
     {
       ++count;
       return this.comp.compare(left, right);
     } 
    } // 

Old code

        sort(A, new StringComparator());

Now

        sort(A, new CountingComparator(new StringComparator()));

Some Questions
--------------

### Patterns

_The difference between Strategy Pattern and Template Method Pattern was a bit vague. From what I got after all, both deal with general approach towards a given task but with different variants. The Strategy Pattern would analyse the given variant of the task and use different steps to achieve it. On the other hand, the Method Pattern follows the same steps every time, but for different variants the implementation of those steps could differ._

> We'll think about this one in terms of sorting.

> We know lots of sorting methods: Bubble sort, Radix sort, Quicksort,
  Insertion sort, Merge sort

        public interface Sorter
        {
          public void sort(...);
        }

        public class Quicksorter implements Sorter
        {
        }

        public class MergeSorter implements Sorters
        {
        }

> Most of your code will just work with Sorters.  You can substitute in
  one sorter for another.

> That's the strategy pattern.

In implementing any of these sorting routines, we'll probably call the
compare method.  If we do it right, the compare method is an instance of
the template method pattern.

_I found the Adapter, Proxy, Facade, Bridge design pattern to be quite confusing. It states: "Convert the programming interface of a class into another interface that clients expect, or decouple an abstraction’s interface from its implementation, for dependency injection or performance." It seems as though this principle is trying to make the program/class more user intuitive, but I really have no idea what “decoupling an abstraction’s interface from its implementation” looks like. _

> To me, these patterns are usd most frequently when you have a class that
  has one interface, and you essentially want to use it to meet another
  interface.

_To me, the ‘decorator’ pattern was the most confusing. Mostly, I don’t understand why attaching responsibilities dynamically is better design-wise than having them statically linked— wouldn’t that make debugging/understanding harder?_

_The decorator pattern. From the wikipedia page, the pattern appears to involve wrapping the class in another class which provides the same interface and just calls directly to original class's functions. Why is this helpful?_

> There are multiple uses of decorator.  We'll look at some examples.

_Observer: One or more entities need to be notified when something happens to an object. Eg: when the value of a slider changes, change the transparency of an image accordingly._

> Many programs have parts that need to know when state changes.  We can
  consider an email reader.

        public interface Observable
        {
          public void addObserver(Observer o);
        }

_I found creational patterns most confusing. From what I understand, they seem to provide a means to create object without using the usual method of instantiating using an operator. Therefore, they hide the creation logic somehow. I'm not quite sure how it is possible to hide the creation logic when creating an object._

_Why would the Prototype design pattern be useful? Why would it be better to create copies of something instead of creating entirely fresh instances?_

> We might build info as we go.  Think about drawings as values.

### SOLID

_The most confusing design principle was the SOLID acronym. It seemed like a more confusing SOFA. Single responsibility was familiar, but a few of these, such as the Liskov substitution principle, seem harder to inspect the code for obvious signals that this might be a problem. I think of code smells as something I can quickly identify as a problem just by looking at the code, not necessary tracing it thoroughly. So something like a segment of code never being executed wouldn't really be a code smell, because you would probably have to trace through the code to make sure that there was no way for a line to be executed. The dependency principle also seemed like something that would have to thought of ahead of time, not noticed as a bad practice after having written the code and looking it over. So SOLID principles seemed harder to detect, or requiring more thought to take care of._

### Dependency Injection

_I'm most confused about the injection principle, because I'm not sure what they mean by inject. What I take this principle to mean is that if two classes are similar, and depend on each other, then you should write a common interface for the two of them to inherit methods from. Why this is, I'm not completely clear. Is this the same type of interface that we talk about when learning Java?_

_Injection of Dependencies was a bit unclear to me. Most other pieces seemed to be referencing code practices which are relevant at the compilation step, but this one seemed focused on the runtime. If I understand correctly, this is targeted at projects that have multiple implementations of a single class that may be used in different scenarios (e.g. testing vs production). This principle asserted that the different implementations should share dependencies, so I assumed that meant using one binary file for all the dependencies for both implementations since the dependencies shouldn’t be different between them._

_The Dependency Inversion Principle confuses me. I think it's trying to tell me that I shouldn't have non-abstract arguments and return values. Shouldn't all of my functions work on the same abstraction level? I don't see the relevancy that the author attributes to this concept._

### Demeter

I got confused about the formal language that was explaining the
concept. It was a bit too abstract at first glance.  Essentially, the
Demeter Principle says that classes should only interact with methods
that they own. In other words, we don't want to access another class's
methods and modify instance variables that belong to an instance of
another class. This can create unpredictable problems and we may not
clearly know how our classes are interacting.

GoF Patterns
------------

### Creational

* Abstact Factory
* Factory Method
* Singleton
* Prototype
* Builder

### Structural

* Adapter
* Proxy
* Facade
* Bridge
* Decorator
* Composite
* Flyweight

### Behavioral

* Template Method
* Strategy
* Observer
* Iterator
* Visitor
* State
* Chain of Responsibility
* Mediator
* Interpreter
* Command

SOLID Principles
----------------

Intended as a mechanism for thinking about class design.  Five basic
principles.

* Single Responsibility - Do one thing well.
* Open/Closed - Open for extension, closed against modification.
* Liskov Substitution Principle - T's subclasses follow the interface
* Interface Segregation
* Dependency Inversion 
