I want to know when we need to use the abstract factory pattern.
Here is an example,I want to know if it is necessary.
The UML
THe above is the abstract factory pattern, it is recommended by my classmate. THe following is myown implemention. I do not think it is necessary to use the pattern.
And the following is some core codes:
package net;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class Test {
public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
DaoRepository dr=new DaoRepository();
AbstractDao dao=dr.findDao("sql");
dao.insert();
}
}
class DaoRepository {
Map<String, AbstractDao> daoMap=new HashMap<String, AbstractDao>();
public DaoRepository () throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
Properties p=new Properties();
p.load(DaoRepository.class.getResourceAsStream("Test.properties"));
initDaos(p);
}
public void initDaos(Properties p) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
String[] daoarray=p.getProperty("dao").split(",");
for(String dao:daoarray) {
AbstractDao ad=(AbstractDao)Class.forName(dao).newInstance();
daoMap.put(ad.getID(),ad);
}
}
public AbstractDao findDao(String id) {return daoMap.get(id);}
}
abstract class AbstractDao {
public abstract String getID();
public abstract void insert();
public abstract void update();
}
class SqlDao extends AbstractDao {
public SqlDao() {}
public String getID() {return "sql";}
public void insert() {System.out.println("sql insert");}
public void update() {System.out.println("sql update");}
}
class AccessDao extends AbstractDao {
public AccessDao() {}
public String getID() {return "access";}
public void insert() {System.out.println("access insert");}
public void update() {System.out.println("access update");}
}
And the content of the Test.properties is just one line:
dao=net.SqlDao,net.SqlDao
So any ont can tell me if this suitation is necessary?
-------------------The following is added to explain the real suitation--------------
I use the example of Dao is beacuse it is common,anyone know it.
In fact,what I am working now is not related to the DAO,I am working to build a Web
service,the web serivce contains some algorithms to chang a file to other format,
For example:net.CreatePDF,net.CreateWord and etc,it expose two interfaces to client:getAlgorithms and doProcess.
The getAlogrithoms will return all the algorithms's ids,each id is realted to the corresponding algorithm.
User who call the doProcess method will also provide the algorithm id he wanted.
All the algorithm extends the AbstractAlgorithm which define a run() method.
I use a AlogrithmsRepository to store all the algorithms(from
the properties file which config the concrete java classes of the algorithms by the web
service admin).That's to say, the interface DoProcess exposed by the web service is
executed by the concrete alogrithm.
I can give a simple example: 1)user send getAlgorithms request:
http://host:port/ws?request=getAlgorithms
Then user will get a list of algorithms embeded in a xml.
<AlgorithmsList>
<algorithm>pdf</algorithm>
<algorithm>word<algorithm>
</AlgorithmsList>
2)user send a DoProcess to server by:
http://xxx/ws?request=doProcess&alogrithm=pdf&file=http://xx/Test.word
when the server recieve this type of requst,it will get the concrete algorithm instance according to the "algorithm" parameter(it is pdf in this request) from the AlgorithmRepostory. And call the method:
AbstractAlgorithm algo=AlgorithmRepostory.getAlgo("pdf");
algo.start();
Then a pdf file will be sent to user.
BTW,in this example, the each algorithm is similar to the sqlDao,AccessDao. Here is the image:
The design image
Now,does the AlgorithmRepostory need to use the Abstract Factory?
The main difference between the two approaches is that the top one uses different DAO factories to create DAO's while the bottom one stores a set of DAO's and returns references to the DAO's in the repository.
The bottom approach has a problem if multiple threads need access to the same type of DAO concurently as JDBC connections are not synchronised.
This can be fixed by having the DAO implement a newInstance()
method which simply creates and returns a new DAO.
abstract class AbstractDao {
public abstract String getID();
public abstract void insert();
public abstract void update();
public abstract AbstractDao newInstance();
}
class SqlDao extends AbstractDao {
public SqlDao() {}
public String getID() {return "sql";}
public void insert() {System.out.println("sql insert");}
public void update() {System.out.println("sql update");}
public AbstractDao newInstance() { return new SqlDao();}
}
The repository can use the DAO's in the repository as factories for the DAO's returned by the Repository (which I would rename to Factory in that case) like this:
public AbstractDao newDao(String id) {
return daoMap.containsKey(id) ? daoMap.get(id).newInstance() : null;
}
Update
As for your question should your web-service implement a factory or can it use the repository like you described? Again the answer depends on the details:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With