我有一堆MDI子节点,它们都以相同的方式创建,并减少冗余代码我希望能够调用一个方法,传递一个字符串(子节点的名称),让它创建节点和将其添加到父级.
我可以做所有的事情,除了从类名字符串创建类,我该怎么做?
在我们MVC系统中所有模型的基类中,我创建了一个工厂方法BaseCLass :: getNew(),它通过SomeChildClass :: getNew()调用时返回所请求子类的实例.
现在,我正在寻找一种方法来强制程序员使用这个工厂.也就是说,我喜欢任何直接创建的类,如下所示:
new SomeChildClass
Run Code Online (Sandbox Code Playgroud)
将在创建时抛出异常,并且只有工厂创建的类才可用.
任何想法如何实现?
我们的代码是用PHP编写的,但即使您考虑使用其他语言,您的想法很有可能也很有价值.
编辑:我不能使我的构造函数私有,因为我继承的类中的框架构造函数是公共的,而且php不允许我这样做.
我的想法是创建可以求和/减去/ ...一起的特定函数对象,返回具有相同属性的新函数对象.希望这个示例代码能够证明这个想法:
from FuncObj import Func
# create some functions
quad = Func(lambda x: x**2)
cube = Func(lambda x: x**3)
# now combine functions as you like
plus = quad + cube
minus = quad - cube
other = quad * quad / cube
# and these can be called
plus(1) + minus(32) * other(5)
Run Code Online (Sandbox Code Playgroud)
我编写了以下代码,希望对此进行评论和记录,以解释我想要实现的目标.
import operator
class GenericFunction(object):
""" Base class providing arithmetic special methods.
Use derived class which must implement the
__call__ method.
"""
# this way …Run Code Online (Sandbox Code Playgroud) 我不知道如果有可能,如何编写调用它的泛型类型的构造函数的方法继承自公共已知的基类<T:Base>来创建T的一些实例而不依赖于显式工厂函数,即所有的钟声和口哨由类型推断提供.
在游乐场中工作的示例:
// Let there be classes MyPod and Boomstick with common Base (not important)
class Base : Printable {
let value : String; init(_ value : String) { self.value = "Base." + value }
var description: String { return value }
}
class MyPod : Base {
init(_ value: String) { super.init("MyPod." + value) }
}
class Boomstick : Base {
init(_ value: String) { super.init("Boomstick." + value) }
}
// PROBLEM: do not know how to force call …Run Code Online (Sandbox Code Playgroud) 我是DI的新手,但我真的很想尝试使用它.
有些事情我不明白.这是一个简单的工厂伪代码,我使用了很多.
class PageFactory {
public function __construct(/* dependency list */) {
... //save reference to the dependencies
}
public function createPage($pagename) {
switch ($pagename) {
case HomePage::name:
return new HomePage(/* dependency list */);
case ContactPage::name:
return new ContactPage(/* dependency list */);
...
default:
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
它有一个非常简单的逻辑,它选择基于字符串的实现实例.它非常有用,因为我可以在以后选择我需要的页面,并且只会创建一个页面.
我将如何重写此代码,因此我的页面实例将由依赖项容器创建,因此我不需要处理工厂及其创建的页面的依赖项?
我看到的唯一解决方案是制作我想要使用的容器,工厂的依赖项,并在工厂内调用它.我有很多问题.
首先,我不想将容器连接到我的应用程序,以及它拥有的每个工厂.
第二,我最大的问题是,对容器的调用非常麻烦,它是字符串式的(即$ container-> get('Foo');).我想尽可能少地使用它.只有一次可能.
编辑:
我不想写一个DI容器.我想使用现有的.我的问题是关于使用情况.我将如何使用DI容器代替或在上述工厂中使用DI容器,同时保持实例选择的逻辑.
编辑2:
我开始使用Dice作为DI容器,因为它很轻,并且知道我需要的一切.如果我可以在一个地方使用它并构建整个应用程序,我更愿意.为此,我需要一种方法以某种方式摆脱这些工厂,或以某种方式修改它以使这些页面像依赖项一样,因此DI容器将为它们提供实例.
编辑3:
是的,我需要这个用于测试目的.我也是测试的新手,但到目前为止我非常喜欢它.
这些页面是MVC框架调用控制器的.但是我检查的所有MVC框架都没有让它们的控制器可测试,因为它们会自动创建它们的实例.并且因为它们是由系统创建的,所以用户无法自定义其构造函数参数.
有一种简单的方法可以检查任何框架.我只是查看我应该在该特定框架中的控制器中使用数据库的方式.大多数框架都是程序性的,或者使用一些服务定位器,无论哪种方式,它们都是从公共范围获取它们的依赖关系,这是我不想做的事情.这就是我没有自动化控制器实例化的原因.缺点是我现在拥有这些奇怪的工厂,它们具有很多依赖性.我想将此任务替换为DI容器.
大多数框架都实现了自己的测试机制,这更像是功能测试,而不是单元测试,但我也不想这样做.
我是AngularJS的新手.我只想将JSON文件数据加载到位于工厂中的变量中.
myApp.factory('quizFactory', function () {
var questions = [
{
"setId":1,
"question":"What is the value of the 7 in the following number? 850,765",
"options": ["70", "7", "7000", "700"],
"answer": 3
},
{
"setId":2,
"question":"Is 7 & 9 even or odd?",
"options": ["Even", "Odd", "Can't Say", "Dont know"],
"answer": 1
},
{
"setId":3,
"question":"In the number 5,281,946 what is the value of the 3rd place?",
"options": ["100", "10,000", "1,000,000", "1,000"],
"answer": 0
},
{
"setId":4,
"question":"Is 12 + 50 even or …Run Code Online (Sandbox Code Playgroud) 我对“与工厂相关的”设计模式及其OOP实现的理解一直很简单。
但是我最近偶然发现了有关该主题的Wikipeda文章(Factory,Abstract factory),这使我有些困惑,尤其是关于OOP中的“ Factory”是什么。
这里有几个引号:
- 在工厂方法或工厂功能中,返回“新”对象的子例程可以称为“工厂”。
- 工厂用于各种设计模式
- “抽象工厂模式”是一种建立工厂集合的方法。
- 工厂是代码中具体类的位置,在该类中构造对象
引起一些问题:
(1)&(2)这是否意味着工厂不是类或对象,而是逻辑?
(2)“工厂”本身不是模式吗?
(3)“收藏”在这里是什么意思?只是说“您可以有多个实现相同接口的工厂(这是一个抽象工厂)”的一种方式吗?
(4)什么?
任何人都可以澄清这意味着什么吗?我对工厂的最初理解不正确吗?
为什么LocalDate,LocalTime,Stream,等对象使用一个工厂方法of()而不是构造的?
我找到了为什么应该使用工厂方法而不是new 这里的解释.这个答案有很多原因,但与Java Date/Time API相关的唯一原因如下:
与构造函数不同,它们不需要在每次调用时创建新对象
作为LocalDate并且LocalTime是不可变的,使用工厂并重用现有对象而不是每次都创建新对象可能是有意义的.
这就是为什么对象喜欢LocalDate和LocalTime用工厂方法创建的原因(即LocalDate.of())?还有其他原因吗?
此外,Stream对象是可变的.为什么使用工厂方法(Stream.of())来创建Stream?
我正在制作一个投票系统,它将在网站周围的多个组件中重复使用.为了保持其干燥,我想从任何组件创建投票组件,到指定的DOM元素..组件已被创建后,实例变量必须设置(在这种情况下model:string和pk:number,公共).
我希望组件在指定位置呈现,打印在工厂创建组件后立即设置的正确数据.投票底部的输出应该是Model: project PK: 1
ComponentFactory目前有两个由Component工厂创建的投票组件的输出:
在正确的位置(目标div),但没有设置实例变量.

在页面的底部,但这是另一个问题,在以后的时间和其他主题.
@NgModule({
..
declarations: [
AppComponent,
ProjectComponent, // parent for voteContainer
VoteComponent, // Dynamic component
],
entryComponents: [
VoteComponent,
], ..
})
Run Code Online (Sandbox Code Playgroud)
包含VoteComponent工厂的父组件
export class ProjectDetailComponent implements AfterViewInit {
@ViewChild('voteComponentContainer', {read: ViewContainerRef}) voteComponentContainer;
public ngAfterViewInit() {
this.factoryVoteComponent();
}
private factoryVoteComponent() {
const voteComponentFactory = this.componentFactoryResolver.resolveComponentFactory(VoteComponent);
const voteComponentRef = this.viewContainerRef.createComponent(voteComponentFactory);
voteComponentRef.instance.model = "project";
voteComponentRef.instance.pk = 1;
voteComponentRef.changeDetectorRef.detectChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
动态组件目标:
<vote-component-container></vote-component-container>
Run Code Online (Sandbox Code Playgroud)
基本投票组件
@Component({ …Run Code Online (Sandbox Code Playgroud) 我正在阅读Joshua Blochs的"Effective Java",它说
静态工厂方法的第三个优点是,与构造函数不同,它们可以返回其返回类型的任何子类型的对象.这为您选择返回对象的类提供了极大的灵活性.这种灵活性的一个应用是API可以在不公开其类的情况下返回对象.以这种方式隐藏实现类会导致非常紧凑的API.此技术适用于基于接口的框架,其中接口为静态工厂方法提供自然返回类型.
谁能解释一下"自然回归类型"是什么?谢谢!