prefer 组合 to 继承

核心不要多继承,要通过组合的模式进行组合,解耦, 非强绑定

需求

我已有一个CodingService的接口,同时有一个CodingServiceImpl的实现类,接口中定义了createReository,pullCode,pushCode三个方法,CodingServiceImpl 实现类里面进行了实现,现在想通过prefer 组合 to 继承的思想,将接口中的3个方法抽取出来变成单独的功能模块,方法依赖的参数变成独立功能模块里的属性,然后通过Builder构造者模式把方法参数传递进功能模块的属性里。功能模块执行没有任何参数的do方法。请帮我设计一下,并给出实践案例

实际代码

为了遵循组合优于继承的原则,并且利用构建者模式来构造对象,我们可以将CodingService接口中的方法createRepository, pullCode, pushCode分别抽象成三个独立的功能模块。每个功能模块都会有一个内部的Builder类用于构建该模块的实例,这些模块将会有一个无参的do方法来执行相应的操作。

以下是根据上述描述设计的代码实现:

首先定义一个基础的接口CodingOperation,所有的操作类都要实现这个接口:

public interface CodingOperation {
    void doOperation();
}

然后为每个操作定义一个模块,每个模块都包含一个Builder类:
创建Repository模块

public class RepositoryCreationModule implements CodingOperation {
    private String repositoryName;
    private String owner;

    private RepositoryCreationModule(Builder builder) {
        this.repositoryName = builder.repositoryName;
        this.owner = builder.owner;
    }

    @Override
    public void doOperation() {
        // 实现创建仓库的逻辑
        System.out.println("Creating repository " + repositoryName + " for owner " + owner);
    }

    public static class Builder {
        private String repositoryName;
        private String owner;

        public Builder repositoryName(String repositoryName) {
            this.repositoryName = repositoryName;
            return this;
        }

        public Builder owner(String owner) {
            this.owner = owner;
            return this;
        }

        public RepositoryCreationModule build() {
            return new RepositoryCreationModule(this);
        }
    }
}

创建代码模块

public class CodePullModule implements CodingOperation {
    private String sourceBranch;
    private String destinationBranch;

    private CodePullModule(Builder builder) {
        this.sourceBranch = builder.sourceBranch;
        this.destinationBranch = builder.destinationBranch;
    }

    @Override
    public void doOperation() {
        // 实现拉取代码的逻辑
        System.out.println("Pulling code from " + sourceBranch + " to " + destinationBranch);
    }

    public static class Builder {
        private String sourceBranch;
        private String destinationBranch;

        public Builder sourceBranch(String sourceBranch) {
            this.sourceBranch = sourceBranch;
            return this;
        }

        public Builder destinationBranch(String destinationBranch) {
            this.destinationBranch = destinationBranch;
            return this;
        }

        public CodePullModule build() {
            return new CodePullModule(this);
        }
    }
}

推送代码模块

public class CodePushModule implements CodingOperation {
    private String branchName;
    private String commitMessage;

    private CodePushModule(Builder builder) {
        this.branchName = builder.branchName;
        this.commitMessage = builder.commitMessage;
    }

    @Override
    public void doOperation() {
        // 实现推送代码的逻辑
        System.out.println("Pushing code to branch " + branchName + " with message '" + commitMessage + "'");
    }

    public static class Builder {
        private String branchName;
        private String commitMessage;

        public Builder branchName(String branchName) {
            this.branchName = branchName;
            return this;
        }

        public Builder commitMessage(String commitMessage) {
            this.commitMessage = commitMessage;
            return this;
        }

        public CodePushModule build() {
            return new CodePushModule(this);
        }
    }
}

现在进行测试

public class CodingServiceClient {
    public static void main(String[] args) {
        RepositoryCreationModule repositoryCreation = new RepositoryCreationModule.Builder()
                .repositoryName("MyRepo")
                .owner("Myself")
                .build();
        repositoryCreation.doOperation();

        CodePullModule codePull = new CodePullModule.Builder()
                .sourceBranch("develop")
                .destinationBranch("feature")
                .build();
        codePull.doOperation();

        CodePushModule codePush = new CodePushModule.Builder()
                .branchName("feature")
                .commitMessage("Added new feature")
                .build();
        codePush.doOperation();
    }
}

好处:
这样的设计允许我们将每个操作封装在自己的模块中,同时通过构建者模式提供了一种清晰的方式来构造这些模块。每个模块都是独立的,它们可以被独立地创建和复用,也便于单独测试和维护

posted @ 2024-03-23 10:27  SpecialSpeculator  阅读(1)  评论(0编辑  收藏  举报