Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.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接口、创建者模式和;getInstance();方法或同等方法_Java_Design Patterns_Abstract Factory - Fatal编程技术网

Java接口、创建者模式和;getInstance();方法或同等方法

Java接口、创建者模式和;getInstance();方法或同等方法,java,design-patterns,abstract-factory,Java,Design Patterns,Abstract Factory,我想首先提到我的问题源于Java中的接口不允许静态方法这一事实。关于这一点的原因已经有过讨论(例如)。所以,让我们不要详述这一点。我正在为我的接口寻找一种方法来创建自身的实例(而不是它的实现)并返回该实例。尽管使用了单例模式、工厂模式和抽象工厂模式,但我仍然无法实现我的目标 要详细说明我正在尝试的内容,以下是我的界面: public interface NoteDataStore { public boolean deleteNote(long noteId); public b

我想首先提到我的问题源于Java中的接口不允许静态方法这一事实。关于这一点的原因已经有过讨论(例如)。所以,让我们不要详述这一点。我正在为我的接口寻找一种方法来创建自身的实例(而不是它的实现)并返回该实例。尽管使用了单例模式、工厂模式和抽象工厂模式,但我仍然无法实现我的目标

要详细说明我正在尝试的内容,以下是我的界面:

public interface NoteDataStore {
    public boolean deleteNote(long noteId);
    public boolean addNote(Note note);
    public List<Note> listNotes();
    public boolean editNote(long noteId, Note note);
    public List<Note> search(String searchString);
}
我尝试使用工厂模式,如下所示:

public interface NoteDataStoreFactory {
    public NoteDataStore getDataStoreInstance();
}

public class NoteDataStoreFactoryImpl implements NoteDataStoreFactory{
    public NoteDataStore getDataStoreInstance(){
        return NoteDataStoreImpl.getInstance();
        /*
         * Here, NoteDataStoreImpl is an implementation of NoteDataStore.
         * This should be transparent to my business logic layer.
         */
    }
}
但是,这仍然需要业务逻辑层了解实现类
NoteDataStoreFactoryImpl
,因此:

NoteDataStore = new NoteDataStoreFactoryImpl().getDataStoreInstance();
我该怎么做?关于要使用的具体实现类,我如何让我的BusinessLogicLayer蒙在鼓里


编辑:我的问题的更详细背景 一些答案建议使用Spring之类的框架。唉,我不能这样做,因为这个应用程序针对各种移动平台(Android、Blackberry、JavaME)。我应该在我最初的问题中明确这一点——为没有这样做而道歉

我的主要目的是开发一款跨平台的应用程序。用户界面、数据库访问、HTTP传输层等必须针对每个平台进行专门编码。然而,业务逻辑非常简单,可以保证在所有平台上都有一个公共层。我打算将业务逻辑层作为JAR库分发。解析和框架层(对于JSON/XML)也是如此

关于这一点,SO已经有过讨论(关于我是否应该走这条路)——。但是,假设这是可以的,并且我继续使用分层方法,并且打算在代码中使用一个通用层。现在,我的情况是:

  • 公共业务逻辑层
  • 特定于平台的数据层(由
    NoteDataStore
    接口表示)
  • 特定于平台的应用程序核心层(控制器,如果我可以这样称呼的话)
  • 请注意,如果我使用Factory模式或其他类似模式,我可以为每个平台提供特定的层。因此,工厂方法/类本身可以了解
    NoteDataStore
    实现类。但是,业务逻辑层必须不知道任何实现类

    各层的典型用途如下:

    public class NoteDataStoreAndroid implements NoteDataStore{
    
        public boolean deleteNote(long noteId){
            /*
             * Android-specific database code
             */
        }
    
        /* ... similarly, other methods */
    }
    
    
    public class AndroidCoreApp{
    
        public void doBusinessLogic(){
            BusinessLogicLayer businessLogic = new BusinessLogicLayer();
            businessLogic.startBusinessLogic();
        }
    }
    

    关于如何处理此场景的任何输入?

    如果要返回实现,可以使用匿名内部类

    NoteDataStore myImplementation = new NoteDataStore (){
    //Implement methods here
    };
    

    您的类应该接受来自外部的工厂实例。当您自己创建实例时,您一无所获,在这里您是正确的

    这里有几种技巧。一般来说,它们属于一种非常普遍的东西,简称IoC。了解“控制容器反转”或IoCC也很有用。Java以Spring为例—read。你应该向真正的Java人询问其他人:)


    还可以看看这一点。

    您看过像Guice和Spring这样的IoC/依赖注入框架吗?它们可能对你所寻找的东西来说太重了,但它们确实解决了你所描述的问题。它们允许根据接口编写所有业务层代码,并通过IoC框架定义实际实现。我个人是Spring的忠实粉丝,在过去6年多的时间里,我几乎在每一个Java应用程序中都使用过Spring。

    我最终接受了@Ray Tayek在对原始问题的评论中提供的建议。在创建
    BusinessLogicLayer
    时,我只需传入
    NoteDataStore
    的一个实例

    这个简单的解决方案非常适合我的需要,因为我并不真正需要工厂。我的主要目标是让BL层不知道它使用的接口的确切实现类。现在,创建接口的具体实现并将其提供给BL层的是核心“控制器”层,而不是工厂。这太完美了

    下面是代码片段

    public class NoteDataStoreAndroid implements NoteDataStore{
    
        public boolean deleteNote(long noteId){
            /*
             * Android-specific database code
             */
        }
    
        /* ... similarly, other methods */
    }
    
    
    public class AndroidCoreApp{
    
        public void doBusinessLogic(){
            BusinessLogicLayer businessLogic = new BusinessLogicLayer(new NoteDataStoreAndroid());
            businessLogic.startBusinessLogic();
        }
    }
    
    public class BusinessLogicLayer {
    
        private NoteDataStore mDataStore;
        public BusinessLogicLayer(NoteDataStore dataStore){
            this.mDataStore = dataStore;
    
            //Do something useful with mDataStore
        }
    
        public void startBusinessLogic(){
            //Do something useful with mDataStore
        }
    
    }
    

    建议您使用ID框架,如Guice和其他框架。不仅仅是使用工厂模式。

    为什么不将NoteDataStoreFactory的实例传递给BusinessLogicLayer构造函数呢?事实上@Ray Tayek,我甚至不需要工厂类。我可以直接将
    NoteDataStore
    的实例传递给
    BusinessLogicLayer
    构造函数-这很有意义,因为“控制器”层是创建
    NoteDataStore
    具体实例的最佳位置。感谢您的详细回复。不幸的是,我没有使用Spring或其他框架的特权。有关我为什么这样说的详细信息,请参见编辑后的问题。我想我可能必须自己实现IoC技术。@techie:好吧,使用IoC并不意味着它应该像春天一样可怕。例如,服务定位器可能非常便宜且易于编写。老实说,我敢肯定,在Java的世界里,存在着一些小的IoCC类型的东西,这些东西正是针对移动设备的。我自己不是一个拳击手,所以在这里不能给你很好的建议。试着问一些关于Java中不同轻量级IOCC的新问题。@OscarMk,谢谢你的建议。我认为它在某些情况下会非常有效。不过,我还在想它怎么适合我的。请查看编辑后的问题,了解有关我的具体场景的更多详细信息。我无法使用框架。请参阅问题(已编辑),了解有关我的场景的更多详细信息。再一次,为没有在第一时间提及这些细节而道歉!虽然这可能是解决问题的一个有价值的提示,但一个好的答案也说明了解决方案。请提供示例代码来说明您的意思。或者,考虑将此写入评论。
    public class NoteDataStoreAndroid implements NoteDataStore{
    
        public boolean deleteNote(long noteId){
            /*
             * Android-specific database code
             */
        }
    
        /* ... similarly, other methods */
    }
    
    
    public class AndroidCoreApp{
    
        public void doBusinessLogic(){
            BusinessLogicLayer businessLogic = new BusinessLogicLayer(new NoteDataStoreAndroid());
            businessLogic.startBusinessLogic();
        }
    }
    
    public class BusinessLogicLayer {
    
        private NoteDataStore mDataStore;
        public BusinessLogicLayer(NoteDataStore dataStore){
            this.mDataStore = dataStore;
    
            //Do something useful with mDataStore
        }
    
        public void startBusinessLogic(){
            //Do something useful with mDataStore
        }
    
    }