我在我的大学里制作了一个Google App Engine应用程序作为课程项目.现在我需要对其进行优化以便在商业上使用它.
如今,代码非常慢.它只有很少的模型,每个模型都有很多属性.在重写模型代码之前,我需要知道如果增加模型的数量,我的应用程序是否会更快,即增加去耦.在什么时候我应该考虑在其他模型中划分模型?
其他问题,如果解耦对性能产生积极影响,那么模型中的属性数量与从数据存储区获取数据的时间成正比?
optimization google-app-engine decoupling models google-cloud-datastore
假设我在 EF Core 中有一个查询,如下所示:
MethodWithDomainLogic() {
return this.dbContext.People.Where(...).ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)
现在,为了将我的域层与我的数据访问层分离,我希望这个方法在我的域程序集中,并且该程序集没有对 EFCore 的引用。所以它看起来像:
在领域层:
public interface IEntities {
IQueryable<Person> People { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在数据层:
private IEntities entities; // injected with a dbcontext that implements the IEntities interface.
public Task<IEnumerable<Person>> MethodWithDomainLogic() {
return this.entities.People.Where(...).ToListAsync(); // How to do this without referencing EFCore?
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这是不可能的,因为 Linq 本身不支持异步查询。
我已经通过在域层中使用 EFCore 接口设置我自己的接口解决了这个问题(基本上是复制并粘贴了 ToListAsync 和 FirstAsync 等方法......)然后在我的数据层中实现它,只需调用EFCore 版本。然而,这是非常混乱和复杂的。
有更好的解决方案吗?我希望我的域方法在没有 EFCore 的情况下使用异步编程和 Linq,但要在数据层中使用 EFCore 实现 Linq/异步编程。
我已经通过以下方式解耦了这个WPF应用程序中的事件.
继续脱钩的最佳方法是什么?
Shell.xaml:
<Button x:Name="btnProcess"
Content="Process"
Margin="10"/>
Run Code Online (Sandbox Code Playgroud)
Bootstrapper.cs:
public void Run()
{
Shell shell = new Shell(new Customer());
shell.Show();
}
Run Code Online (Sandbox Code Playgroud)
Shell.xaml.cs:
public Shell(IPerson person)
{
InitializeComponent();
btnProcess.Click +=new RoutedEventHandler(person.Process);
}
Run Code Online (Sandbox Code Playgroud)
Customer.cs:
public class Customer : IPerson
{
public void Process(object sender, RoutedEventArgs e)
{
Button theButton = (Button)sender;
theButton.Content = "Customer processed.";
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码成功地将视图Shell与模型分离,Customer:IPerson以便我可以交换例如以Employee:IPerson自己的方式处理"已处理" 的模型等.这是第一个目标.
但现在:
Processed方法与特定于Button 的方式分离,以便它还可以与一个MenuItem或一个ListView进行对话,该ViewView在视图中触发事件,因此它甚至不必是一个调用它的元素,例如单元测试类?我们有两个系统,其中系统A向系统B发送数据.要求每个系统可以独立于另一个系统运行,如果另一个系统停机,它们都不会爆炸.问题是系统A在满足解耦要求的同时与系统B通信的最佳方式是什么.
系统B当前有一个进程,用于轮询db表中的数据并处理已插入的任何新行.
一个提出的设计是系统A只是将数据插入系统b的db表中,并让系统B通过现有过程处理新行.问题是这个解决方案是否满足解耦两个系统的要求?数据库是否被视为系统B的一部分,可能变得不可用并导致系统A爆炸?
另一种解决方案是系统A将数据放入MQ队列,并具有从MQ读取然后插入系统B数据库的进程.但这只是额外的开销吗?最终是MQ队列比db表更容错吗?
假设我有一个名为Component的抽象基类,它是GUI组件层次结构的根.在这种情况下,我们可能有两个子类,Button和Label,它们都是抽象类,并作为各自具体类层次结构的根存在.
从Button继承的具体类可能包括RoundButton和SquareButton.
从Label继承的具体类可能包括TextLabel和PictureLabel.
最后,假设有一个聚合Container类,它包含一组Component对象.
问题是我有指向Component对象的指针,但我需要将它们标识为Buttons或Labels.例如,如果我想指定所有Buttons的内部文本应该有一个更大的字体,我可以迭代Container中的所有Component对象,并以某种方式确定哪些是按钮,并调用一些特定于按钮的方法.
这些组件"系列"标识自己的一种方法是使用字符串.
class Component {
public:
virtual char const * const getFamilyID() const = 0;
};
// In Button.h
char const * const COMPONENT_BUTTON = "button";
class Button : public Component {
public:
virtual char const * const getFamilyID() const { return COMPONENT_BUTTON; };
};
// Code sample
if (strcmp(component->getFamilyID(),COMPONENT_BUTTON) == 0)
// It's a button!
Run Code Online (Sandbox Code Playgroud)
这是松散耦合的,因为该组件的任务是为这些家庭定义这些家庭; 它不需要了解哪些家庭存在.客户端需要知道不同的组件系列,但如果它尝试针对某些操作来定位特定的组件系列,那么这是无法避免的.
但是,假设我们有非常高的性能要求,我们希望避免比较字符串.避免将此功能设置为虚拟也很好,以便我们可以内联它.此外,如果Component的每个子类都需要声明一个全局常量,那么以某种方式修改Component类以使其成为需求或使其不必要可能会很好.
解决此问题的一种方法是在Component.h中定义一个枚举器
enum COMPONENT_FAMILY {
COMPONENT_BUTTON = 0,
COMPONENT_LABEL,
// etc...
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,getFamilyID()只能返回COMPONENT_FAMILY枚举,我们基本上只能比较整数.不幸的是,这意味着任何新的组件系列都必须在此枚举中"注册",这很容易但对其他程序员来说并不完全直观.此外,该方法仍然必须是虚拟的,除非我们创建一个我们知道将具有极低基数(非理想)的非静态COMPONENT_FAMILY成员.
什么是解决这个问题的好方法?在我的情况下,性能是关键,虽然类似于枚举解决方案似乎很容易,但我想知道我是否忽略了更好的方法.
---编辑---
我意识到我应该指出,在实际系统中,Container等价物只能存储每个族的1个组件.因此,组件实际上存储在地图中,例如:
std:map<COMPONENT_FAMILY, Component*> …Run Code Online (Sandbox Code Playgroud) 我正在开发一个包含多个应用程序的项目,并希望包含新闻报道的新闻应用程序.
但是,我想将新闻故事链接到我的自定义应用程序中的对象,但使用开源新闻应用程序来运行新闻.
目前,我只是通过攻击所选的新闻应用程序来添加与我的模型的ForeignKey关系.
即一个小部件应用程序,具有小部件模型
然后是一个新闻应用程序,其入口模型直接链接到我的小部件模型
有一个更好的方法吗?因为如果我想用最新版本更新新闻应用程序,它显然会覆盖我的黑客.
我可以从我的自定义模型获得链接,但工作流程应该是真的
不
我想知道在c#(或者甚至是cli)中是否有一种标准方法可以有效地将实现逻辑分离为单独的类库/程序集,这些库/程序集将由一个进程动态加载,该进程将基于公共接口对这些库执行操作.
更确切地说:假设我正在构建一个接收消息的服务,并将这些消息的处理委托给其他人.就像是:
while(true){
message = read_message_from_somewhere();
class_from_another_lib.do_somthing_with_Message(message);
}
Run Code Online (Sandbox Code Playgroud)
我希望进程从某种配置中在运行时加载类lib.我假设lib会有一些主类或类工厂实现一些接口部分,如下所示:
ISomePublicIface{
void do_somthing_with_Message(messageT);
}
Run Code Online (Sandbox Code Playgroud)
这一切都感觉有些java isish我需要做的就是在一个程序集中使用一个类可注入的接口在应用程序配置中添加一行并免费获得一些东西.
想象一组代表某些 API 的库。通过使用控制反转机制,具体的实现将被注入到消费项目中。
这是一个情况。我有一些 API 库依赖于其他 API 库来实现某些功能 - 因此 API 库本身在某些时候是耦合的。这种耦合可能会在以后成为一个问题,因为改变一个 API 会导致依赖的 API 的改变,相应的实现也需要改变,所以在最坏的情况下,我们最终会得到相当多的项目需要改变。进行修改以反映仅其中一个形式的更改。
现在我想到了两种可能的解决方案:
创建一个统一相关 API 库的整体 API 项目。
通过使每个库为依赖于其他 API 的所有功能提供接口,进一步解耦 API,从而消除直接依赖关系。这可能会导致两个库中出现类似的代码,但可以自由地通过 IoC 机制选择实现,并且还允许 API 彼此独立地改进(当 API 发生更改时,更改只会影响其实现库,而不影响其他 API 或其实现)。
第二种方法的问题是重复代码,结果可能是需要引用太多的 api 库(例如,在 .NET 应用程序中,每个 API 将是一个单独的 DLL。在某些情况下,例如 Silverlight应用程序,这可能是应用程序大小的问题 - 下载时间和客户端性能总体)。
针对目前的情况有没有更好的解决办法。什么时候最好将一些 API 库合并到一个更大的库中,什么时候最好?我知道这是我问的一个非常普遍的问题,但让我们暂时忽略截止日期、估计、客户要求和技术,我希望能够在实现最大可扩展性和最短维护时间的基础上确定正确的方法。那么,选择这两种方法或您可能建议我的另一种方法的充分理由是什么?
编辑:
我觉得我必须澄清一下这个问题。我想要的是 API 之间的解耦,而不是 API 与其实现的解耦。因此,例如,如果我有用于验证访问权限的安全 API,以及使用(引用)安全 API 的用户帐户 API,则更改安全 API 将需要更改用户帐户 API 以及两者的实现。以这种方式耦合的 API 越多,需要应用的更改就越多。这是我想避免的。
让我说我有classA一类音频,多次采样音频输入.每次class A获得一个新数据(可以在第二次发生多次),他需要通知另一个类,即classB.
现在,我可以只让实例class B 在classA和B键时,有一个新的数据到达,但这不是一个模块化的软件.
我想classA是"盲"到外面,只是给他添加到每个项目,并有另一个classB,将register他一些怎么样,所以当有新的东西,B会知道这件事,(没有呼叫乙!)
它在客观c中的表现如何?
非常感谢 .
我有一个控制器,可以获取要传递给视图的数据.向此注入(通过疙瘩容器)服务,该服务使用许多域模型+业务逻辑来创建数据.
服务本身有一个注入其中的"存储库"类,它有创建数据映射器和返回域模型实例的方法.
我知道我可能没有深入了解存储库概念,因为Martin Fowler将其设置为"在映射层上构建另一层抽象"和"存储库在域和数据映射层之间进行调解,就像在-memory域对象集合." 所以我可能会错误地使用这个术语.
服务:
class InputService
{
private $repos;
public function __construct($repo) {
$this->repos = $repo;
}
public function getInitialData()
{
$product = $this->repo->getProduct();
$country = $this->repo->getCountry();
$spinalPoint = $this->repo->getPoint();
/*business logic with model instances to produce data array*/
return //array of data
}
}
Run Code Online (Sandbox Code Playgroud)
库:
class InputRepository
{
private $db;
public function __construct($db) {
$this->db = $db;
}
public function getCountry()
{
$mapper = new CountryMapper($this->db);
$country = $mapper->fetch();
return $country; //returns country object
} …Run Code Online (Sandbox Code Playgroud) php model-view-controller datamapper decoupling repository-pattern
decoupling ×10
c# ×2
.net ×1
api ×1
c++ ×1
datamapper ×1
django ×1
django-apps ×1
events ×1
linq ×1
models ×1
mvp ×1
mvvm ×1
objective-c ×1
optimization ×1
php ×1
polymorphism ×1
wpf ×1