avatarPeterson C

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3348

Abstract

rd">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">loadStaffNames</span>()</span>{ <span class="hljs-keyword">this</span>.staffNames.<span class="hljs-keyword">add</span>(<span class="hljs-string">"Michael Bublé"</span>); <span class="hljs-keyword">this</span>.staffNames.<span class="hljs-keyword">add</span>(<span class="hljs-string">"Frank Sinatra"</span>); <span class="hljs-keyword">this</span>.staffNames.<span class="hljs-keyword">add</span>(<span class="hljs-string">"Mile Davis"</span>); <span class="hljs-keyword">this</span>.staffNames.<span class="hljs-keyword">add</span>(<span class="hljs-string">"Louis Armstrong"</span>); <span class="hljs-keyword">this</span>.staffNames.<span class="hljs-keyword">add</span>(<span class="hljs-string">"Nat King Cole"</span>); }</pre></div><div id="32e2"><pre> <span class="hljs-keyword">public</span> <span class="hljs-title class_">List</span><<span class="hljs-title class_">String</span>> <span class="hljs-title function_">getStaffNames</span>(<span class="hljs-params"></span>){ <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">staffNames</span>; }

<span class="hljs-keyword">public</span> <span class="hljs-title class_">String</span> <span class="hljs-title function_">findStaffByName</span>(<span class="hljs-params"><span class="hljs-built_in">String</span> name</span>){
    <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">staffNames</span>
            .<span class="hljs-title function_">stream</span>()
            .<span class="hljs-title function_">filter</span>(x -&gt; x.<span class="hljs-title function_">equalsIgnoreCase</span>(name))
            .<span class="hljs-title function_">findFirst</span>()
            .<span class="hljs-title function_">orElse</span>(<span class="hljs-literal">null</span>);
}</pre></div><div id="7127"><pre>    <span class="hljs-meta">@Override</span>
<span class="hljs-keyword">public</span> Object <span class="hljs-title function_">clone</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> CloneNotSupportedException{
    <span class="hljs-type">Staff</span> <span class="hljs-variable">copiedStaff</span> <span class="hljs-operator">=</span> (Staff)<span class="hljs-built_in">super</span>.clone();
    <span class="hljs-built_in">this</span>.staffNames.stream().forEach(
            x -&gt; copiedStaff.staffNames.add(x));
    <span class="hljs-keyword">return</span> copiedStaff;
}

}</pre></div><p id="57e9">In this our Staff class, the costly operation is performed in the <b><i>loadStaffNames</i> </b>method, which is a private method that gets called each time an object is created using the <b><i>new </i></b>keyword. So if you need to create an object with the same data, there is no need to reload the data again. This pattern provides a way to create instances by cloning an existing object.</p><p id="c96c">In the <b><i>findStaffByName</i> </b>method, we also used the same loaded data to perform the search. If your application requires a way to reload the data from the database or whatever data source bei

Options

ng used, then your class can provide a method to do that.</p><p id="ab5a">You still need to create at least one object using the new keyword. Cloning something implies there’s an original or existing object. Once you have an existing object, then you can clone it whenever you want another instance of a class instead of creating a new one from scratch. You want to do that because creating a new one would make another call to the database in our case — or whatever costly operation you’re trying to limit.</p><p id="f066">You can then use your Staff class and clone is like this.</p><div id="1fb6"><pre><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-built_in">void</span> <span class="hljs-title function_">main</span>(<span class="hljs-params"><span class="hljs-built_in">String</span>[] args</span>) {</pre></div><div id="d83d"><pre> <span class="hljs-keyword">try</span> { Staff staff = <span class="hljs-keyword">new</span> Staff(); System.out.<span class="hljs-keyword">println</span>(<span class="hljs-string">"number of staff in: "</span> + staff.getStaffNames().<span class="hljs-keyword">size</span>());</pre></div><div id="b0ae"><pre> Staff copiedStaff <span class="hljs-operator">=</span> (Staff)staff.clone()<span class="hljs-comment">;</span></pre></div><div id="5e61"><pre> System.out.<span class="hljs-keyword">println</span>(<span class="hljs-string">"number of staff: "</span> + copiedStaff.getStaffNames().<span class="hljs-keyword">size</span>());</pre></div><div id="2c0e"><pre> <span class="hljs-keyword">System</span>.<span class="hljs-keyword">out</span>.println(staff.hashCode()); <span class="hljs-keyword">System</span>.<span class="hljs-keyword">out</span>.println(copiedStaff.hashCode());</pre></div><div id="cfe3"><pre> } catch (CloneNotSupportedException e) { e<span class="hljs-selector-class">.printStackTrace</span>(); } }</pre></div><div id="c7aa"><pre><span class="hljs-comment">//</span><span class="hljs-literal">---------------</span><span class="hljs-comment">output</span><span class="hljs-literal">----------------</span></pre></div><div id="1f4d"><pre><span class="hljs-attribute">number</span> of staff: <span class="hljs-number">5</span> <span class="hljs-attribute">number</span> of staff: <span class="hljs-number">5</span> <span class="hljs-attribute">2114889273</span> <span class="hljs-attribute">1025799482</span></pre></div><p id="aecb">There are always pros and cons to every solution. Always remember there isn’t just one solution to solve every problem. So use your best judgment when considering this pattern.</p><p id="eddb">Thank you for making it to the end. <b><i>Happy coding</i></b>.</p><blockquote id="6901"><p><b><i>Previous</i></b><i>: <a href="https://readmedium.com/creational-design-pattern-abstract-factory-5e3f9b53cbf4"></a></i><a href="https://readmedium.com/creational-design-pattern-abstract-factory-5e3f9b53cbf4">Creational Design Pattern: Abstract Factory</a></p></blockquote><blockquote id="ae9b"><p><b><i>Next:</i></b> <a href="https://readmedium.com/behavioral-design-pattern-chain-of-responsibility-782862e333d9"><i>Behavioral Design Pattern: Chain of Responsibility</i></a></p></blockquote></article></body>

A GUIDE TO SOFTWARE DESIGN PATTERNS

Creational Design Pattern: Prototype

Photo by Alex wong on Unsplash

The prototype pattern is one of the five creational patterns that is used when the creation of new objects is done by cloning an existing instance.

In plain English, this simply means you don’t use the new keyword to create a new instance, rather a deep-cloning of an existing object is performed. This pattern is used for a few reasons, but the most important one is to avoid the expensive cost of creating new objects the standard way in some applications — e.g., using the ‘new’ keyword.

Some applications load data from a data source and it can be anything from a database, a file, etc… If your application needs to load data, then loading that same information each time you create a new object can be time-consuming and or memory intensive depending on the size. This is where the prototype pattern comes in handy.

For instance, you’re tasked to design and implement a package that creates Staff. Staff includes professors, assistants, custodians, interns, etc… Your staff object needs to be able to return all staff members’ names and perform a lookup by name. We’re going to assume that all names in our data source are unique. Now imagine having to make a call to load the staff members’ data every time you create a new object. That can be quite an expensive operation. We can use the prototype pattern to solve this problem.

For an object to be cloneable, it needs to implement the Cloneable interface. We need to override the clone method to perform a deep-copy of the object being cloned. If you’re not familiar with the cloning concept, I suggest you check out The Difference Between Shallow And Deep Copy.

We won’t be reading data from a data source in the sample, rather we’ll hardcode some values for brevity’s sake. The code for the Staff class would look like this.

public class Staff implements Cloneable {
    private List<String> staffNames;
public Staff(){
        this.staffNames = new ArrayList<>();
        loadStaffNames();
    }
//simulates a database call to get all staff names
    private void loadStaffNames(){
        this.staffNames.add("Michael Bublé");
        this.staffNames.add("Frank Sinatra");
        this.staffNames.add("Mile Davis");
        this.staffNames.add("Louis Armstrong");
        this.staffNames.add("Nat King Cole");
    }
    public List<String> getStaffNames(){
        return this.staffNames;
    }
    
    public String findStaffByName(String name){
        return this.staffNames
                .stream()
                .filter(x -> x.equalsIgnoreCase(name))
                .findFirst()
                .orElse(null);
    }
    @Override
    public Object clone() throws CloneNotSupportedException{
        Staff copiedStaff = (Staff)super.clone();
        this.staffNames.stream().forEach(
                x -> copiedStaff.staffNames.add(x));
        return copiedStaff;
    }
}

In this our Staff class, the costly operation is performed in the loadStaffNames method, which is a private method that gets called each time an object is created using the new keyword. So if you need to create an object with the same data, there is no need to reload the data again. This pattern provides a way to create instances by cloning an existing object.

In the findStaffByName method, we also used the same loaded data to perform the search. If your application requires a way to reload the data from the database or whatever data source being used, then your class can provide a method to do that.

You still need to create at least one object using the new keyword. Cloning something implies there’s an original or existing object. Once you have an existing object, then you can clone it whenever you want another instance of a class instead of creating a new one from scratch. You want to do that because creating a new one would make another call to the database in our case — or whatever costly operation you’re trying to limit.

You can then use your Staff class and clone is like this.

public static void main(String[] args)  {
    try {
        Staff staff = new Staff();
        System.out.println("number of staff in: "
                    + staff.getStaffNames().size());
        Staff copiedStaff = (Staff)staff.clone();
        System.out.println("number of staff: "
                    + copiedStaff.getStaffNames().size());
        System.out.println(staff.hashCode());
            System.out.println(copiedStaff.hashCode());
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
}
//---------------output----------------
number of staff: 5
number of staff: 5
2114889273
1025799482

There are always pros and cons to every solution. Always remember there isn’t just one solution to solve every problem. So use your best judgment when considering this pattern.

Thank you for making it to the end. Happy coding.

Previous: Creational Design Pattern: Abstract Factory

Next: Behavioral Design Pattern: Chain of Responsibility

Programming
Software Engineering
Software Architecture
Software Development
Developer
Recommended from ReadMedium