CSC/ECE 517 Fall 2010/ch7 7g ms: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 5: Line 5:
In software engineering, an anti-pattern (or antipattern) is a pattern that may be commonly used but is ineffective and/or counterproductive in practice.
In software engineering, an anti-pattern (or antipattern) is a pattern that may be commonly used but is ineffective and/or counterproductive in practice.


In analysis paralysis, we over analyze (or over think) a situation until no decision is ever made, which effectively paralyzes the current process' outcome.
Analysis Paralysis is one of the classic anti-patterns in object oriented software development. In analysis paralysis, we over analyze (or over think) a situation until no decision is ever made, which effectively paralyzes the current process' outcome.


===Class Diagram===
[[Image:IC73826.gif|500px|center]]


This diagram is a Universal Modeling Languages (UML) diagram of how a Singleton class would look if implemented in Java.
This diagram is a Universal Modeling Languages (UML) diagram of how a Singleton class would look if implemented in Java.
===Sequence Diagram===
[[Image:CR2.gif|500px|center]]
This diagram illustrates how the Singleton class creates an instance of the Singleton object.  The client classes then create instances of the Singleton class which handles access to the Singleton object.


=Implementation=
=History=
When this pattern is implemented then it must only have one instantiation of a class and that class must satisfy the global access principles.  The pattern requires a mechanism to access the singleton class without instantiating another class object and a mechanism to persist the value of class members among class objects.  [[#References|[1]]]


==Creating the instance==
=How to Defeat Analysis Paralysis=
===Early Instantiation===
    * Keep models small. Never integrate them. Building a bigger model doesn't add knowledge - it destroys knowledge.
The instance can be created with a static constructor in static languages. (See the java example below)  This means that the single instance is created on program start up and all new methods are private and never used except by the singleton class itself.
    * You don't have to go the whole XP hog, but make testing drive analysis. How's that? Here's a requirement; build a test harness for it. Oh, you can't? Well, why not? Do enough analysis to know how to build the harness - and then stop!
    * Don't employ "analysts". Employ developers. If a developer doesn't know how to analyze a requirement, they'll soon learn; if an analyst doesn't know how to develop a solution, their "analysis" is worthless.
    * If you are management, refuse to review technical documents. Review working functionality. If you're not seeing new functionality every cycle, kick butt until you do.
    * Employ a professional architect. Just one architect is what you want - never more than that. The architect doesn't have to be team leader - in fact it's probably better if he's not. He's not responsible for analyzing the project's requirements either. He's responsible for providing generic tools to coordinate and support the other developers. Let no one else call the shots on infrastructure, and for f*ck's sake don't go ballsing the thing up by trying to mess with it yourself. Nor let anyone suggest that architecture be decided by voting or meeting - a sure recipe for AnalysisParalysis.
    * Start your project with one requirement and an architectural prototype. Don't give 'em more than a month to code it. Yeah, it'll be lame - but it's there, and it's code, and it works. Now let 'em refine and replace and refactor - that's real work. A project without a prototype is like a candle without a wick, which is how AnalysisParalysis really happens.  


In static languages, this is accomplished by setting the constructors to private and controlling creation of instance of the object from within the object itself.
=Causes=
*Pride
*Narrow Mindedness


In dynamic languages, this is done by changing the access level of the constructor to prevent use outside the class just as in the static patterns.
===Late Instantiation===
The instance of the class can be created after class loading. (See the C++ example)  This can be done by only allocating the instance on the first access of the instance variable.
==Accessing the instance==
In static languages, such as Java, the Singleton class will have a method which returns the instance of the Singleton class so that the other classes can use the functionality encapsulated in the Singleton class.
In dynamic languages, such as Ruby, if a class needs to access the functionality within the Singleton class then it simply needs to access the instance variable @instance and all the functionality therein.
=Examples=
==Java==
Java's API includes a Singleton class which implements the static version of the Singleton pattern.  Java's implementation of the Singleton pattern only allows the programmer to create one instance of the Singleton class.  The Singleton class automatically creates INSTANCE when it is initialized.  The getInstance() method returns the single instance of the class that has been initialized.  Java also utilizes a constructor to initialize the Singleton class. 
<pre>
    private static final Singleton INSTANCE = new Singleton();
 
    // Private constructor prevents instantiation from other classes
    private Singleton() {
    }
    public static Singleton getInstance() {
        return INSTANCE;
    }
</pre>
[[#References|[1]]]
==Ruby==
Ruby implements the Singleton pattern by privatizing the "new" method and creates an instance variable called @instance.  This implementation guarantees that the class will not be able create more than one instantiation of itself and that the system will have the global access privileges since the @instance variable has a global scope. [[#References|[6]]]
<pre>
class genericFactory
  include Singleton
end
</pre>
[[#References|[1]]]
<pre>
class Logger
  def initialize
    @log = File.open("log.txt", "a")
  end
 
  @@instance = Logger.new
  def self.instance
    return @@instance
  end
 
  def log(msg)
    @log.puts(msg)
  end
 
  private_class_method :new
end
Logger.instance.log('message 1')
</pre>
[[#References|[6]]]
==C++==
<pre>
// Declaration
class Singleton {
public:
    static Singleton* Instance();
protected:
    Singleton();
private:
    static Singleton* _instance;
}
// Implementation
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance() {
    if (_instance == 0) {
        _instance = new Singleton;
    }
    return _instance;
}
</pre>
[[#References|[3]]]
=Benefits=
*This pattern allows the programmer to control the instances of a particular object, it ensures that all objects use the same instance of a class.[[#References|[3]]]
*The Singleton class has the ability to control the instantiation process since it implements the instantiation functionality.[[#References|[3]]]
=Drawbacks=
*Unit tests are much harder to write when using the Singleton pattern.[[#References|[3]]]
*This pattern reduces the potential for parallelism within a program since the threads must be serialized.[[#References|[3]]]
*The overhead of checking whether there is an instance of a class that already exists every time an objects requests a reference.  Although the overhead is minuscule, this could be a serious problem for systems which don't have the resources to waste.  [[#References|[3]]]
*There may be some development confusion with implementing the singleton class (especially one defined in a class library) because developers may forget that they cannot use the "new" keyword to instantiate the object.[[#References|[3]]]
*The singleton design pattern doesn't address the issue of deleting the single object.  Some languages implement memory management which means that the Singleton class can only be unallocated by itself since it holds a private reference to the instance of itself.  In languages that don't provide memory management, then the single instance can be deleted but it will cause a dangling reference to that object.[[#References|[3]]]


=References=
=References=
[[#References|[1]]] Wikipedia. (2010, October) Wikipedia - Singleton_Pattern. [Online]. http://en.wikipedia.org/wiki/Singleton_pattern#Traditional_simple_way
[[#References|[2]]] Freeman, Eric, Elisabeth Freeman, Kathy Sierra, and Bert Bates. (October 2004) Head First design patterns. [Print.]
[[#References|[3]]] C# Corner (2010, October) Creational Patterns - Singleton. [Online]. http://www.c-sharpcorner.com/UploadFile/susanabraham/CreationalPatterns06042005050058AM/CreationalPatterns.aspx
[[#References|[4]]] Source Making (2010, October) Singleton Design Pattern. [Online]. http://sourcemaking.com/design_patterns/singleton
[[#References|[5]]] JavaBeginner.com (2010, October) Java Singleton Design Pattern. [Online]. http://www.javabeginner.com/learn-java/java-singleton-design-pattern
[[#References|[6]]] Dalibor Nasevic (2010, October) Ruby Singleton Pattern Again. [Online]. http://dalibornasevic.com/posts/9-ruby-singleton-pattern-again

Revision as of 20:37, 1 December 2010

Analysis Paralysis Anti-Pattern

Analysis Paralysis Anti-pattern

In software engineering, an anti-pattern (or antipattern) is a pattern that may be commonly used but is ineffective and/or counterproductive in practice.

Analysis Paralysis is one of the classic anti-patterns in object oriented software development. In analysis paralysis, we over analyze (or over think) a situation until no decision is ever made, which effectively paralyzes the current process' outcome.


This diagram is a Universal Modeling Languages (UML) diagram of how a Singleton class would look if implemented in Java.

History

How to Defeat Analysis Paralysis

   * Keep models small. Never integrate them. Building a bigger model doesn't add knowledge - it destroys knowledge.
   * You don't have to go the whole XP hog, but make testing drive analysis. How's that? Here's a requirement; build a test harness for it. Oh, you can't? Well, why not? Do enough analysis to know how to build the harness - and then stop!
   * Don't employ "analysts". Employ developers. If a developer doesn't know how to analyze a requirement, they'll soon learn; if an analyst doesn't know how to develop a solution, their "analysis" is worthless.
   * If you are management, refuse to review technical documents. Review working functionality. If you're not seeing new functionality every cycle, kick butt until you do.
   * Employ a professional architect. Just one architect is what you want - never more than that. The architect doesn't have to be team leader - in fact it's probably better if he's not. He's not responsible for analyzing the project's requirements either. He's responsible for providing generic tools to coordinate and support the other developers. Let no one else call the shots on infrastructure, and for f*ck's sake don't go ballsing the thing up by trying to mess with it yourself. Nor let anyone suggest that architecture be decided by voting or meeting - a sure recipe for AnalysisParalysis.
   * Start your project with one requirement and an architectural prototype. Don't give 'em more than a month to code it. Yeah, it'll be lame - but it's there, and it's code, and it works. Now let 'em refine and replace and refactor - that's real work. A project without a prototype is like a candle without a wick, which is how AnalysisParalysis really happens. 

Causes

  • Pride
  • Narrow Mindedness


References