设计模式以保持行为独特但根据接口有所不同
Design pattern to keep behavior unique but make differ according to interfaces
我正在寻找我刚刚制作的设计模式的名称,以及它是否是一个好的。
所以基本上我是在寻找一种方法来在 Actor class 的子class 之间保持主要行为,根据子class 的子接口划分子行为。 =35=] 实现。
这里有一个简化的例子,可以让我的观点更容易理解...
演员 Class :
public abstract class Actor implements FirstSubBehavior, SecondSubBehavior/*, MoreBehaviors...*/{
public final void mainBehavior(){
doFirstSubBehavior();
doSecondSubBehavior();
/* ... */
//doNthSubBehavior();
System.out.println();
}
}
一个 FirstSubBehavior 接口:
public interface FirstSubBehavior{
public void doFirstSubBehavior();
public interface FirstWay extends FirstSubBehavior{
public default void doFirstSubBehavior(){
System.out.println("I'm doing the 1st sub-behavior using the 1st way.");
}
}
public interface SecondWay extends FirstSubBehavior{
public default void doFirstSubBehavior(){
System.out.println("I'm doing the 1st sub-behavior using the 2nd way.");
}
}
/* ... */
public interface NthWay extends FirstSubBehavior{
public default void doFirstSubBehavior(){
System.out.println("I'm doing the 1st sub-behavior using the Nth way.");
}
}
}
一个 SecondSubBehavior 接口:
public interface SecondSubBehavior{
public void doSecondSubBehavior();
public interface FirstWay extends SecondSubBehavior{
public default void doSecondSubBehavior(){
System.out.println("I'm doing the 2nd sub-behavior using the 1st way.");
}
}
public interface SecondWay extends SecondSubBehavior{
public default void doSecondSubBehavior(){
System.out.println("I'm doing the 2nd sub-behavior using the 2nd way.");
}
}
/* ... */
public interface NthWay extends SecondSubBehavior{
public default void doSecondSubBehavior(){
System.out.println("I'm doing the 2nd sub-behavior using the Nth way.");
}
}
}
还有一个 Main Class 来测试它:
public class Main{
public static void main(String[] args){
class Actor1 extends Actor implements FirstSubBehavior.FirstWay, SecondSubBehavior.FirstWay {}
new Actor1().mainBehavior();
class Actor2 extends Actor implements FirstSubBehavior.FirstWay, SecondSubBehavior.NthWay {}
new Actor2().mainBehavior();
}
}
这会产生以下输出:
I'm doing the 1st sub-behavior using the 1st way.
I'm doing the 2nd sub-behavior using the 1st way.
I'm doing the 1st sub-behavior using the 1st way.
I'm doing the 2nd sub-behavior using the Nth way.
所以 main 很重要,在那里你可以看到我想如何使用我的 Actor class:我想对我所有的 subclasses 的主要行为进行一次编码,然后能够根据它实现的默认子行为使其不同。
希望我说清楚了,如果不是我可以重新表述。
仔细阅读Liskov substitute。所以你的模式破坏了坚定的行为。
出现的问题:
- 如果两个步骤之间的状态转换需要是原子的/事务性的怎么办? (全部或none)
- 如果在执行已获取资源的步骤时抛出 RuntimeException 怎么办?
- 如果链下的条件需要链上的改变怎么办?
这样的链接模式已经存在,但作为有效的 Liskov 替代品:
- Servlets有一个过滤链,通过接口明确限制。状态更改是可能的,例如会话内存或请求包装。
- 验证器只收集错误或快速失败,验证对象的状态没有变化。 (这更像是一个通用契约,因为除非验证真正的不可变,否则没有什么可以阻止验证器实例也调用设置方法。)
- 通过命令进行状态转换。每个命令都绑定一个更改,可以完成、撤消或重新完成。命令序列形成一个链来改变一个或多个实体。命令永远不会改变,也不会改变/命令本身是不可变的。
- 策略是一种更好的模式,在一侧有一个契约和多种实现。例如 XML-readers 或 writers 的构造取决于生成通用接口的类路径。
我总是更喜欢策略方法,但也喜欢一个建议的评论:为了特定的目的。您需要从各种资源中读取字符串行或一组专用记录:每种资源类型都有一个策略。合约表示为如下接口:
public interface LineReader {
List<String> readAll();
}
这可以通过 FileLineReader、StreamLineReader 和/或 UserInputReader 来实现。然后将其链接为:
// already unmodifiable, factory classes/ methods
final List<Command> commandChain=Commands.forUsecase(UseCase.READ_TRANSFORM_PERSIST);
final Processor p=new Processor();
// only proceeds upon valid records
p.setPrecondition(Validators.fixedLengthRecordStyle());
// set of commands doing something with the context and data
p.setCommandChain(commandChain);
// Where to take data from
p.setSource(new FileLineReader(new File("/tmp/input.csv", LineFilters.skipEmptyLinesAndComments())));
// now there's a result
final ProcessingResult pr = p.process();
if (!pr.isValid()) {
// print validation errors and exit
}
if (!pr.isSuccessful()) {
// print processing errors and exit
}
// print success and exit.
System.printf("Read %d records, stored %d records, %d were duplicates",
pr.getNumberOfRecords(), pr.getNumberOfSaved(),
pr.getNumberOfSkipped());
我正在寻找我刚刚制作的设计模式的名称,以及它是否是一个好的。
所以基本上我是在寻找一种方法来在 Actor class 的子class 之间保持主要行为,根据子class 的子接口划分子行为。 =35=] 实现。
这里有一个简化的例子,可以让我的观点更容易理解...
演员 Class :
public abstract class Actor implements FirstSubBehavior, SecondSubBehavior/*, MoreBehaviors...*/{
public final void mainBehavior(){
doFirstSubBehavior();
doSecondSubBehavior();
/* ... */
//doNthSubBehavior();
System.out.println();
}
}
一个 FirstSubBehavior 接口:
public interface FirstSubBehavior{
public void doFirstSubBehavior();
public interface FirstWay extends FirstSubBehavior{
public default void doFirstSubBehavior(){
System.out.println("I'm doing the 1st sub-behavior using the 1st way.");
}
}
public interface SecondWay extends FirstSubBehavior{
public default void doFirstSubBehavior(){
System.out.println("I'm doing the 1st sub-behavior using the 2nd way.");
}
}
/* ... */
public interface NthWay extends FirstSubBehavior{
public default void doFirstSubBehavior(){
System.out.println("I'm doing the 1st sub-behavior using the Nth way.");
}
}
}
一个 SecondSubBehavior 接口:
public interface SecondSubBehavior{
public void doSecondSubBehavior();
public interface FirstWay extends SecondSubBehavior{
public default void doSecondSubBehavior(){
System.out.println("I'm doing the 2nd sub-behavior using the 1st way.");
}
}
public interface SecondWay extends SecondSubBehavior{
public default void doSecondSubBehavior(){
System.out.println("I'm doing the 2nd sub-behavior using the 2nd way.");
}
}
/* ... */
public interface NthWay extends SecondSubBehavior{
public default void doSecondSubBehavior(){
System.out.println("I'm doing the 2nd sub-behavior using the Nth way.");
}
}
}
还有一个 Main Class 来测试它:
public class Main{
public static void main(String[] args){
class Actor1 extends Actor implements FirstSubBehavior.FirstWay, SecondSubBehavior.FirstWay {}
new Actor1().mainBehavior();
class Actor2 extends Actor implements FirstSubBehavior.FirstWay, SecondSubBehavior.NthWay {}
new Actor2().mainBehavior();
}
}
这会产生以下输出:
I'm doing the 1st sub-behavior using the 1st way.
I'm doing the 2nd sub-behavior using the 1st way.
I'm doing the 1st sub-behavior using the 1st way.
I'm doing the 2nd sub-behavior using the Nth way.
所以 main 很重要,在那里你可以看到我想如何使用我的 Actor class:我想对我所有的 subclasses 的主要行为进行一次编码,然后能够根据它实现的默认子行为使其不同。
希望我说清楚了,如果不是我可以重新表述。
仔细阅读Liskov substitute。所以你的模式破坏了坚定的行为。
出现的问题:
- 如果两个步骤之间的状态转换需要是原子的/事务性的怎么办? (全部或none)
- 如果在执行已获取资源的步骤时抛出 RuntimeException 怎么办?
- 如果链下的条件需要链上的改变怎么办?
这样的链接模式已经存在,但作为有效的 Liskov 替代品:
- Servlets有一个过滤链,通过接口明确限制。状态更改是可能的,例如会话内存或请求包装。
- 验证器只收集错误或快速失败,验证对象的状态没有变化。 (这更像是一个通用契约,因为除非验证真正的不可变,否则没有什么可以阻止验证器实例也调用设置方法。)
- 通过命令进行状态转换。每个命令都绑定一个更改,可以完成、撤消或重新完成。命令序列形成一个链来改变一个或多个实体。命令永远不会改变,也不会改变/命令本身是不可变的。
- 策略是一种更好的模式,在一侧有一个契约和多种实现。例如 XML-readers 或 writers 的构造取决于生成通用接口的类路径。
我总是更喜欢策略方法,但也喜欢一个建议的评论:为了特定的目的。您需要从各种资源中读取字符串行或一组专用记录:每种资源类型都有一个策略。合约表示为如下接口:
public interface LineReader {
List<String> readAll();
}
这可以通过 FileLineReader、StreamLineReader 和/或 UserInputReader 来实现。然后将其链接为:
// already unmodifiable, factory classes/ methods
final List<Command> commandChain=Commands.forUsecase(UseCase.READ_TRANSFORM_PERSIST);
final Processor p=new Processor();
// only proceeds upon valid records
p.setPrecondition(Validators.fixedLengthRecordStyle());
// set of commands doing something with the context and data
p.setCommandChain(commandChain);
// Where to take data from
p.setSource(new FileLineReader(new File("/tmp/input.csv", LineFilters.skipEmptyLinesAndComments())));
// now there's a result
final ProcessingResult pr = p.process();
if (!pr.isValid()) {
// print validation errors and exit
}
if (!pr.isSuccessful()) {
// print processing errors and exit
}
// print success and exit.
System.printf("Read %d records, stored %d records, %d were duplicates",
pr.getNumberOfRecords(), pr.getNumberOfSaved(),
pr.getNumberOfSkipped());