public FactoryPatternTest{publicstaticvoidmain(String[] args){ShapeFactory shapeFactory =newShapeFactory();Shape shape1 =shapeFactory.getShape("STAR");shape1.draw();Shape shape2 =shapeFactory.getShape("SQUARE");shape2.draw(); }}
즉, 서브 클래스에서 오브젝트 생성 방법 클래스를 결정할 수 있도록 미리 정의해둔 메소드를 팩토리 메소드라고 하며, 이 방식을 통해 오브젝트를 생성하는 방법을 팩토리 메소드 패턴이라고 한다.
Factory Method Pattern을 왜 사용할까?
팩토리 메소드 패턴을 사용하는 이유는 클래스간의 결합도를 낮추기 위한것입니다. 결합도라는 것은 간단히 말해 클래스의 변경점이 생겼을 때 얼마나 다른 클래스에도 영향을 주는가입니다. 팩토리 메소드 패턴을 사용하는 경우 직접 객체를 생성해 사용하는 것을 방지하고 서브 클래스에 위임함으로써 보다 효율적인 코드 제어를 할 수 있고 의존성을 제거합니다. 결과적으로 결합도 또한 낮출 수 있습니다.
예제
Sub Class의 getConnection()을 통해 만들어진 Connection 종류가 달라질 수 있게 하는 것을 목적으로 하는 팩토리 메소드 패턴의 예시이다.
packagespringbook.user.dao;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importspringbook.user.domain.User;publicabstractclassUserDao {publicvoidadd(User user) throwsClassNotFoundException,SQLException {Connection c =getConnection();PreparedStatement ps =c.prepareStatement("insert into users(id, name, password) values(?,?,?)");ps.setString(1,user.getId());ps.setString(2,user.getName());ps.setString(3,user.getPassword());ps.executeUpdate();ps.close();c.close(); }publicUserget(String id) throwsClassNotFoundException,SQLException {Connection c =getConnection();PreparedStatement ps = c.prepareStatement("select * from users where id = ?");ps.setString(1, id);ResultSet rs =ps.executeQuery();rs.next();User user =newUser();user.setId(rs.getString("id"));user.setName(rs.getString("name"));user.setPassword(rs.getString("password"));rs.close();ps.close();c.close();return user; }abstractprotectedConnectiongetConnection() throwsClassNotFoundException,SQLException ;}
packagespringbook.user.dao;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.SQLException;publicclassDUserDaoextendsUserDao {protectedConnectiongetConnection() throwsClassNotFoundException,SQLException {Class.forName("com.mysql.jdbc.Driver");Connection c =DriverManager.getConnection("jdbc:mysql://localhost/springbook?characterEncoding=UTF-8","DuserId","DUserPassword");return c; }}
packagespringbook.user.dao;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.SQLException;publicclassNUserDaoextendsUserDao {protectedConnectiongetConnection() throwsClassNotFoundException,SQLException {Class.forName("com.mysql.jdbc.Driver");Connection c =DriverManager.getConnection("jdbc:mysql://localhost/springbook?characterEncoding=UTF-8","NUserId","NUserPassword");return c; }}
publicstaticvoidmain(String[] args) throws ClassNotFoundException, SQLException {UserDao dao =newNUserDao();User user =newUser();user.setId("admin");user.setName("test1");user.setPassword("admintest");dao.add(user);System.out.println(user.getId() +" 등록 완료");User user2 =dao.get(user.getId());System.out.println(user2.getName());System.out.println(user2.getPassword());System.out.println(user2.getId() +" 호출 완료"); }
NUserDao와 DUserDao가 Connection을 생성하는 방법이 다르므로, 팩토리 메소드 패턴으로 볼 수 있다.