- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
关闭。这个问题需要更多 focused .它目前不接受答案。
想改进这个问题?更新问题,使其仅关注一个问题 editing this post .
4年前关闭。
Improve this question
我在我的应用程序的一个部分中使用工厂设计模式,我注意到使用常规工厂模式每次都会创建一个新对象。我有一个场景,我需要多次迭代工厂类中的 createinstance 方法,并且每次创建新的消费者对象时。
在 Program.cs 中,我创建了人员列表,我在其中键入了一些随机输入数据。基于对每个人的操作的代码应该动态地执行该类中的 process 方法。这个逻辑似乎像我预期的那样工作,但是如果重复相同的操作,那么会多次创建相同的对象。
为了解决这个问题,我修改了 ActionFactory 类(如下面的 Modified Action Factory 片段所示),我在其中维护一个字典来保存为特定操作创建的实例。如果重复该操作,则不是创建新实例,而是从字典中获取先前创建的实例。这似乎已经解决了问题,如 Output2 图像所示。
但是我想知道/向专业人士学习,如果我在“Modified Action Factory”类中所做的工作是否足够(或者)对于这类问题我应该使用其他模式而不是工厂设计模式。为了维护单个对象,我能想到的另一种方法可能是在每个 Action 类中创建一个单例对象,但问题是如何从工厂类调用单例实例?因为工厂类总是调用 createinstance 而不会调用单例实例..我是设计模式的新手,我正在努力学习更多关于它们的知识并提高我的编码标准。提前致谢
下面是代码:
class Program
{
static void Main(string[] args)
{
List<Person> ListofPeople = new List<Person>();
Person p1 = new Person() {Name = "P1", State = "CA", Action = "Add"};
ListofPeople.Add(p1);
Person p2 = new Person() { Name = "P2", State = "NJ", Action = "Add" };
ListofPeople.Add(p2);
Person p3 = new Person() { Name = "P3", State = "VA", Action = "Update" };
ListofPeople.Add(p3);
Person p4 = new Person() { Name = "P4", State = "VA", Action = "Update" };
ListofPeople.Add(p4);
Person p5 = new Person() { Name = "P5", State = "VA", Action = "Update" };
ListofPeople.Add(p5);
Person p6 = new Person() { Name = "P6", State = "VA", Action = "Delete" };
ListofPeople.Add(p6);
ActionFactory factory= new ActionFactory();
foreach (var person in ListofPeople)
{
IAction action = (IAction) factory.CreateInstance(person.Action.ToLower());
action.Process();
}
Console.ReadKey();
}
}
public class Person
{
public string Name { get; set; }
public string State { get; set; }
public string Action { get; set; }
}
public class ActionFactory
{
Dictionary<string, Type> actions;
public ActionFactory()
{
LoadTypesICanReturn();
}
public object CreateInstance(string actionName)
{
Type t = GetTypeToCreate(actionName);
if (t == null)
return null;
var actionProcessor = Activator.CreateInstance(t) as IAction;
return actionProcessor;
}
Type GetTypeToCreate(string actionName)
{
foreach (var action in actions)
{
if (action.Key.Contains(actionName))
{
return actions[action.Key];
}
}
return null;
}
void LoadTypesICanReturn()
{
actions = new Dictionary<string, Type>();
Type[] typesInThisAssembly = Assembly.GetExecutingAssembly().GetTypes();
foreach (Type type in typesInThisAssembly)
{
if (type.GetInterface(typeof(IAction).ToString()) != null)
{
actions.Add(type.Name.ToLower(), type);
}
}
}
}
public interface IAction
{
void Process();
}
public class Add: IAction
{
public Add()
{
Console.WriteLine("add constructor...");
}
#region IAction Members
public void Process()
{
Console.WriteLine("Add Processor....");
}
#endregion
}
public class Update: IAction
{
public Update()
{
Console.WriteLine("Update constructor...");
}
public void Process()
{
Console.WriteLine("Update Processor...");
}
}
public class Delete : IAction
{
public Delete()
{
Console.WriteLine("Delete Constructor...");
}
#region IAction Members
public void Process()
{
Console.WriteLine("Delete Processor...");
}
#endregion
}
public class ActionFactory
{
Dictionary<string, Type> actions;
private Dictionary<Type, IAction> actionInstances;
public ActionFactory()
{
actionInstances = new Dictionary<Type, IAction>();
LoadTypesICanReturn();
}
public object CreateInstance(string actionName)
{
Type t = GetTypeToCreate(actionName);
if (t == null)
return null;
if (actionInstances.ContainsKey(t))
return actionInstances[t];
else
{
var actionProcessor = Activator.CreateInstance(t) as IAction;
LoadIAction(t, actionProcessor);
return actionProcessor;
}
}
private void LoadIAction(Type t, IAction actionProcessor)
{
if (!actionInstances.ContainsKey(t))
{
actionInstances.Add(t, actionProcessor);
}
}
Type GetTypeToCreate(string actionName)
{
foreach (var action in actions)
{
if (action.Key.Contains(actionName))
{
return actions[action.Key];
}
}
return null;
}
void LoadTypesICanReturn()
{
actions = new Dictionary<string, Type>();
Type[] typesInThisAssembly = Assembly.GetExecutingAssembly().GetTypes();
foreach (Type type in typesInThisAssembly)
{
if (type.GetInterface(typeof(IAction).ToString()) != null)
{
actions.Add(type.Name.ToLower(), type);
}
}
}
}
最佳答案
Factory
设计模式用于简化对象的创建,通常当您不知道要创建的类型时,它将在运行时提供。
有时,也可能是因为它们有依赖关系,而你想抽象依赖关系的创建,或者只是因为你想做一些事情。
在您的情况下,Add
, Update
, 和 Delete
是通常由某些第 3 方调用的方法,而不是数据类型本身,由 @sokohavi
指定多于。
您的案件可以由Command Design Pattern
处理.
假设你想加载一堆命令(又名:Add Person X, Update Person Y, Delete Person Z
),并且你想缓冲它们以备将来使用。
abstract class PersonCommand
{
Person Person { protected get; } // you can call this payload, or person, w/e
PersonCommand(Person person)
{
Person = person;
}
public abstract void Apply(); // can be called Execute or Process as well, or w/e. problem domain.
}
class AddCommand : PersonCommand
{
AddCommand(Person person) : base(person) { }
public override void Apply()
{
// send REST PUT request, add person to DB, whatever you want to do here.
}
}
class UpdateCommand : PersonCommand
{
UpdateCommand(Person person) : base(person) { }
public override void Apply()
{
// send REST POST request, update person in DB, whatever you want to do here.
}
}
class DeleteCommand : PersonCommand
{
DeleteCommand(Person person) : base(person) { }
public override void Apply()
{
// send REST DELETE request, remove person from DB, whatever you want to do here.
}
}
var commandsToExecute = new List<PersonCommand>();
commandsToExecute.Add(new AddCommand(new Person { Name = "asd", State = "CA" }));
commandsToExecute.Add(new UpdateCommand(new Person { Name = "barry", State = "CA" }));
commandsToExecute.Add(new DeleteCommand(new Person { Name = "barry", State = "CA" }));
commandsToExecute.ForEach(cmd => cmd.Apply());
Command
s 不是那么容易创建的,例如,它们可能需要了解 REST 请求的服务端点。
CommandFactory
可以创建,然后可以通过操作名称处理创建:
class CommandFactory
{
private readonly Dictionary<string, Func<Person, PersonCommand>> creationFuncs;
CommandFactory(string backendUrl)
{
creationFuncs = new Dictionary<string, Func<Command, Person>>();
creationFuncs.Add("add", (person) => return new AddCommand(backendUrl, person));
creationFuncs.Add("update", (person) => return new UpdateCommand(backendUrl, person));
creationFuncs.Add("delete", (person) => return new DeleteCommand(backendUrl, person));
}
PersonCommand Create(string action, Person person)
{
// validation can be added here
return creationFuncs[action](person);
}
}
var factory = new CommandFactory("http://localhost:4200/person/");
var commandsToExecute = new List<PersonCommand>();
commandsToExecute.Add(factory.Create("add", new Person { Name = "asd", State = "CA" }));
commandsToExecute.Add(factory.Create("update", new Person { Name = "barry", State = "CA" }));
commandsToExecute.Add(factory.Create("delete", new Person { Name = "barry", State = "CA" }));
commandsToExecute.ForEach(cmd => cmd.Apply());
关于c# - 工厂模式和对象持久性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43310187/
对此感到疯狂,真的缺少一些东西。 我有webpack 4.6.0,webpack-cli ^ 2.1.2,所以是最新的。 在文档(https://webpack.js.org/concepts/mod
object Host "os.google.com" { import "windows" address = "linux.google.com" groups = ["linux"] } obj
每当我安装我的应用程序时,我都可以将数据库从 Assets 文件夹复制到 /data/data/packagename/databases/ .到此为止,应用程序工作得很好。 但 10 或 15 秒后
我在 cc 模式缓冲区中使用 hideshow.el 来折叠我不查看的文件部分。 如果能够在 XML 文档中做到这一点就好了。我使用 emacs 22.2.1 和内置的 sgml-mode 进行 xm
已结束。此问题不符合 Stack Overflow guidelines .它目前不接受答案。 我们不允许提出有关书籍、工具、软件库等方面的建议的问题。您可以编辑问题,以便用事实和引用来回答它。 关闭
根据java: public Scanner useDelimiter(String pattern) Sets this scanner's delimiting pattern to a patt
我读过一些关于 PRG 模式以及它如何防止用户重新提交表单的文章。比如this post有一张不错的图: 我能理解为什么在收到 2xx 后用户刷新页面时不会发生表单提交。但我仍然想知道: (1) 如果
看看下面的图片,您可能会清楚地看到这一点。 那么如何在带有其他一些 View 的简单屏幕中实现没有任何弹出/对话框/模式的微调器日期选择器? 我在整个网络上进行了谷歌搜索,但没有找到与之相关的任何合适
我不知道该怎么做,我一直遇到问题。 以下是代码: rows = int(input()) for i in range(1,rows): for j in range(1,i+1):
我想为重写创建一个正则表达式。 将所有请求重写为 index.php(不需要匹配),它不是以/api 开头,或者不是以('.html',或'.js'或'.css'或'.png'结束) 我的例子还是这样
MVC模式代表 Model-View-Controller(模型-视图-控制器) 模式 MVC模式用于应用程序的分层开发 Model(模型) - 模型代表一个存取数据的对象或 JAVA PO
我想为组织模式创建一个 RDF 模式世界。您可能知道,组织模式文档基于层次结构大纲,其中标题是主要的分组实体。 * March auxiliary :PROPERTIES: :HLEVEL: 1 :E
我正在编写一个可以从文件中读取 JSON 数据的软件。该文件包含“person”——一个值为对象数组的对象。我打算使用 JSON 模式验证库来验证内容,而不是自己编写代码。符合代表以下数据的 JSON
假设我有 4 张 table 人 公司 团体 和 账单 现在bills/persons和bills/companys和bills/groups之间是多对多的关系。 我看到了 4 种可能的 sql 模式
假设您有这样的文档: doc1: id:1 text: ... references: Journal1, 2013, pag 123 references: Journal2, 2014,
我有这个架构。它检查评论,目前工作正常。 var schema = { id: '', type: 'object', additionalProperties: false, pro
这可能很简单,但有人可以解释为什么以下模式匹配不明智吗?它说其他规则,例如1, 0, _ 永远不会匹配。 let matchTest(n : int) = let ran = new Rand
我有以下选择序列作为 XML 模式的一部分。理想情况下,我想要一个序列: 来自 my:namespace 的元素必须严格解析。 来自任何其他命名空间的元素,不包括 ##targetNamespace和
我希望编写一个 json 模式来涵盖这个(简化的)示例 { "errorMessage": "", "nbRunningQueries": 0, "isError": Fals
首先,我是 f# 的新手,所以也许答案很明显,但我没有看到。所以我有一些带有 id 和值的元组。我知道我正在寻找的 id,我想从我传入的三个元组中选择正确的元组。我打算用两个 match 语句来做到这
我是一名优秀的程序员,十分优秀!