General programming question. When to use OOP?

后端 未结 6 2200
没有蜡笔的小新
没有蜡笔的小新 2021-02-11 03:44

My program needs to do 2 things.

  1. Extract stuff from a webpage.

  2. Do stuff with a webpage.

However, there are many webpages, su

6条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-11 04:37

    I regularly define classes for solving problems for a few reasons, I'll model an example of my thinking below. I have no compunctions about mixing OO models and procedural styles, that's often more a reflection of your work society than personal religion. It often works to have a procedural facade for a class hierarchy if that's what other maintainers expect. (Please excuse the PHP syntax.)

  • I'm developing strategies and I can follow a generic model. So a possible modeling of your task might involve getting something to chew on URLs passed. This works if you want to simplify the outer logic a lot, and remove conditionals. This shows that I can use DNRY for the gather() method.

    // batch process method
    function MunchPages( $list_of_urls )
    {
        foreach( $list_of_urls as $url )
        {
            $muncher = PageMuncher::MuncherForUrl( $url );
            $muncher->gather();
            $muncher->process();
        }
    }
    // factory method encaps strategy selection
    function MuncherForUrl( $url )
    {
        if( strpos( $url, 'facebook.com' ))
             return new FacebookPageMuncher( $url );
        if( ... ) 
             return new .... ;
    }
    // common tasks defined in base PageMuncher
    class PageMuncher 
    {
        function gather() { /* use some curl or what */ }
        function process() {}
    }
    class FacebookPageMuncher extends PageMuncher
    {
        function process() { /* I do it 'this' way for FB */ }
    }
    

  • I'm creating a set of routines that are ideally hidden, and better yet, shared. An example of this might be having a class that defines toolbox methods common to a task. More specific tasks could extend the toolbox to develop their own behavior.

    class PageMuncherUtils
    {
        static function begin( $html, $context )
        {
           // process assertions about html and context
        }
        static function report_fail( $context ) {}
        static function exit_retry( $context ) {}
    }
    // elsewhere I compose the methods in cases I don't wish to inherit them
    class TwitterPageMuncher
    {
        function validateAnchor( $html, $context )
        {
            if( ! PageMuncherUtils::begin( $html, $context )) 
                return PageMuncherUtils::report_fail( $context );
        }
    }
    

  • I want to organize my code to convey broader meaning to the maintainer. Consider that if I have even one remote service I'm interfacing with, I might be diving into different APIs inside their interface, and I want to group those routines along similar topics. Below, I show an example how I like to define a class defining common constants, a class defining basic service methods, and a more specific class for weather alerts because the alert should know how to refresh itself, and it's a more specific than the weather service itself, but also leverages the WeatherAPI constants as well.

    class WeatherAPI
    {
        const URL = 'http://weather.net';
        const URI_TOMORROW = '/nextday/';
        const URI_YESTERDAY= '/yesterday/';
        const API_KEY = '123';
    }
    class WeatherService
    {
        function get( $uri ) {  }
        function forecast( $dateurl ) {  }
        function alerts( $dateurl )
        {
            return new WeatherAlert( 
                $this->get( WeatherAPI::URL.$date
                           ."?api=".WeatherAPI::API_KEY ));
        }
    }
    class WeatherAlert
    {
        function refresh() {}
    }
    // exercise:
    $alert = WeatherService::alerts( WeatherAPI::URI_TOMORROW );
    $alert->refresh();
    

提交回复
热议问题