Abstract_Factory_Pattern

package abstract_factory_pattern;

public class User {
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

package abstract_factory_pattern;

public interface IUser {
    //If we use:protected void insert(User user);
    //Illegal modifier for the interface method insert;
    //only public, abstract, default, static and strictfp are permitted
    void insert(User user);
    User getUser(int id);
}

package abstract_factory_pattern;

public class AccessUser implements IUser{
    public void insert(User user) {
        System.out.println("Add a user in Access.");
    }
    public User getUser(int id) {
        System.out.println("Get a user through id in Access.");
        return null;
    }
}

package abstract_factory_pattern;

public class SqlServerUser implements IUser{
    //private->default(friendly)->protected->public
    /* The scope:
     * private:class itself.
     * default:every class in the packet.
     * protected:every class in the packet and its subclass in the other packet.
     * public:every class no matter where it is.
     * In real using,when subclass override its superclass's methods,we need to 
     * keep the subclass's scope  bigger than superclass's scope.Otherwise,the error
     * will be as follows:
     *      - Cannot reduce the visibility of the inherited method from IUser. 
     * Meanwhile,the subclass can not throw "new" exceptions that its superclass haven't.
     * Why?
     * The answer is:Liskov Substitution Principle(LSP)
     */
    public void insert(User user) {//The superclass's scope is default,we can't use others
        //except "public".why?
        System.out.println("Add a user in sqlServer.");
    }
    public User getUser(int id) {
        System.out.println("Get user through id in sqlServer.");
        return null;
    }
}

package abstract_factory_pattern;

public class Department {
    private int id;
    private String deptName;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getDeptName() {
        return deptName;
    }
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
}

package abstract_factory_pattern;

public interface IDepartment {
    void insert(Department department);
    Department getDepartment(int id);
}

package abstract_factory_pattern;

public class AccessDepartment implements IDepartment{
    public void insert(Department department) {
        System.out.println("Add a department in Access.");
    }
    public Department getDepartment(int id) {
        System.out.println("Delete a department through id in Access");
        return null;
    }
}

package abstract_factory_pattern;

public class SqlServerDepartment implements IDepartment{
    public void insert(Department department) {
        System.out.println("Add a user in sqlServer.");
    }
    public Department getDepartment(int id) {
        System.out.println("Delete a user through id in sqlServer");
        return null;
    }
}

package abstract_factory_pattern;

public interface IFactory {
    IUser createUser();
    IDepartment createDepartment();
}

package abstract_factory_pattern;

public class AccessFactory implements IFactory{
    public IUser createUser() {
        return new AccessUser();
    }
    public IDepartment createDepartment() {
        return new AccessDepartment();
    }
}

package abstract_factory_pattern;

public class SqlServerFactory implements IFactory{
    public IUser createUser() {
        return new SqlServerUser();
    }
    public IDepartment createDepartment() {
        return new SqlServerDepartment();
    }
}

package abstract_factory_pattern;
public class DataAccess {
    private static final String AssemblyName = "abstract_factory_pattern";
    private static final String db = "Access";
    //private static final String db = "SqlServer";//Changed part easily.
    public static IUser CreateUser() {
        String className = AssemblyName + "." + db + "User";
        IUser user = null;
        try {
            user = (IUser)Class.forName(className).newInstance();
        }catch(Exception e) {
            e.printStackTrace();
        }
        return user;
    }
}

package abstract_factory_pattern;

public class Main {
    public static void main(String args[]) {
        User user = new User();
        Department dept = new Department();
        //IFactory factory = new SqlServerFactory();
        IFactory factory = new AccessFactory();
        
        IUser iu = factory.createUser();
        iu.insert(user);
        iu.getUser(1);
        
        IDepartment id = factory.createDepartment();
        id.insert(dept);
        id.getDepartment(1);
        System.out.println();
        //Use reflection.
        IUser iuNew = DataAccess.CreateUser();
        iuNew.insert(user);
        
    }
}
/* The factory_pattern focus on the specific type of product.
 * By comparison:
 * The abstract_factory_pattern focus on multiple types of product.
 * Such as:
 * The department and user are different series of product.
 * This is good.But from the other side,if we want to add a new type like salary,
 * we have to add these class:ISalary,AccessSalary,SqlServerSalary and ISalary createSalary().
 * We need to revise all the factory's class.
 * So,we should to give a idea to avoid it.
 * We can remove abstract factory.
 * The premier code is compiled statically.
 * We can use reflection so as to let the object constructed dynamically.
 * The "Spring" uses "Dependency Injection" and configuration file.
 */

This is a general introduction to the 23 design patterns:
https://blog.csdn.net/GZHarryAnonymous/article/details/81567214

猜你喜欢

转载自blog.csdn.net/GZHarryAnonymous/article/details/82827666
今日推荐