- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我自己尝试设计模式和原则并提出了一个问题。之前,为糟糕的编码风格习惯感到抱歉!!
在这种情况下,我有一个类似 ITest 的接口(interface):
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 中的方法 2() 不可用,因为对于 ITest 的接口(interface)。现在,如果我需要这个“重要”方法怎么办?有几种可能性。我可以在接口(interface)中对其进行抽象,或者使 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() 方法中,我可以使用一个小钩子(Hook)或链接机制调用这两个方法,而无需引用新对象,也不会违反设计原则,而且我不需要额外的类来进行扩展或抽象。
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()));
}
}
此外,我还可以封装、继承和抽象其他方法、字段等。这意味着,我可以创建更复杂、更灵活的层次结构。
我现在的问题:这是一种反模式、糟糕的设计原则,还是我们可以从中受益?
感谢观看。 :-)
最佳答案
Is this a kind of anti-pattern, bad design-principle or could we benefit from this?
是的,这是一个糟糕的模式。
问题源于您已将 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
并转换为B
。那么你要增加什么值(value)?您只是让界面变得不那么连贯且更加困惑。
关于java - 这是一种反模式还是违反了一些设计原则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50253508/
我目前正在对一个 mmorpg 的二进制网络协议(protocol)进行逆向工程。我正在用 java 实现该协议(protocol)。 对于每个数据包类型,我将创建一个表示二进制数据的类。 例如,聊天
我正在尝试围绕现有类编写半透明包装器,我希望它能够模仿其他类的序列化。 例如,给定以下类: class Foo { [JsonConverter(CustomConverter)] s
是否有使用 Jackson 序列化和反序列化枚举集的简单方法? private enum Type { YES, NO } @JacksonXmlProperty(localName = "t
我很想知道当我们反序列化一个对象时会发生什么。 例如,如果我的类对象由许多其他对象组成,对象创建过程如何在反序列化过程中发生 最佳答案 对象是用默认的初始化字段创建的,然后用从串行流中获取的属性值填充
我正在尝试序列化和反序列化(使用 QDataStream 但这与这里无关)一个 enum class变量: enum class Type : char { Trivial, Comp
我不确定这到底有什么问题...它不会为我编译,我将它从 c 翻译成 C++(或尝试)...是的,我是初学者。谢谢! #include #include using namespace std; i
我遇到的问题与此处描述的问题非常相似:Combining type and field serializers case class(id: Option[UUID], otherValue:Stri
我们知道base中的apply()可以对数组的边距应用一个函数,边距应该是行或列。我想将边距扩大到“对角线” 和“反对角线”。结构看起来像 diagApply <- function(x, FUN,
我找到了 JSON serialization and deserialization to objects in Flutter 的例子但是如何使用像这样的人员列表来做到这一点: [ {
我有一个相当大的terms聚合结果,这些结果被加载到下拉列表中以提供filter功能。 可以说,我的下拉列表中有4000多种动物。我的另一个下拉列表有4种动物颜色。 例, animal --> ["d
我需要将 C# (.NET Framework 4.5.2) 中的一个类与 XML 序列化(反序列化),该类具有 string 的字典属性。键和 string[]数组值。我正在使用 Serializa
[已解决]应用给定的解决方案,效果很好! 程序的目的:在用户打开和关闭程序时保存/重新加载以前的数据。 我曾经用一个对象(obj)成功(反)序列化,现在我有两个不同类的不同对象。 我试图通过查看其他帖
问题 假设我有一个代表某事或其他的枚举: public enum ResultState { Found, Deleted, NotFound } 在我的序列化 json 中,
是否有取消 JSON 字符串的功能?我猜它不会内置到 JQuery 中,但它可以通过编写一个操纵字符串的脚本来实现吗?我在下面遇到了这个问题。 我正在使用 NYTimes API,但它不支持 JSON
对于这个问题,假设当对象完全写入流并成功读出时,或者当对象部分写入流并且读回对象时发生异常时,序列化/反序列化是原子的。假设写操作可能无法成功完成,例如因为停电了。 在Serializable的描述中
有谁知道时序检查是否仍在检测虚拟环境?我尝试使用 rdtsc 指令来获取 cpu 周期并比较真实 linux 机器和在 virtualbox 上运行的 linux 之间的结果。但结果似乎不稳定。有时,
我正在对一个(外部给定的)XML 文件进行操作,该文件具有以下形式的元素 10 20 30 40 50 60 70 80 我知道如何将属性作为属性处理(通过使用 [XmlAttri
我有一个通用的序列化器和反序列化器,用于通过网络连接发送的消息: public static async Task SerializeObject(Object obj) {
我正在考虑将当前基于 WCF 的应用程序迁移到 protobuf-net.Grpc。这似乎是可行的,但是我无法在不包含所有具有 [ProtoInclude] 属性的派生类的情况下使(DTO 类)基类的
我正在尝试将一些数据保存到文件中,但文件保存到的目录不正确。 using (StreamWriter sw = new StreamWriter(dir + "\\temp" + x + ".txt"
我是一名优秀的程序员,十分优秀!