我尝试使用设计模式& - 原则并有一个问题。 以前,抱歉编码风格不好!!
在这种情况下我有像ITest这样的界面:
public interface ITest
{
public void method1();
}
然后将方法和字段(如果有的话)实现到具体的类B中,如下所示:
public class B implements ITest
{
//This is the method from the interface
@Override
public void method1()
{
System.out.println("method1");
}
//This is another method in class B
public void method2()
{
System.out.println("method2");
}
}
现在在应用程序代码中我把它放在这样:
public class Main
{
public static void main(final String args[]) throws Exception
{
//One principle says:
//programm to an interface instead to an implementation
ITest test = new B();
//method from interface
test.method1();
//this method is not accessible because not part of ITest
test.method2(); //compile-time error
}
}
你看到来自B类的method2()因为ITest的界面而无法使用。 现在,如果我需要这种“重要”方法怎么办? 有几种可能性。我可以在界面中抽象它或者使B类抽象并扩展到另一个类等等,或者在main()方法中进行引用,如:
B test = new B();
但这违反了原则。 所以,我将界面修改为:
public interface ITest
{
//A method to return the class-type B
public B hook();
public void method1();
}
并在B类中实施:
public class B implements ITest
{
//this returns the object reference of itself
@Override
public B hook()
{
return this;
}
//This is the method from the interface
@Override
public void method1()
{
System.out.println("method1");
}
//This is the 'important' method in class B
public void method2()
{
System.out.println("method2");
}
}
现在在我的main()方法中,我可以使用一个小钩子或链接机制调用这两个方法而不引用一个新对象,也不违反设计原则,我不需要额外的类来进行扩展或抽象。
public class Main
{
public static void main(final String args[])
{
//programm to an interface instead into an implemintation
ITest test = new B();
//method from interface
test.method1();
//method2 will not be accessible from ITest so we referencing B through a method hook()
//benefits: we don't need to create extra objects nor additional classes but only referencing
test.hook().method2();
System.out.println("Are they both equal: "+test.equals(test.hook()));
}
}
另外,我可以封装,继承和抽象其他方法,字段等。 这意味着,我可以创建更复杂和灵活的层次结构。
我现在的问题: 这是一种反模式,糟糕的设计原则还是我们可以从中受益?
感谢您的收看。 : - )
答案 0 :(得分:3)
这是一种反模式,糟糕的设计原则还是我们可以 受益于此?
是的,这是一种糟糕的模式。
问题源于您将data have;
informat date ddmmyy10.;
format date ddmmyy10.;
input
date carrier $ Flight tailnum $ origin $ dest $ Distance Air_time Arr_Delay;
datalines;
01-01-2013 UA 1545 N14228 EWR IAH 1400 227 17
01-01-2013 UA 1714 N24211 LGA IAH 1416 227 .
01-01-2013 AA 1141 N619AA JFK MIA 1089 160 .
01-01-2013 EV 5708 N829AS LGA IAD 229 53 -18
01-01-2013 B6 79 N593JB JFK MCO 944 140 14
01-01-2013 AA 301 N3ALAA LGA ORD 733 138 .
01-01-2013 B6 49 N793JB JFK PBI 1028 149 .
01-01-2013 B6 49 N793JB JFK PBI 1028 149 15
01-01-2013 B6 71 N657JB JFK TPA 1005 158 19
01-01-2013 UA 194 N29129 JFK LAX 2475 345 23
01-01-2013 UA 1124 N53441 EWR SFO 2565 361 -29
;
run;
proc sort data=work.have; by origin dest carrier; run;
Proc stdize data=work.have reponly method=mean out=work.Complete_data ;
var Arr_Delay;
by origin dest carrier ;
Run;
与ITest
紧密耦合的事实。假设我要创建B
的新实现 - 让我们称之为ITest
。
C
我们无法实现这种方法。唯一合理的做法是返回public class C implements ITest
{
@Override
public B hook()
{
// How do I implement this?
}
@Override
public void method1()
{
System.out.println("method1");
}
}
。这样做会强制我们界面的任何用户不断进行防御性空检查。
如果他们在使用方法结果之前每次都必须进行检查,他们也可以只执行null
并投射到instanceof
。那你有什么价值呢?你只是让界面不那么连贯,更加混乱。
答案 1 :(得分:1)
将B
返回到ITest
实现的接口B
的方法绝对是一个糟糕的设计选择,因为它强制其他类实现ITest
返回B
,例如
public class C implements ITest {
@Override
public B hook()
{
return // What do I return here? C is not a B
}
...
}
您的首选更好:
B test1 = new B();
C test2 = new C();