Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何控制另一个类中的构造函数访问_Java_Design Patterns_Constructor - Fatal编程技术网

Java 如何控制另一个类中的构造函数访问

Java 如何控制另一个类中的构造函数访问,java,design-patterns,constructor,Java,Design Patterns,Constructor,我创建了一个类(ProjectsDataAccess),该类将处理对数据库的访问,该类可以执行以下操作: 接收项目对象并将其保存到数据库 从数据库中按id检索项目,并将其作为项目对象返回 这是psudo代码: class ProjectsDataAccess { public void addProject(Project project) { // get the project data from the object and save it to t

我创建了一个类(ProjectsDataAccess),该类将处理对数据库的访问,该类可以执行以下操作:

  • 接收项目对象并将其保存到数据库
  • 从数据库中按id检索项目,并将其作为项目对象返回
  • 这是psudo代码:

     class ProjectsDataAccess {
    
            public void addProject(Project project) {
              // get the project data from the object and save it to the database
            }
    
            public void getProject() {
             // get the project data from the database and return new project 
             //object with that data
            }
    
          }
    
    这就是项目的目标:

    class Project{
    
       private String name;
       private int id;
    
       private Project(){}
    
       Project(int id, String name){
         this. id = id;
         this.name = name;
       }
       Project(String name){
         this. id = // generate id
         this.name = name;
      }
    }
    

    我的问题是,我不希望类的用户使用此构造函数创建对象并提供自己的ID
    项目(int-ID,String-name)
    ,但我只希望ProjectsDataAccess类使用它,以便它能够从数据库中检索数据(包括ID),然后使用构造函数进行设置。有没有一种方法可以改变我的设计来做到这一点。

    解决方案是将
    ProjectsDataAccess
    Project
    类保持在同一个包中,并使构造函数
    Project(int-id,String-name)
    包可见(没有任何修改,就像现在一样)。另一个构造函数
    项目(字符串名称)
    需要是
    公共的
    才能对客户端代码可见。当然,将客户机代码放在不同的包中

     package foo;
    
     public class ProjectsDataAccess {
    
        public void addProject(Project project) {
          // get the project data from the object and save it to the database
        }
    
        public void getProject() {
         // get the project data from the database and return new project 
         //object with that data
        }
    
      }
    
    
    
    package foo;
    
    public class Project {
    
       private String name;
       private int id;
    
       private Project(){}
    
       Project(int id, String name){
          this. id = id;
          this.name = name;
       }
    
       public Project(String name){
          this. id = // generate id
          this.name = name;
       }
    }
    

    我建议您向用户返回一个不同的界面,只使用用户应该调用的方法

    例如:

    interface UserProjectInterface
    {
       void AnyMethodUserIsSupposedToCall();
    }
    
    class Project implements ProjectUserInterface
    {
       //constructor won-t be no longer visible to the client class
       public Project(){}
    }
    
    然后仅返回接口:

    class ProjectsDataAccess {
    
       public void addProject(ProjectUserInterfaceproject);
    
    
       public ProjectUserInterfacegetProject getProject() {
         return new Project();
       }
    
    }
    
    这种模式有几个不同的优点,因为您没有向客户机类公开具体类型


    编辑:

    如果用户应该创建UserProjectInterface,则可以使用工厂来创建对象:

    interface AbstractProjectFactory
    {
        UserProjectInterface CreateProject();
    
    }
    
    并提供实例化具体对象的实现:

    public AConcreteProjectFactory implements AbstractProjectFactory
    {
        public UserProjectInterface CreateProject()
        {
           return new Project();
        }
    }
    
    用法示例:

    //client class:
    AbstractProjectFactory factory = new AConcreteProjectFactory();
    UserProjectInterface project = factory.CreateProject();
    
    ProjectsDataAccess access = new ProjectsDataAccess();
    access.addProject(project );
    

    你能解释更多吗,因为用户需要创建一个新的项目对象并将其传递给ProjectsDataAccess。感谢您的编辑,现在就有意义了。那么,您对dcernahoschi解决方案有何看法?您认为使用工厂模式会给我带来更大的灵活性,还是会让事情变得更复杂,而不是将构造函数包私有化。嗯,他的答案是正确的。顺便说一句,这取决于您项目的复杂性。通常,使用接口和工厂是强制类解耦和隐藏具体类型的好方法。除了隐藏构造函数之外,它还有很多好处。我唯一的问题是,我将Project类和ProjectsDataAccess类放在不同的包中,很难移动它,因为包含Project类的包在客户端和服务器之间共享。但包的主要目标之一是:隐藏内部从客户端代码。如果您将ProjectsDataAccess和constructor项目(int-id,String-name)视为“内部构件”,那么它们应该保持在同一个包中。