我应该如何编写工厂类 - 生成派生的对象
首先,我将布置我的一般设置并描述类的目标,因为我认为这对于一个问题很重要:
- 这旨在根据应用程序需要动态缓存文件和文件夹。
- 如果用户需要将它们复制到某个地方,则可以复制本地版本,而不是每次下载遥控器。相反,只有在可用的文件/文件夹更新时才下载。 (对于文件夹,这是通过Robocopy Rigroner执行的)
- 此外,对这里的文字墙感到抱歉
public enum SyncMode
{
None = -2, // SyncMode Not Defined by Object (don't actually intend in my use case, added for future compatibility/interfaces)
AlwaysReturnNetwork = -1, //DynamicPath should prioritize the network string, UNLESS the network is unavailable and the path exists locally.
Dynamic = 0, // Another one for potential future objects
OfflineCache = 1, // Allow file/folder to be downloaded for use in offline mode of the application
LocalCache = 2, // Cache the file/folder locally for quicker access
AlwaysReturnLocal = 3, // Designed to essentially be a file that is required by the application
}
// this class will allow consumers to override some functions, for example the actions to take when downloading the file from remote to local.
//(base will assume its not web-based, so a web-based consumer will need to implement that functionality by overriding the virtual methods)
// As shown below, the consumer must also specify how to determine if the user is set up to local/offline cache, as well as if the application is running in offline (assume network unavailable) mode
public abstract class FileOperations
{
abstract bool IsApplicationOffline {get;}
abstract bool AllowOfflineCaching {get;}
abstract bool AllowLocalCaching {get;}
}
public abstract class AbstractNetworkPath
{
public string LocalPath { get; } // File/Folder might exist at this location on the pc
public string NetPath { get; } // File/Folder should exist at this location on a remote location
public SyncMode SyncMode {get;} //Determine how the DynamicPath functions
public string DynamicPath {get;} //String is returned based on the SyncMode value and if the path exists locally
protected bool ShouldCache => SyncMode == AlwaysReturnLocal || SyncMode >=OfflineCache && FileOps.AllowOfflineCaching || SyncMode >= LocalCaching && FileOps.AllowLocalCaching;
internal protected FileOperations FileOps {get;} // Reference to the object passed into the ctor/factory
}
public class SyncedFile : AbstractNetworkPath
{
public void CopyTo(string destPath)
{
if (ShouldCache) this.FileOps.UpdateFile(this.NetPath, this.LocalPath);
FileOps.CopyFile(this.DynamicPath, destPath);
}
}
public class NetworkFolder: AbstractNetworkPath
{
// This class represents a remote folder, and prioritizes the network location
// This is meant to specify some location, not necessarily one that gets downloaded.
// For example, a main directory with a bunch of files/folders, most of which the application doesn't need or want.
}
public class SyncedFolder : NetworkFolder
{
// This class represents a remote folder, but prioritizes the local location
// This class also adds the methods to download the folder locally
public void CopyTo(string destPath)
{
if (ShouldCache) this.FileOps.UpdateFolder(this.NetPath, this.LocalPath);
FileOps.CopyFolder(this.DynamicPath, destPath);
}
}
,因此它很有趣:
- 我要为此设置的工厂将包含FileOps对象,因此消费者不必必须在构造函数中不断地指定它 - 工厂将为他们做。
- 网络文件夹中存在一个SyncedFile(但不一定在该文件夹中,而是在子文件夹路径中),因此SyncedFileFactory必须包含一种使用该父级创建对象的方法。同样的原理适用于同步固定器
- SyncedFile和SyncedFolder都期望永远不会使用“ EnswaysRoturnnetwork”枚举值。这就是为什么我想使用工厂方法,以确保该值永远不会传递到CTOR中,因为这些对象处于该状态是没有意义的。
- 还有一个我允许从中创建对象的界面。这样,消费者可以从数据库(或我的情况下是Excel文件)中读取一些实现接口的对象,然后将其传递到工厂以构造对象。
这是问题:
我的计划是拥有
SyncedFileFactory
,NetworkFolderFactory
和SyncedfolderFactory
- 但是,既然我已经写出来了,我只能评估SyncMode并从NetworkFolderFactory返回SynceDFolder或NetworkFolder。这是足够容易理解的,还是我应该拥有自己的工厂以清楚建筑?
- 请注意,我最初没有想到这个问题,因此我以下问题:
拥有将其SyncMode应用于所构建的类的工厂是否有意义?或更通用的工厂,简单地验证传递到该方法的SyncMode?
这是我目前拥有的:
public class SyncedFileFactory
{
Public SyncedFileFactory(SyncMode syncmode, FileOperations fileOps) { /* Ctor*/ }
public FileOperations FileOperationsObj{get;}
Public SyncMode SyncMode {get;}
}
public class NSOFactory
{
Public NSOFactory(FileOperations fileOps)
{
FileFactory_Offline = new(SyncMode.OfflineCache, fileOps);
FileFactory_LocalCache = new(SyncMode.LocalCache, fileOps);
FileFactory_Required = new(SyncMode.AlwaysReturnLocal, fileOps);
}
public SyncedFileFactory FileFactory_Offline {get;}
public SyncedFileFactory FileFactory_LocalCache {get;}
public SyncedFileFactory FileFactory_Required {get;}
}
我喜欢这会强制执行SyncModes的类型,并且仅构造具有有效同步模式的对象,但是当从已经指定的syncmode构造的对象时,我们会遇到一些问题,我遇到了一些问题,我' m不确定在使用该接口时保持工厂结构清除(强制指定SyncMode)时,最佳方法可以使工厂结构保持清晰
- ,尚不清楚应该发生什么。 (它使用接口指定的SyncMode或工厂的SyncMode?)
- 使用父网络折叠对象生成它时的同一问题。
- 但是,如果网络折叠符对象是“ ewerning returnnetwork”,那么SyncedFile和SyncedFolder不应继承它
:可能的解决方案 - 需要思考:
因此,现在我的思维方式本质上是:
Offlinecache
应该优先考虑localcache
,用于施工,但是ewlboyturnlocal
是施工的最高优先级。那么,我是否只是简单地评估输入父母和所选工厂并采取相应行动?那可能是最简单的事情。但是,如果有人去看它,您将与输入值不同的输出值结束。这种交互降低了清晰度,但与库的预期功能保持一致。
To start, I'll lay out my general setup and describe the goal of the classes, as I feel its important for the question:
- This is designed to dynamically cache files and folders as needed by the application.
- If the user needs to copy them somewhere, this allows them to copy the local version instead of downloading off the remote every single time. Instead, it will only download if an update to the file/folder is available. (For folders, this is performed with robocopy mirroring)
- Also, sorry for wall of text here
public enum SyncMode
{
None = -2, // SyncMode Not Defined by Object (don't actually intend in my use case, added for future compatibility/interfaces)
AlwaysReturnNetwork = -1, //DynamicPath should prioritize the network string, UNLESS the network is unavailable and the path exists locally.
Dynamic = 0, // Another one for potential future objects
OfflineCache = 1, // Allow file/folder to be downloaded for use in offline mode of the application
LocalCache = 2, // Cache the file/folder locally for quicker access
AlwaysReturnLocal = 3, // Designed to essentially be a file that is required by the application
}
// this class will allow consumers to override some functions, for example the actions to take when downloading the file from remote to local.
//(base will assume its not web-based, so a web-based consumer will need to implement that functionality by overriding the virtual methods)
// As shown below, the consumer must also specify how to determine if the user is set up to local/offline cache, as well as if the application is running in offline (assume network unavailable) mode
public abstract class FileOperations
{
abstract bool IsApplicationOffline {get;}
abstract bool AllowOfflineCaching {get;}
abstract bool AllowLocalCaching {get;}
}
public abstract class AbstractNetworkPath
{
public string LocalPath { get; } // File/Folder might exist at this location on the pc
public string NetPath { get; } // File/Folder should exist at this location on a remote location
public SyncMode SyncMode {get;} //Determine how the DynamicPath functions
public string DynamicPath {get;} //String is returned based on the SyncMode value and if the path exists locally
protected bool ShouldCache => SyncMode == AlwaysReturnLocal || SyncMode >=OfflineCache && FileOps.AllowOfflineCaching || SyncMode >= LocalCaching && FileOps.AllowLocalCaching;
internal protected FileOperations FileOps {get;} // Reference to the object passed into the ctor/factory
}
public class SyncedFile : AbstractNetworkPath
{
public void CopyTo(string destPath)
{
if (ShouldCache) this.FileOps.UpdateFile(this.NetPath, this.LocalPath);
FileOps.CopyFile(this.DynamicPath, destPath);
}
}
public class NetworkFolder: AbstractNetworkPath
{
// This class represents a remote folder, and prioritizes the network location
// This is meant to specify some location, not necessarily one that gets downloaded.
// For example, a main directory with a bunch of files/folders, most of which the application doesn't need or want.
}
public class SyncedFolder : NetworkFolder
{
// This class represents a remote folder, but prioritizes the local location
// This class also adds the methods to download the folder locally
public void CopyTo(string destPath)
{
if (ShouldCache) this.FileOps.UpdateFolder(this.NetPath, this.LocalPath);
FileOps.CopyFolder(this.DynamicPath, destPath);
}
}
So here is where it gets fun:
- The factories I want to set up for this will contain the FileOps object so that the consumer doesn't have to constantly specify it in the constructor - the factory will do it for them.
- A SyncedFile exists within a NetworkFolder(but not necessarily in that folder, but maybe in a subfolder path), so the SyncedFileFactory must contain a method to create a object using that parent. This same principle applies to SyncedFolder
- SyncedFile and SyncedFolder both expect to never use the 'AlwaysReturnNetwork' enum value. This is partly why I wanted to use a factory method, to ensure that value is never passed into the CTOR, as it doesn't make sense for those objects to be in that state.
- There also exists an interface I'm allowing creation of the object from. This way, a consumer can read data from a database (or in my case an excel file) into some object that implements the interface, which can then be passed into the factory to construct the object.
Heres are questions:
My plan is to have a
SyncedFileFactory
, aNetworkFolderFactory
, and aSyncedFolderFactory
- But, now that I've written that out, I could just evaluate the SyncMode and return either a SyncedFolder OR NetworkFolder from the NetworkFolderFactory. Is this the easy enough to understand, or should I have its own factory for clarity of construction?
- Note that I didn't think of this originally due to my question below:
Does it make sense to have a factory that applies its SyncMode to the class being constructed? Or a more generic Factory that simply validates the SyncMode passed into the method?
Here is what I have at the moment:
public class SyncedFileFactory
{
Public SyncedFileFactory(SyncMode syncmode, FileOperations fileOps) { /* Ctor*/ }
public FileOperations FileOperationsObj{get;}
Public SyncMode SyncMode {get;}
}
public class NSOFactory
{
Public NSOFactory(FileOperations fileOps)
{
FileFactory_Offline = new(SyncMode.OfflineCache, fileOps);
FileFactory_LocalCache = new(SyncMode.LocalCache, fileOps);
FileFactory_Required = new(SyncMode.AlwaysReturnLocal, fileOps);
}
public SyncedFileFactory FileFactory_Offline {get;}
public SyncedFileFactory FileFactory_LocalCache {get;}
public SyncedFileFactory FileFactory_Required {get;}
}
I like that this enforces the types of SyncModes and only constructs objects with valid sync modes, but when constructing from an object that already has a syncMode specified, we run into a few issues, and I'm unsure the best way to work around this while keeping factory structure clear
- when using the interface (which enforces specifying a SyncMode), it becomes unclear what should happen. (Does it use the SyncMode specified by the interface, or the SyncMode of the factory?)
- Same issue for when generating it using a parent NetworkFolder object.
- But if the NetworkFolder object is 'AlwaysReturnNetwork', then SyncedFile and SyncedFolder should not inherit it anyway
Edit: Possible Solution - Need Thoughts on this:
So now my line of thinking is essentially:
OfflineCache
should take priority overLocalCache
, for construction, butAlwaysReturnLocal
is highest priority for construction. So Do I simply evaluate the input parent and the chosen factory and act accordingly? That might be the easiest thing to do. But if someone goes to look at it, you wind up with the output value differing from the input value. That interaction reduces clarity, but keeps in line with intended function of the library.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,因此,当我继续开发此DLL时,我遇到了其他一些问题。我将为下面的其他人详细介绍可能受到启发的任何人。
原始思考过程:创建每个SyncMode类型的工厂(至少是主要值)。
我想到的原因是:
此问题:
原始计划:具有一个全局设置对象,该库是指定义
func< bool>
是否确定应用程序是否确定应用程序的目标。是否处于离线模式,是否允许本地缓存等。此问题:
解决方案:
nsofactorySettings的属性
。所有派生类都指向此属性,而不是静态类。)用于执行特定枚举的结构:
工厂班级:
OK, so as I continued to develop this dll, i ran into some other issues that have since been worked out. I'll detail my resolution to this below for anyone else that may be inspired.
Original Thought Process: Create a factory of each SyncMode type (atleast the primary values).
Reason I thought of wanted it:
Problems with this:
Original Plans: Have a global settings object the library refers to that takes care of defining the
Func<bool>
targets that determine if the application is in offline mode, whether to allow local caching, etc.Problems with this:
Solutions:
NSOFactorySettings
. All derived classes now point to this property instead of the static class.)Struct used for enforcing specific enums:
Factory Class: