我正在使用TestNG在Java中运行基于Selenium的测试.我有一堆重复的测试.通常,除测试名称和一个参数外,它们都是相同的.
我想自动生成它.我在考虑使用工厂.有没有办法生成不同名称的测试?最好的办法是什么?
至于现在我有类似下面的东西,我想创建像LinkOfInterestIsActiveAfterClick这样的10个测试
@Test(dependsOnGroups="loggedin")
public class SmokeTest extends BrowserStartingStoping{
public void LinkOfInterestIsActiveAfterClick(){
String link = "link_of_interest";
browser.click("*",link);
Assert.assertTrue(browser.isLinkActive(link));
}
}
Run Code Online (Sandbox Code Playgroud)
我正在按照上一个问题的回复中提出的方式实现Factory类:
它是一个Factory,它存储从字符串到对象创建函数的映射,因此我可以通过字符串标识符从工厂请求不同类型的对象.这个工厂生成的所有类都将继承自一个抽象类(Connection),为不同协议(HTTPConnection,FTPConnection等)的连接提供通用接口.
我很好地掌握了与上述方法相关联的方法是如何运作的.
我遇到问题的地方是试图找出一种机制来防止在不使用Factory的情况下实例化Connection对象.为了使Factory能够完成它的工作,我需要为它提供一个对象创建函数来存储它的地图.我不能提供它的构造函数,因为你不能创建构造函数的函数指针.因此,如上面的链接,必须有一个单独的对象创建函数来返回新对象.但要做到这一点,我需要使这个创建函数或者是类的静态方法,客户端代码能够访问它,或者是一个单独的函数,它需要a)Connection类的构造函数是公共的,或者b)使构造函数成为私有,并使非类成员创建函数成为朋友,这不是继承的,可以'
类似地,如果我只是使用Connection类生成Factory类的朋友,那么它应该生成所以它可以访问它们的私有构造函数,这样可以工作,但是我无法通过abstact基类强制执行,因为朋友不是继承的.每个子类都必须明确地与Factory成为朋友.
任何人都可以建议实施我上面描述的方法吗?
重申要求:
1 - 生成各种对象的工厂,所有对象都基于传入的标识符从相同的基类派生到Factory的Create方法.
2 - 工厂需要生成的所有子类将自动向工厂注册创建函数和标识符(参见上面链接的SO答案)
3 - 工厂生产的所有子类都不应该是可实例化的(可实例化的?)而不经过工厂
4 - 使用继承将#3显式强制作为抽象基类的一部分.删除了某人从抽象基类继承子类的可能性,同时还提供了自由实例化对象的机制.
我想要实现的总体目标是允许将新的Connection类型添加到层次结构中,而不必以任何方式更改Factory类,同时还强制Connection的所有子类不能通过客户端代码直接实例化.
我很乐意这可能不是实现我想要的最佳方式,欢迎其他替代方案的建议.
编辑 - 当我回到家时希望能够更清楚地添加一些代码片段.
所以,这是交易.我设法在不使用全局变量或静态类/函数的情况下创建框架.
我正在使用一种使用Factory的依赖注入形式.由于框架将用于各种事情,我正在创建一个更通用的工厂,它将构建您的类,并以递归方式依赖它.
为了节省内存,每次对象被实例化时,Factory都会存储对它的引用,因此如果另一个对象具有对该对象的依赖关系,Factory将只需要返回引用.这样我们就不需要两次实例化同一个对象了.
这意味着,在许多类中,我们将对同一对象有许多不同的引用.例如,如果我声明Blog_model,Blog_controller,Blog_view,Form_validation需要Config对象,则每个实例都将使用对同一Config对象的引用进行实例化,尽管是注入.
我不熟悉单元测试或任何类型的自动测试.我刚刚发现使用全局变量和静态都很糟糕(这就是为什么我要重写我使用的框架).我想问的是,这会引入全球状态吗?它是否以任何方式妨碍测试?
----更新------
这是一个用PHP编写的MVC框架.
这是我通常看到显示的抽象工厂模式的方式:
public abstract class Factory
{
public abstract Product GetProduct();
}
public class ConcreteFactory1 : Factory
{
public override Product GetProduct() { return new Product1(); }
}
class ConcreteFactory2 : Factory
{
public override Product GetProduct() { return new Product2(); }
}
interface Product
{
void SomeMethod();
}
class Product1 : Product
{
public void SomeMethod() { Console.WriteLine("1"); }
}
class Product2 : Product
{
public void SomeMethod() { Console.WriteLine("2"); }
}
class Program
{
static void Main(string[] args)
{ …Run Code Online (Sandbox Code Playgroud) 我有共同的代码(我称之为控制器的多个类)需要由项目中的多个包共享.我正在考虑创建一个返回这些控制器的工厂.因此,工厂将有一个hashmap,可以返回请求的控制器,如果没有创建,则创建一个新的.控制器有公共代码,因为我不需要创建这些控制器的多个实例,我认为它们应该是单例.
这看起来像是一个好方法吗?
调用在我的控制器中使用.factory创建的服务时遇到问题.代码如下所示.工厂(app.js):
.factory('Database',function($http){
return {
getDatabase: function(){
var database = {};
$http.get('http://localhost:3001/lookup').
success(function(data){
database.companyInfo = data.info.companyInfo;
});
}).
error(function(data){
console.log('Error' + data);
});
return database;
}
};
})
Run Code Online (Sandbox Code Playgroud)
控制器:
angular.module('webClientApp')
.controller('MainCtrl', function (Database,Features,$scope,$http) {
$scope.databaseString = [];
$scope.quarters = ['Q1','Q2','Q3','Q4'];
$scope.years = ['2004','2005','2006','2007','2008','2009','2010',
'2011','2012','2013','2014'];
$scope.features = Features.getFeatures();
$scope.database = Database.getDatabase();
console.log($scope.database);
Run Code Online (Sandbox Code Playgroud)
现在,当我在Firebug中检查元素时,我console.log($scope.database)在GET语句结果之前得到了打印输出.$scope.database显示为Object {}具有所有适当的礼节.但是,如果我尝试使用,console.log($scope.database.companyInfo)我得到一个undefined结果,而我应该得到data.info.companyInfo' that I passed from the数据库服务(在这种情况下是一个数组).
这里有什么问题?有人能帮我吗?(如果您需要澄清,请告诉我..)
在重构一些代码的同时,我发现我们应该在几个地方使用一些多态,而不是必须在这个地方有一堆if/else块.
虽然面向对象的类很容易实现,但是当我们必须决定使用什么实现时,就会出现问题.似乎有很多解决方案,但我想看看是否有更优雅或"最佳实践"的方法来做到这一点.
所以基本上,例如,为了举例说明,我将选择一张信用卡,对于每种信用卡类型,我都有一个实现.因此我有这样的类结构:
每个子类都将扩展CreditCard超类.
现在在Web应用程序中,我将传递一个String,表示用户选择的卡类型.现在我需要将它路由到实际的实现类本身.这是众多选择发挥作用的地方.
如果有更好的选择或者我坚持这些,请告诉我.
工厂:
@Autowired @Qualifier("visa") private CreditCard visa;
@Autowired @Qualifier("mastercard") private CreditCard mastercard;
@Autowired @Qualifier("amex") private CreditCard amex;
public CreditCard getCreditCard(String input) {
{
if ("visa".equals(input)) {
return visa;
} else if ("mastercard".equals(input)) {
return mastercard;
} else if ("amex".equals(input)) {
return amex;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
地图:
@Autowired HashMap<String, CreditCard> creditCardImpls;
public CreditCard getCreditCard(String input) {
return creditCardImpls.get(input);
}
Run Code Online (Sandbox Code Playgroud)
ApplicationContext getBean:
@Autowired private ApplicationContext applicationContext;
public CreditCard getCreditCard(String …Run Code Online (Sandbox Code Playgroud) 据我所知,Factory Method比Simple Factory的主要优点之一是它不违反Open-Closed SOLID原则.也就是说,前者不需要在添加新类型时修改switch语句.
有一件我希望得到澄清.如果我要使用一个简单的工厂,我会有一个像这样的工厂(简化):
public class ObjectFactory {
public static IObject CreateObject(ObjectTypeEnum objectType) {
switch (objectType) {
case TypeA:
return ObjectA;
break;
case TypeB:
return ObjectB;
break;
case TypeC:
return ObjectC;
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且客户端会这样称呼它:
IObject myObject = ObjectFactory.CreateObject(objectType);
Run Code Online (Sandbox Code Playgroud)
文献中的缺点是在添加新对象类型时需要修改CreateObject.
但是使用Factory方法,我们不会将此修改从工厂移动到客户端,就像这样(客户端代码):
IObject myObject;
switch (objectType) {
case TypeA:
myObject = ObjectAFactory.CreateObject();
break;
case TypeB:
myObject = ObjectBFactory.CreateObject();
break;
case TypeC:
myObject = ObjectCFactory.CreateObject();
break;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,每次添加新类型时都需要修改客户端,而在之前的情况下需要修改工厂.那么一个优于另一个的优势是什么?请不要将此标记为重复,我已经查看了很多关于工厂的SO帖子,没有一个解决这个特定的区别.
是否有更好的解决方案不会违反客户或工厂方面的开放/封闭原则?
design-patterns factory factory-pattern open-closed-principle solid-principles
我目前正在研究一个学生项目,并想知道是否有办法专门用工厂方法创建对象?
public class PersonFactory {
public static Person createPerson() {
// some constraints ...
return new Person();
}
}
Run Code Online (Sandbox Code Playgroud)
我的示例PersonFactory.java应该Person用它的createPerson()方法返回对象.
public class Person {
// some examples ...
private String name;
private int age;
public Person() {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但在main程序中,我仍然能够Person使用它们的公共构造函数创建对象(因为它是public).但是如果我将构造函数更改为private,则工厂方法也无法访问它.
public class PersonManagement {
public static void main(String[] args) {
// both still works ...
Person p1 = new Person();
Person p2 = PersonFactory.createPerson(); …Run Code Online (Sandbox Code Playgroud) 考虑以下工作习惯Seq:
class MySeq[B](val s: Seq[B])
extends Seq[B]
with GenericTraversableTemplate[B, MySeq]
with SeqLike[B, MySeq[B]] {
override def companion = MySeq
def iterator = s.iterator
def apply(i: Int) = s(i)
def length = s.length
override def toString = s map { _.toString } mkString("\n")
}
object MySeq extends SeqFactory[MySeq] {
implicit def canBuildFrom[B]: CanBuildFrom[Coll, B, MySeq[B]] =
new GenericCanBuildFrom[B]
def newBuilder[B] = new ListBuffer[B] mapResult (x => new MySeq(x.toSeq))
}
Run Code Online (Sandbox Code Playgroud)
我想对type参数强加一个绑定B.换句话说,我想要这样的东西(不工作):
class MyA
class MySeq[+B <: MyA](val s: …Run Code Online (Sandbox Code Playgroud)