web-dev-qa-db-ja.com

神オブジェクトになるクラスはどのパターンを使用するか

私はAndroidアプリを開発しており、MainActivityGod Objectになりつつあります。
ところで、ネイティブActivityクラスの実装は、すでにGod Objectのようなものです。
問題は、私の活動クラスがどんどん増えていることです。
Androidに慣れていない人のために、クラスの責任について説明します。
アクティビティは、UI、ライフサイクル、OSと通信する機能を備えた画面のようなものです。
ドロワーは、アプリのナビゲーション用のアクティビティサイドメニューを表示するUIの一部です。何が問題ですか。

public abstract class MainActivity extends SingleFragmentToolBarActivity<T> implements Drawer.OnDrawerItemClickListener {
    private static final int PROFILE_HEADER_IDENTIFIER = 200;
    private float mDisplayDpWidth;
    private float mDisplayDpHeight;
    private Drawer.Result mNavigationDrawer;
    private AccountHeader.Result mAccountHeader;
    private double mDrawerWidthFactor = 0.9;
    private double mDrawerHeaderHeightFactor = 0.3;
    private IProfile<ProfileDrawerItem> mGuestProfile;
    private IProfile<ProfileDrawerItem> mLoggedInProfile;
    private boolean userIsLogged = false;
    public Drawer.Result getNavigationDrawer() {
        return this.mNavigationDrawer;
    }
    private AccountHeader.Result geAccountHeader() {
        return this.mAccountHeader;
    }
    private static final int PROFILE_SETTING = 1;
    private final AccountHeader.OnAccountHeaderSelectionViewClickListener mHeaderSelectionViewClickListener = new AccountHeader.OnAccountHeaderSelectionViewClickListener(.....);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setUpNavigationDrawer(savedInstanceState);
    }

    private void setUpNavigationDrawer(Bundle savedInstanceState) {
        DrawerImageLoader.init(new DrawerImageLoader.IDrawerImageLoader() {
            @Override
            public void set(ImageView imageView, Uri uri, Drawable placeholder) {
                Picasso.with(imageView.getContext()).load(uri).placeholder(placeholder).into(imageView);
            }

            @Override
            public void cancel(ImageView imageView) {
                Picasso.with(imageView.getContext()).cancelRequest(imageView);
            }

            @Override
            public Drawable placeholder(Context ctx) {
                return null;
            }
        });
        getDisplayMetrics();
        mGuestProfile = buildGuestProfile();
        mAccountHeader = buildNavigationHeader(savedInstanceState);
        mNavigationDrawer = buildDrawer(savedInstanceState);
    }
    protected Drawer.Result buildDrawer(Bundle savedInstanceState) {
     Drawer drawer =  new Drawer(this)
            .withActivity(this);
    ........
    }
    protected List<IProfile> getProfileItemList() {
    ......        
    }
    protected AccountHeader.Result buildNavigationHeader(Bundle savedInstanceState) {
    ......
    }
    private ProfileDrawerItem buildGuestProfile() {
        .......
    }
    private ProfileDrawerItem buildLoggedInProfile(UserBean userBean) {
        .......
    }
    private void getDisplayMetrics() {
       .....
    }
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l, IDrawerItem iDrawerItem) {
     ......
    }

    protected Drawer addItemsIntoDrawer(Drawer buildDrawer) {
        ......
    }
    public void setDrawerWidthFactor(double factor) {
      ......
    }
    public void setDrawerHeaderHeightFactor(double factor) {
      ......
    }

これは、一部のメソッドとクラスメンバーの宣言にすぎません。
上記のコードは、MainActivityのナビゲーションドロワーを設定するためだけのものです。サービスと通信するためのコードが今後さらに増える予定です。そのままにしておくと、すぐにクラスを取得できます何百万行ものコード、大量のクラスメンバー、大量のメソッド。

この問題を解決するために、この方法でどのパターンが許容できるかを説明します。
ドロワーを設定するには、アクティビティへの参照が必要です。
私はこの問題を解決する方法をいくつか考えています。
ナビゲーションドロワーの設定を担当するこれらすべてのメソッドで戦略パターン作成インターフェイスを使用しますが、この場合、インターフェイスへの参照をインターフェイス実装に渡し、インターフェイスではなく抽象クラスを作成して、参照をコンストラクタへのアクティビティ。
これは機能しますが、それでも完璧でクリーンなソリューションではないと思います。

クラスの成長を止めるために何ができるか提案してください。

[〜#〜]編集[〜#〜]

私の活動の責任はごくわずかであり、将来的にはより重要な責任が発生するため、多くの初期化コードを作成する必要はありません。メソッドの本文を投稿していません(300行のコード)。ここで可能な方法の1つは、基本的なメソッドを使用して抽象クラスを作成し、実装を作成して、必要なときにアクティビティで使用することです。この場合、実行時に(ビューが表示される前に)変更することができます。膨張した)。

4
CROSP

たとえば、各操作を担当するクラスのリストを作成できます。

public abstract class MainActivity extends SingleFragmentToolBarActivity<T> implements Drawer.OnDrawerItemClickListener {
    ....

    private void setUpNavigationDrawer(Bundle savedInstanceState) {
        NavigationDrawer drawer = new NavigationDrawer(this,savedInstanceState);  
        drawer.setup();
    }
}

ここで、各操作(この例ではNavigationDrawer)のロジックを、操作を処理する独自のクラスに移動できます。

2

まず、独自の責任を持つ複数のクラスに分類します。

最初にここでGRASPプリンシパルを適用する必要があります。 [〜#〜]掴み[〜#〜]

第二に、私は戦略設計パターンを検討します。 戦略デザインパターン

1
Alexus